ida-domain-scripting
Write and execute Python scripts using the IDA Domain API for reverse engineering. Analyze binaries, extract functions, strings,…
Analyze binaries using the Domain API for IDA Pro. Use when examining program structure, functions, disassembly, cross-references, or strings.
$ npx -y skills add HexRaysSA/claude-marketplace --skill ida-domain-api --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/ida-domain-apiContext preview
The summary Claude sees to decide when to auto-load this skill.
Analyze binaries using the Domain API for IDA Pro. Use when examining program structure, functions, disassembly, cross-references, or strings.
name: ida-domain-api description: Analyze binaries using the Domain API for IDA Pro. Use when examining program structure, functions, disassembly, cross-references, or strings.
Use this skill to efficiently use the Domain API for IDA Pro, which is easier and more concise than the legacy IDA Python SDK.
**Always prefer the IDA Domain API** over the legacy low-level IDA Python SDK. The Domain API provides a clean, Pythonic interface that is easier to use and understand.
| Resource | URL | |----------|-----| | **LLM-optimized overview** | https://ida-domain.docs.hex-rays.com/llms.txt | | **Getting Started** | https://ida-domain.docs.hex-rays.com/getting_started/index.md | | **Examples** | https://ida-domain.docs.hex-rays.com/examples/index.md | | **API Reference** | https://ida-domain.docs.hex-rays.com/ref/{module}/index.md |
Available API modules: `bytes`, `comments`, `database`, `entries`, `flowchart`, `functions`, `heads`, `hooks`, `instructions`, `names`, `operands`, `segments`, `signature_files`, `strings`, `types`, `xrefs`
**To fetch specific API documentation**, use URLs like:
from ida_domain import Database
from ida_domain.database import IdaCommandOptions
# Open an existing .i64/.idb
ida_options = IdaCommandOptions(auto_analysis=False, new_database=False)
with Database.open("path/to/sample.i64", ida_options, save_on_close=False) as db:
pass
# Analyze a raw input file and create a new database
ida_options = IdaCommandOptions(
auto_analysis=True,
new_database=True,
output_database="path/to/cache/sample.i64",
load_resources=True,
)
with Database.open("path/to/input.exe", ida_options, save_on_close=True) as db:
pass`IdaCommandOptions` maps directly to IDA command-line switches. Two options are especially common for headless analysis tools:
**`load_resources=True`** (maps to `-R`): loads MS Windows exe resources. Important for PE analysis that needs resource data.
**`plugin_options`** (maps to `-O`): pass options to IDA plugins. The most common use is **disabling Lumina** to prevent it from injecting bad or non-deterministic names:
ida_options = IdaCommandOptions(
auto_analysis=True,
new_database=True,
output_database=str(cache_path),
load_resources=True,
plugin_options="lumina:host=0.0.0.0 -Osecondary_lumina:host=0.0.0.0",
)This sets both primary and secondary Lumina server addresses to `0.0.0.0`, effectively disabling Lumina lookups. The `plugin_options` field is a raw string; `build_args()` emits `-O{value}` verbatim, so embedding `-O` inside the value for additional plugin options works correctly — the above produces `-Olumina:host=0.0.0.0 -Osecondary_lumina:host=0.0.0.0`.
Other useful fields: `processor` (`-p`), `log_file` (`-L`), `script_file` (`-S`), `db_compression` (`-P`). See the `IdaCommandOptions` docstring for the full list.
For repeatable CLI tools, do not re-analyze raw binaries every run. Prefer this pattern:
import contextlib
import fcntl
import hashlib
import os
import time
from pathlib import Path
import ida_auto
from ida_domain import Database
from ida_domain.database import IdaCommandOptions
DATABASE_POLL_INTERVAL = 0.25
DATABASE_ACCESS_TIMEOUT = 5.0
DATABASE_ANALYSIS_TIMEOUT = 120.0
def get_cache_dir() -> Path:
root = Path(os.environ.get("XDG_CACHE_HOME", Path.home() / ".cache"))
return root / "your-tool"
def compute_sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as f:
for chunk in iter(lambda: f.read(65536), b""):
digest.update(chunk)
return digest.hexdigest()
def wait_for_repack(db_path: Path, timeout: float) -> None:
nam_path = db_path.with_suffix(".nam")
deadline = time.monotonic() + timeout
while nam_path.exists():
if time.monotonic() >= deadline:
raise RuntimeError(f"database appears busy: {db_path}")
time.sleep(DATABASE_POLL_INTERVAL)
@contextlib.contextmanager
def database_access_guard(db_path: Path, timeout: float):
wait_for_repack(db_path, timeout)
lock_path = Path(str(db_path) + ".lock")
lock_fd = lock_path.open("w")
deadline = time.monotonic() + timeout
try:
while True:
try:
fcntl.flock(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
break
except OSError:
if time.monotonic() >= deadline:
raise RuntimeError(f"timed out waiting for lock: {db_path}")
time.sleep(DATABASE_POLL_INTERVAL)
wait_for_repack(db_path, max(0.0, deadline - time.monotonic()))
yield
finally:
fcntl.flock(lock_fd, fcntl.LOCK_UN)
lock_fd.close()
def resolve_database(file_path: Path) -> Path:
if file_path.suffix.lower() in {".i64", ".idb"}:
return file_path
cache_dir = get_cache_dir()
cache_dir.mkdir(parents=True, exist_ok=True)
cache_path = cache_dir / f"{compute_sha256(file_path)}.i64"
if cache_path.exists():
return cache_path
with database_access_guard(cache_path, DAClaude Code plugins and skills for Hex-Rays ecosystem.
Write and execute Python scripts using the IDA Domain API for reverse engineering. Analyze binaries, extract functions, strings,…
Develop plugins for IDA Pro in Python, using idiomatic patterns, lessons, and tricks, including the Python Domain API…
Package IDA Pro plugins for the IDA Plugin Manager and plugins.hex-rays.com repository