ida-domain-scripting

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
IMPORTANT - Path Resolution: This skill can be installed in different locations. Before executing any commands, determine the skill directory based on where you loaded this SKILL.md file, and use that path in all commands below. Replace
$SKILL_DIR
with the actual discovered path.
Common installation paths:
  • Project-specific:
    <project>/.claude/skills/ida-domain-scripting
  • Manual global:
    ~/.claude/skills/ida-domain-scripting
重要提示 - 路径解析: 本技能可安装在不同位置。执行任何命令前,请根据加载此SKILL.md文件的位置确定技能目录,并在以下所有命令中使用该路径。将
$SKILL_DIR
替换为实际找到的路径。
常见安装路径:
  • 项目专属:
    <project>/.claude/skills/ida-domain-scripting
  • 手动全局安装:
    ~/.claude/skills/ida-domain-scripting

IDA Domain Scripting

IDA Domain 脚本开发

General-purpose binary analysis skill. I'll write custom IDAPython code for any reverse engineering task you request and execute it via the universal executor.
CRITICAL WORKFLOW - Follow these steps in order:
  1. Create a work dir in /tmp with timestamp - NEVER write scripts to skill directory; always create a workdir
    /tmp/ida-domain-YYYYMMDD_HHMMSS_ffffff-<name>
    with microseconds for uniqueness (e.g.,
    /tmp/ida-domain-20260109_143052_847291-list-functions
    ). Generate timestamp with:
    datetime.now(). strftime ('%Y%m%d_%H%M%S_%f')
    . This will always be referenced as <work_dir>
  2. Check API_REFERENCE.md exists - Always check that $SKILL_DIR/API_REFERENCE.md exists. Inform the user to run the bootstrap if not.
  3. Execute from skill directory - Always run:
    cd $SKILL_DIR && uv run python run.py <work_dir>/script.py -f <binary>
  4. Ask before saving - Scripts that modify the database require explicit user confirmation before using
    --save
通用二进制分析技能。我会为你请求的任何逆向工程任务编写自定义IDAPython代码,并通过通用执行器运行。
关键工作流程 - 请按顺序执行以下步骤:
  1. 在/tmp中创建带时间戳的工作目录 - 切勿将脚本写入技能目录;始终创建唯一的工作目录
    /tmp/ida-domain-YYYYMMDD_HHMMSS_ffffff-<name>
    ,使用微秒保证唯一性(例如:
    /tmp/ida-domain-20260109_143052_847291-list-functions
    )。使用以下命令生成时间戳:
    datetime.now(). strftime ('%Y%m%d_%H%M%S_%f')
    。 此目录将统一称为<work_dir>
  2. 检查API_REFERENCE.md是否存在 - 始终检查$SKILL_DIR/API_REFERENCE.md是否存在。如果不存在,请告知用户运行引导程序。
  3. 从技能目录执行命令 - 始终运行:
    cd $SKILL_DIR && uv run python run.py <work_dir>/script.py -f <binary>
  4. 保存前需确认 - 修改数据库的脚本在使用
    --save
    参数前需要用户明确确认

How It Works

工作原理

  1. You describe what you want to analyze/extract
  2. I write custom IDA Domain API code in
    <work_dir>/script.py
    (timestamped with microseconds for parallel execution)
  3. I execute it via:
    cd $SKILL_DIR && uv run python run.py <work_dir>/script.py -f <binary>
  4. Results displayed in real-time
  5. Script files auto-cleaned from /tmp by your OS
  1. 你描述想要分析/提取的内容
  2. 我在
    <work_dir>/script.py
    中编写自定义IDA Domain API代码(带微秒时间戳以支持并行执行)
  3. 通过以下命令执行:
    cd $SKILL_DIR && uv run python run.py <work_dir>/script.py -f <binary>
  4. 实时显示结果
  5. 脚本文件会由操作系统自动从/tmp中清理

Setup (First Time)

首次设置

bash
cd $SKILL_DIR && uv run python setup.py
This clones ida-domain from GitHub and installs dependencies. Only needed once.
Using a specific version:
bash
uv run python setup.py --ref v0.1.0   # Specific release
uv run python setup.py --ref main     # Bleeding edge
Requirements:
  • uv package manager
  • git
  • IDA Pro 9.1+
  • IDADIR environment variable pointing to IDA installation
bash
cd $SKILL_DIR && uv run python setup.py
此命令会从GitHub克隆ida-domain并安装依赖项。仅需执行一次。
使用特定版本:
bash
uv run python setup.py --ref v0.1.0   # 指定版本
uv run python setup.py --ref main     # 最新开发版
要求:
  • uv包管理器
  • git
  • IDA Pro 9.1+
  • 指向IDA安装目录的IDADIR环境变量

Execution Pattern

执行模式

Step 1: Write analysis script to <work_dir>
python
undefined
步骤1:将分析脚本写入<work_dir>
python
undefined

<work_dir>/script.py

<work_dir>/script.py

for func in db.functions: name = db.functions.get_name(func) print(f"{name}: 0x{func.start_ea:08X}")

**Step 2: Execute from skill directory**

```bash
cd $SKILL_DIR && uv run python run.py <work_dir>/script.py -f /path/to/binary
Step 3: Review results
Scripts are auto-wrapped with
Database.open()
boilerplate. The
db
variable is available for accessing all entities.
for func in db.functions: name = db.functions.get_name(func) print(f"{name}: 0x{func.start_ea:08X}")

**步骤2:从技能目录执行**

```bash
cd $SKILL_DIR && uv run python run.py <work_dir>/script.py -f /path/to/binary
步骤3:查看结果
脚本会自动包装
Database.open()
模板代码。
db
变量可用于访问所有实体。

Common Patterns

常见模式

List All Functions

列出所有函数

python
undefined
python
undefined

<work_dir>/script.py

<work_dir>/script.py

for func in db.functions: name = db.functions.get_name(func) size = func.end_ea - func.start_ea print(f"{name}: 0x{func.start_ea:08X} - 0x{func.end_ea:08X} ({size} bytes)")
undefined
for func in db.functions: name = db.functions.get_name(func) size = func.end_ea - func.start_ea print(f"{name}: 0x{func.start_ea:08X} - 0x{func.end_ea:08X} ({size} bytes)")
undefined

Find Function by Name

按名称查找函数

python
undefined
python
undefined

<work_dir>/script.py

<work_dir>/script.py

func = db.functions.get_function_by_name("main") if func: print(f"Found main at 0x{func.start_ea:08X}")
# Get callers
callers = db.functions.get_callers(func)
print(f"Called by {len(callers)} functions:")
for caller in callers:
    print(f"  - {db.functions.get_name(caller)}")
else: print("main not found")
undefined
func = db.functions.get_function_by_name("main") if func: print(f"Found main at 0x{func.start_ea:08X}")
# 获取调用者
callers = db.functions.get_callers(func)
print(f"Called by {len(callers)} functions:")
for caller in callers:
    print(f"  - {db.functions.get_name(caller)}")
else: print("main not found")
undefined

Search Strings

搜索字符串

python
undefined
python
undefined

<work_dir>/script.py

<work_dir>/script.py

import re
import re

Find all strings

查找所有字符串

for s in db.strings: print(f"0x{s.address:08X}: {s}")
for s in db.strings: print(f"0x{s.address:08X}: {s}")

Find URLs

查找URL

url_pattern = re.compile(r"https?://[\w./]+", re.IGNORECASE) for s in db.strings: try: content = str(s) if url_pattern.search(content): print(f"URL found: {content}") except: pass
undefined
url_pattern = re.compile(r"https?://[\w./]+", re.IGNORECASE) for s in db.strings: try: content = str(s) if url_pattern.search(content): print(f"URL found: {content}") except: pass
undefined

Analyze Cross-References

分析交叉引用

python
undefined
python
undefined

<work_dir>/script.py

<work_dir>/script.py

Get xrefs TO an address

获取指向某地址的交叉引用

target = 0x00401000 print(f"References TO 0x{target:08X}:") for xref in db.xrefs.to_ea(target): print(f" From 0x{xref.from_ea:08X} (type: {xref.type.name})")
target = 0x00401000 print(f"References TO 0x{target:08X}:") for xref in db.xrefs.to_ea(target): print(f" From 0x{xref.from_ea:08X} (type: {xref.type.name})")

Get xrefs FROM an address

获取从某地址出发的交叉引用

print(f"References FROM 0x{target:08X}:") for xref in db.xrefs.from_ea(target): print(f" To 0x{xref.to_ea:08X} (type: {xref.type.name})")
undefined
print(f"References FROM 0x{target:08X}:") for xref in db.xrefs.from_ea(target): print(f" To 0x{xref.to_ea:08X} (type: {xref.type.name})")
undefined

Decompile Function

反编译函数

python
undefined
python
undefined

<work_dir>/script.py

<work_dir>/script.py

func = db.functions.get_function_by_name("main") if func: try: lines = db.functions.get_pseudocode(func) print("\n".join(lines)) except RuntimeError as e: print(f"Decompilation failed: {e}")
undefined
func = db.functions.get_function_by_name("main") if func: try: lines = db.functions.get_pseudocode(func) print("\n".join(lines)) except RuntimeError as e: print(f"Decompilation failed: {e}")
undefined

Analyze Function Complexity

分析函数复杂度

python
undefined
python
undefined

<work_dir>/script.py

<work_dir>/script.py

complex_funcs = [] for func in db.functions: flowchart = db.functions.get_flowchart(func) if flowchart: block_count = len(flowchart) edge_count = sum(b.count_successors() for b in flowchart) cyclomatic = edge_count - block_count + 2
    if cyclomatic > 10:
        name = db.functions.get_name(func)
        complex_funcs.append((name, func.start_ea, cyclomatic))
complex_funcs.sort(key=lambda x: x[2], reverse=True) print("Most complex functions:") for name, addr, cc in complex_funcs[:10]: print(f" {name}: complexity={cc} at 0x{addr:08X}")
undefined
complex_funcs = [] for func in db.functions: flowchart = db.functions.get_flowchart(func) if flowchart: block_count = len(flowchart) edge_count = sum(b.count_successors() for b in flowchart) cyclomatic = edge_count - block_count + 2
    if cyclomatic > 10:
        name = db.functions.get_name(func)
        complex_funcs.append((name, func.start_ea, cyclomatic))
complex_funcs.sort(key=lambda x: x[2], reverse=True) print("Most complex functions:") for name, addr, cc in complex_funcs[:10]: print(f" {name}: complexity={cc} at 0x{addr:08X}")
undefined

Search Byte Patterns

搜索字节模式

python
undefined
python
undefined

<work_dir>/script.py

<work_dir>/script.py

Search for NOP sled

搜索NOP滑条

pattern = b"\x90\x90\x90\x90" results = db.bytes.find_binary_sequence(pattern) for addr in results: print(f"Found NOP sled at 0x{addr:08X}")
pattern = b"\x90\x90\x90\x90" results = db.bytes.find_binary_sequence(pattern) for addr in results: print(f"Found NOP sled at 0x{addr:08X}")

Search for x64 function prologue

搜索x64函数序言

prologue = b"\x55\x48\x89\xE5" # push rbp; mov rbp, rsp for addr in db.bytes.find_binary_sequence(prologue): print(f"Prologue at 0x{addr:08X}")
undefined
prologue = b"\x55\x48\x89\xE5" # push rbp; mov rbp, rsp for addr in db.bytes.find_binary_sequence(prologue): print(f"Prologue at 0x{addr:08X}")
undefined

Export to JSON

导出为JSON

python
undefined
python
undefined

<work_dir>/script.py

<work_dir>/script.py

import json from pathlib import Path
functions = [] for func in db.functions: name = db.functions.get_name(func) functions.append({ "name": name, "start": f"0x{func.start_ea:08X}", "end": f"0x{func.end_ea:08X}", "size": func.end_ea - func.start_ea, })
output = {"module": db.module, "functions": functions} Path("/tmp/functions.json").write_text(json.dumps(output, indent=2)) print(f"Exported {len(functions)} functions to /tmp/functions.json")
undefined
import json from pathlib import Path
functions = [] for func in db.functions: name = db.functions.get_name(func) functions.append({ "name": name, "start": f"0x{func.start_ea:08X}", "end": f"0x{func.end_ea:08X}", "size": func.end_ea - func.start_ea, })
output = {"module": db.module, "functions": functions} Path("/tmp/functions.json").write_text(json.dumps(output, indent=2)) print(f"Exported {len(functions)} functions to /tmp/functions.json")
undefined

Inline Execution (Simple Tasks)

内联执行(简单任务)

For quick one-off tasks, you can execute code inline without creating files:
bash
undefined
对于快速一次性任务,你可以直接内联执行代码而无需创建文件:
bash
undefined

Quick function count

快速统计函数数量

cd $SKILL_DIR && uv run python run.py -c "print(f'Functions: {len(db.functions)}')" -f binary
cd $SKILL_DIR && uv run python run.py -c "print(f'Functions: {len(db.functions)}')" -f binary

Get binary info

获取二进制文件信息

cd $SKILL_DIR && uv run python run.py -c "print(f'{db.module}: {db.architecture} {db.bitness}-bit')" -f binary

**When to use inline vs files:**

- **Inline**: Quick one-off tasks (count functions, get binary info, check if symbol exists)
- **Files**: Complex analysis, multi-step tasks, anything user might want to re-run
cd $SKILL_DIR && uv run python run.py -c "print(f'{db.module}: {db.architecture} {db.bitness}-bit')" -f binary

**何时使用内联模式vs文件模式:**

- **内联模式**:快速一次性任务(统计函数数量、获取二进制文件信息、检查符号是否存在)
- **文件模式**:复杂分析、多步骤任务、用户可能需要重新运行的任务

Advanced Usage

高级用法

For comprehensive IDA Domain API documentation, see API_REFERENCE.md:
  • Database properties and metadata
  • Function enumeration and analysis
  • String detection and searching
  • Cross-reference queries
  • Byte pattern matching
  • Control flow analysis
  • Decompilation (Hex-Rays)
  • Type information
  • Comments and names
完整的IDA Domain API文档,请查看API_REFERENCE.md
  • 数据库属性和元数据
  • 函数枚举与分析
  • 字符串检测与搜索
  • 交叉引用查询
  • 字节模式匹配
  • 控制流分析
  • 反编译(Hex-Rays)
  • 类型信息
  • 注释与名称

Tips

提示

  • Default is read-only - Use
    --save
    only when modifications should persist (and ask user first!)
  • Timeout - Default 30 minutes; use
    --timeout 0
    for long-running analysis
  • No-wrap mode - Use
    --no-wrap
    when your script already has
    Database.open()
  • Error handling - Always use try-except for decompilation and string operations
  • Check for None - Functions like
    get_function_by_name()
    return None if not found
  • 默认只读模式 - 仅当需要持久化修改时才使用
    --save
    参数(且需先询问用户!)
  • 超时设置 - 默认30分钟;长时间分析可使用
    --timeout 0
    取消超时限制
  • 无包装模式 - 当你的脚本已包含
    Database.open()
    时,使用
    --no-wrap
    参数
  • 错误处理 - 反编译和字符串操作始终使用try-except
  • 检查None值 -
    get_function_by_name()
    等函数未找到时会返回None

Troubleshooting

故障排除

When encountering errors: Check the ida-domain source code first by searching for the method signature in
$SKILL_DIR/ida-domain/ida_domain/
. The API may differ from what's documented or expected.
Virtual environment not found:
bash
cd $SKILL_DIR && uv run python setup.py
IDA SDK fails to load / IDADIR error:
bash
export IDADIR=/path/to/ida
Script timeout:
bash
cd $SKILL_DIR && uv run python run.py --timeout 3600 ...  # 1 hour
cd $SKILL_DIR && uv run python run.py --timeout 0 ...     # No timeout
AttributeError: 'Xrefs' has no attribute 'get_xrefs_to': Use
db.xrefs.to_ea(addr)
not
db.xrefs.get_xrefs_to(addr)
AttributeError on func_t object: Call methods on
db.functions
, not on the func object:
python
undefined
遇到错误时: 首先在
$SKILL_DIR/ida-domain/ida_domain/
中搜索方法签名查看ida-domain源代码。API可能与文档或预期有所不同。
未找到虚拟环境:
bash
cd $SKILL_DIR && uv run python setup.py
IDA SDK加载失败 / IDADIR错误:
bash
export IDADIR=/path/to/ida
脚本超时:
bash
cd $SKILL_DIR && uv run python run.py --timeout 3600 ...  # 1小时
cd $SKILL_DIR && uv run python run.py --timeout 0 ...     # 无超时限制
AttributeError: 'Xrefs' has no attribute 'get_xrefs_to': 使用
db.xrefs.to_ea(addr)
而非
db.xrefs.get_xrefs_to(addr)
func_t对象出现AttributeError: 调用
db.functions
上的方法,而非直接调用func对象:
python
undefined

Wrong: func.get_callers()

错误写法: func.get_callers()

Right: db.functions.get_callers(func)

正确写法: db.functions.get_callers(func)


**UnicodeDecodeError when reading strings:**

```python
for s in db.strings:
    try:
        content = str(s)
    except:
        continue  # Skip problematic strings

**读取字符串时出现UnicodeDecodeError:**

```python
for s in db.strings:
    try:
        content = str(s)
    except:
        continue  # 跳过有问题的字符串

Example Usage

使用示例

User: "How many functions are in this binary?"

Claude: I'll count the functions. Let me analyze the binary...
[Writes: <work_dir>/script.py]
[Runs: cd $SKILL_DIR && uv run python run.py <work_dir>/script.py -f binary]
[Output: Functions: 250]

The binary contains 250 functions.
User: "Find all functions that call malloc"

Claude: I'll find all callers of malloc...
[Writes: <work_dir>/script.py]
[Runs: cd $SKILL_DIR && uv run python run.py <work_dir>/script.py -f binary]
[Output: malloc called by 15 functions: sub_401000, sub_402000, ...]

Found 15 functions that call malloc:
- sub_401000 at 0x00401000
- sub_402000 at 0x00402000
...
User: "Decompile the main function and save it"

Claude: I'll decompile main and save the output...
[Writes: <work_dir>/script.py]
[Runs: cd $SKILL_DIR && uv run python run.py <work_dir>/script.py -f binary]
[Output: Saved to /tmp/main.c]

Done! The decompiled code is saved to /tmp/main.c
用户: "这个二进制文件中有多少个函数?"

Claude: 我来统计函数数量。让我分析一下这个二进制文件...
[写入: <work_dir>/script.py]
[运行: cd $SKILL_DIR && uv run python run.py <work_dir>/script.py -f binary]
[输出: Functions: 250]

该二进制文件包含250个函数。
用户: "找到所有调用malloc的函数"

Claude: 我来查找所有调用malloc的函数...
[写入: <work_dir>/script.py]
[运行: cd $SKILL_DIR && uv run python run.py <work_dir>/script.py -f binary]
[输出: malloc called by 15 functions: sub_401000, sub_402000, ...]

找到15个调用malloc的函数:
- sub_401000 at 0x00401000
- sub_402000 at 0x00402000
...
用户: "反编译main函数并保存"

Claude: 我来反编译main函数并保存输出...
[写入: <work_dir>/script.py]
[运行: cd $SKILL_DIR && uv run python run.py <work_dir>/script.py -f binary]
[输出: Saved to /tmp/main.c]

完成!反编译代码已保存到/tmp/main.c