ida-domain-api

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Domain API for IDA Pro

IDA Pro的Domain API

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.
使用本技能可高效运用IDA Pro的Domain API,它比旧版IDA Python SDK更易用、更简洁。
优先使用IDA Domain API而非旧版底层IDA Python SDK。Domain API提供了简洁、符合Python风格的接口,更易于使用和理解。

Documentation Resources

文档资源

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:
  • https://ida-domain.docs.hex-rays.com/ref/functions/index.md
    - Function analysis API
  • https://ida-domain.docs.hex-rays.com/ref/xrefs/index.md
    - Cross-reference API
  • https://ida-domain.docs.hex-rays.com/ref/strings/index.md
    - String analysis API
可用API模块:
bytes
,
comments
,
database
,
entries
,
flowchart
,
functions
,
heads
,
hooks
,
instructions
,
names
,
operands
,
segments
,
signature_files
,
strings
,
types
,
xrefs
获取特定API文档,可使用如下格式的URL:
  • https://ida-domain.docs.hex-rays.com/ref/functions/index.md
    - 函数分析API
  • https://ida-domain.docs.hex-rays.com/ref/xrefs/index.md
    - 交叉引用API
  • https://ida-domain.docs.hex-rays.com/ref/strings/index.md
    - 字符串分析API

Opening a Database

打开数据库

python
from ida_domain import Database
from ida_domain.database import IdaCommandOptions
python
from ida_domain import Database
from ida_domain.database import IdaCommandOptions

Open an existing .i64/.idb

打开现有.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
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
undefined
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
undefined

Commonly Used IdaCommandOptions

常用IdaCommandOptions选项

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:
python
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.
IdaCommandOptions
直接映射IDA命令行开关。对于无头分析工具,有两个选项尤为常用:
load_resources=True
(对应
-R
): 加载Windows可执行文件资源。对于需要资源数据的PE分析至关重要。
plugin_options
(对应
-O
): 向IDA插件传递选项。最常见的用途是禁用Lumina以防止它注入错误或非确定性名称:
python
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",
)
这会将主、次Lumina服务器地址均设置为
0.0.0.0
,从而有效禁用Lumina查询。
plugin_options
字段是原始字符串;
build_args()
会原样输出
-O{value}
,因此在值中嵌入
-O
以传递额外插件选项是可行的——上述代码会生成
-Olumina:host=0.0.0.0 -Osecondary_lumina:host=0.0.0.0
其他实用字段:
processor
(对应
-p
)、
log_file
(对应
-L
)、
script_file
(对应
-S
)、
db_compression
(对应
-P
)。完整列表请查看
IdaCommandOptions
的文档字符串。

Transparent Database Cache for Headless Tools

无头工具的透明数据库缓存

For repeatable CLI tools, do not re-analyze raw binaries every run. Prefer this pattern:
  • if the input is already an
    .i64
    or
    .idb
    , use it directly
  • otherwise hash the raw input and use the SHA-256 as the cache key
  • create
    <cache>/<sha256>.i64
    on demand
  • serialize access with a lock file and an extra
    .nam
    check, because another IDA process may have the database unpacked
  • create the cached database with
    save_on_close=True
  • reopen cached databases read-only with
    save_on_close=False
  • after requesting auto-analysis, call
    ida_auto.auto_wait()
    before querying
python
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, DATABASE_ANALYSIS_TIMEOUT):
        if cache_path.exists():
            return cache_path

        ida_options = IdaCommandOptions(
            auto_analysis=True,
            new_database=True,
            output_database=str(cache_path),
            load_resources=True,
        )
        with Database.open(str(file_path), ida_options, save_on_close=True):
            ida_auto.auto_wait()

        if not cache_path.exists():
            raise RuntimeError(f"analysis did not create {cache_path}")
        return cache_path


@contextlib.contextmanager
def open_database_session(db_path: Path, auto_analysis: bool = False):
    with database_access_guard(db_path, DATABASE_ACCESS_TIMEOUT):
        ida_options = IdaCommandOptions(auto_analysis=auto_analysis, new_database=False)
        with Database.open(str(db_path), ida_options, save_on_close=False) as db:
            if auto_analysis:
                ida_auto.auto_wait()
            yield db
Notes:
  • keep cached database creation quiet in normal mode; only log cache paths in verbose/debug mode
  • if you need a different cache policy, keep the same three-phase guard: wait for
    .nam
    , acquire
    flock
    , re-check
    .nam
  • if you must fall back to
    idapro.open_database(...)
    for options not exposed by
    ida-domain
    , import your local project modules before
    import idapro
    , because
    idapro
    can mutate
    sys.path
  • disable Lumina via
    plugin_options="lumina:host=0.0.0.0 -Osecondary_lumina:host=0.0.0.0"
    in
    IdaCommandOptions
    (see "Commonly Used IdaCommandOptions" above); no need to fall back to
    idapro.open_database()
    for this
对于可重复运行的CLI工具,不要每次运行都重新分析原始二进制文件。建议采用以下模式:
  • 如果输入文件已经是
    .i64
    .idb
    ,直接使用它
  • 否则对原始输入文件进行哈希,使用SHA-256作为缓存键
  • 按需创建
    <cache>/<sha256>.i64
  • 使用锁文件和额外的
    .nam
    检查实现序列化访问,因为其他IDA进程可能正在解压数据库
  • 创建缓存数据库时设置
    save_on_close=True
  • 以只读模式重新打开缓存数据库,设置
    save_on_close=False
  • 请求自动分析后,在查询前调用
    ida_auto.auto_wait()
python
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, DATABASE_ANALYSIS_TIMEOUT):
        if cache_path.exists():
            return cache_path

        ida_options = IdaCommandOptions(
            auto_analysis=True,
            new_database=True,
            output_database=str(cache_path),
            load_resources=True,
        )
        with Database.open(str(file_path), ida_options, save_on_close=True):
            ida_auto.auto_wait()

        if not cache_path.exists():
            raise RuntimeError(f"analysis did not create {cache_path}")
        return cache_path


@contextlib.contextmanager
def open_database_session(db_path: Path, auto_analysis: bool = False):
    with database_access_guard(db_path, DATABASE_ACCESS_TIMEOUT):
        ida_options = IdaCommandOptions(auto_analysis=auto_analysis, new_database=False)
        with Database.open(str(db_path), ida_options, save_on_close=False) as db:
            if auto_analysis:
                ida_auto.auto_wait()
            yield db
注意:
  • 在正常模式下保持缓存数据库创建过程静默;仅在verbose/debug模式下记录缓存路径
  • 如果需要不同的缓存策略,保留相同的三步防护:等待
    .nam
    文件、获取
    flock
    锁、重新检查
    .nam
    文件
  • 如果必须回退到
    idapro.open_database(...)
    以使用
    ida-domain
    未公开的选项,请在
    import idapro
    之前导入本地项目模块,因为
    idapro
    可能会修改
    sys.path
  • 通过在
    IdaCommandOptions
    中设置
    plugin_options="lumina:host=0.0.0.0 -Osecondary_lumina:host=0.0.0.0"
    禁用Lumina(参见上文“常用IdaCommandOptions选项”);无需为此回退到
    idapro.open_database()

Key Database Properties

核心数据库属性

python
with Database.open(path, ida_options) as db:
    db.minimum_ea      # Start address
    db.maximum_ea      # End address
    db.metadata        # Database metadata
    db.architecture    # Target architecture

    db.functions       # All functions (iterable)
    db.strings         # All strings (iterable)
    db.segments        # Memory segments
    db.names           # Symbols and labels
    db.entries         # Entry points
    db.types           # Type definitions
    db.comments        # All comments
    db.xrefs           # Cross-reference utilities
    db.bytes           # Byte manipulation
    db.instructions    # Instruction access

python
with Database.open(path, ida_options) as db:
    db.minimum_ea      # 起始地址
    db.maximum_ea      # 结束地址
    db.metadata        # 数据库元数据
    db.architecture    # 目标架构

    db.functions       # 所有函数(可迭代)
    db.strings         # 所有字符串(可迭代)
    db.segments        # 内存段
    db.names           # 符号与标签
    db.entries         # 入口点
    db.types           # 类型定义
    db.comments        # 所有注释
    db.xrefs           # 交叉引用工具
    db.bytes           # 字节操作
    db.instructions    # 指令访问

Functions

函数

Iterating Functions

遍历函数

python
undefined
python
undefined

Iterate all functions

遍历所有函数

for func in db.functions: print(db.functions.get_name(func))
for func in db.functions: print(db.functions.get_name(func))

Get function count

获取函数数量

count = len(db.functions)

If your report needs thunk functions or library functions, iterate `db.functions` directly and classify them by flags. Do not assume a higher-level wrapper already included them.
count = len(db.functions)

如果你的报告需要包含跳转函数或库函数,请直接遍历`db.functions`并通过标志进行分类。不要假设更高层级的封装已经包含了这些函数。

Finding Functions

查找函数

python
func = db.functions.get_at(0x401000)           # By address
func = db.functions.get_function_by_name("main")  # By name
func = db.functions.get_next(ea)               # Next function after ea
python
func = db.functions.get_at(0x401000)           # 通过地址查找
func = db.functions.get_function_by_name("main")  # 通过名称查找
func = db.functions.get_next(ea)               # 获取ea之后的下一个函数

Functions in range

获取地址范围内的函数

for func in db.functions.get_between(start_ea, end_ea): print(func.start_ea)
undefined
for func in db.functions.get_between(start_ea, end_ea): print(func.start_ea)
undefined

Function Properties

函数属性

python
name = db.functions.get_name(func)
signature = db.functions.get_signature(func)
flags = db.functions.get_flags(func)  # Returns FunctionFlags
python
name = db.functions.get_name(func)
signature = db.functions.get_signature(func)
flags = db.functions.get_flags(func)  # 返回FunctionFlags

Check function attributes

检查函数属性

db.functions.is_far(func) db.functions.does_return(func)
undefined
db.functions.is_far(func) db.functions.does_return(func)
undefined

Function Code

函数代码

python
undefined
python
undefined

Get disassembly lines

获取反汇编代码行

lines = db.functions.get_disassembly(func, remove_tags=True)
lines = db.functions.get_disassembly(func, remove_tags=True)

Get decompiled pseudocode

获取反编译伪代码

pseudocode = db.functions.get_pseudocode(func, remove_tags=True)
pseudocode = db.functions.get_pseudocode(func, remove_tags=True)

Get microcode

获取微代码

microcode = db.functions.get_microcode(func, remove_tags=True)
undefined
microcode = db.functions.get_microcode(func, remove_tags=True)
undefined

Function Analysis

函数分析

python
undefined
python
undefined

Get instructions in function

获取函数内的指令

for insn in db.functions.get_instructions(func): print(insn.ea)
for insn in db.functions.get_instructions(func): print(insn.ea)

Get flowchart for basic blocks

获取基本块流程图

flowchart = db.functions.get_flowchart(func) for block in flowchart: print(f"Block: {block.start_ea:#x} - {block.end_ea:#x}")
flowchart = db.functions.get_flowchart(func) for block in flowchart: print(f"Block: {block.start_ea:#x} - {block.end_ea:#x}")

Get callers/callees

获取调用者/被调用者

callers = db.functions.get_callers(func) callees = db.functions.get_callees(func)
callers = db.functions.get_callers(func) callees = db.functions.get_callees(func)

Get function chunks

获取函数块

for chunk in db.functions.get_chunks(func): print(f"Chunk: {chunk.start_ea:#x}, main={chunk.is_main}")
for chunk in db.functions.get_chunks(func): print(f"Chunk: {chunk.start_ea:#x}, main={chunk.is_main}")

Get data items within function

获取函数内的数据项

for data_ea in db.functions.get_data_items(func): print(f"Data at {data_ea:#x}")
undefined
for data_ea in db.functions.get_data_items(func): print(f"Data at {data_ea:#x}")
undefined

Thunk-Aware Analysis

跳转函数感知分析

If your tool renders callers/callees, API usage, or function summaries, resolve thunks once and reuse the result everywhere. A good default is:
  • check
    FunctionFlags.THUNK
  • follow only single-target thunk chains
  • stop on cycles, zero-target chains, or multi-target chains
  • cap the depth so malformed databases cannot loop forever
python
from ida_domain.functions import FunctionFlags

MAX_THUNK_DEPTH = 5


def resolve_thunk(db, func):
    current = func
    seen = set()

    for _ in range(MAX_THUNK_DEPTH):
        if not (db.functions.get_flags(current) & FunctionFlags.THUNK):
            return current

        if current.start_ea in seen:
            return current
        seen.add(current.start_ea)

        callees = list(db.functions.get_callees(current))
        if len(callees) != 1:
            return current

        current = callees[0]

    return current
Use the resolved target consistently for:
  • caller lists
  • callee lists
  • API/import classification
  • attaching per-function metadata like matches or tags
如果你的工具需要展示调用者/被调用者、API使用情况或函数摘要,请一次性解析跳转函数并在所有场景复用结果。推荐默认逻辑:
  • 检查
    FunctionFlags.THUNK
    标志
  • 仅跟踪单目标跳转链
  • 在出现循环、零目标链或多目标链时停止
  • 设置深度上限,避免畸形数据库导致无限循环
python
from ida_domain.functions import FunctionFlags

MAX_THUNK_DEPTH = 5


def resolve_thunk(db, func):
    current = func
    seen = set()

    for _ in range(MAX_THUNK_DEPTH):
        if not (db.functions.get_flags(current) & FunctionFlags.THUNK):
            return current

        if current.start_ea in seen:
            return current
        seen.add(current.start_ea)

        callees = list(db.functions.get_callees(current))
        if len(callees) != 1:
            return current

        current = callees[0]

    return current
在以下场景中统一使用解析后的目标:
  • 调用者列表
  • 被调用者列表
  • API/导入分类
  • 附加函数元数据(如匹配结果或标签)

Local Variables

局部变量

python
undefined
python
undefined

Get all local variables

获取所有局部变量

lvars = db.functions.get_local_variables(func) for lvar in lvars: print(f"{lvar.name}: {lvar.type_str}, arg={lvar.is_argument}")
lvars = db.functions.get_local_variables(func) for lvar in lvars: print(f"{lvar.name}: {lvar.type_str}, arg={lvar.is_argument}")

Find variable by name

通过名称查找变量

lvar = db.functions.get_local_variable_by_name(func, "result")
lvar = db.functions.get_local_variable_by_name(func, "result")

Get variable references in pseudocode

获取伪代码中的变量引用

refs = db.functions.get_local_variable_references(func, lvar) for ref in refs: print(f"Line {ref.line_number}: {ref.access_type} in {ref.context}")
undefined
refs = db.functions.get_local_variable_references(func, lvar) for ref in refs: print(f"Line {ref.line_number}: {ref.access_type} in {ref.context}")
undefined

Modifying Functions

修改函数

python
db.functions.set_name(func, "new_name")
db.functions.set_comment(func, "This function does X", repeatable=False)
db.functions.create(ea)   # Create function at address
db.functions.remove(ea)   # Remove function at address

python
db.functions.set_name(func, "new_name")
db.functions.set_comment(func, "This function does X", repeatable=False)
db.functions.create(ea)   # 在指定地址创建函数
db.functions.remove(ea)   # 删除指定地址的函数

Instructions

指令

Iterating Instructions

遍历指令

python
undefined
python
undefined

All instructions in database

遍历数据库中所有指令

for insn in db.instructions: print(db.instructions.get_disassembly(insn))
for insn in db.instructions: print(db.instructions.get_disassembly(insn))

Instructions in range

遍历地址范围内的指令

for insn in db.instructions.get_between(start_ea, end_ea): print(insn.ea)
undefined
for insn in db.instructions.get_between(start_ea, end_ea): print(insn.ea)
undefined

Getting Instructions

获取指令

python
insn = db.instructions.get_at(ea)          # Decode at address
insn = db.instructions.get_previous(ea)    # Previous instruction
python
insn = db.instructions.get_at(ea)          # 解码指定地址的指令
insn = db.instructions.get_previous(ea)    # 获取前一条指令

Instruction Properties

指令属性

python
disasm = db.instructions.get_disassembly(insn)
mnemonic = db.instructions.get_mnemonic(insn)  # "mov", "push", etc.
db.instructions.is_valid(insn)
python
disasm = db.instructions.get_disassembly(insn)
mnemonic = db.instructions.get_mnemonic(insn)  # "mov", "push"等指令助记符
db.instructions.is_valid(insn)

Control Flow Analysis

控制流分析

python
db.instructions.is_call_instruction(insn)      # Is this a call?
db.instructions.is_indirect_jump_or_call(insn) # Indirect jump/call?
db.instructions.breaks_sequential_flow(insn)   # Stops flow (ret, jmp)?
python
db.instructions.is_call_instruction(insn)      # 是否为调用指令?
db.instructions.is_indirect_jump_or_call(insn) # 是否为间接跳转/调用?
db.instructions.breaks_sequential_flow(insn)   # 是否中断顺序执行流(如ret、jmp)?

Working with Operands

操作数处理

python
count = db.instructions.get_operands_count(insn)
operands = db.instructions.get_operands(insn)  # List of Operand objects

for op in operands:
    info = op.get_info()
    print(f"Operand {op.number}: {op.type.name}")

    if isinstance(op, RegisterOperand):
        print(f"  Register: {op.get_register_name()}")
    elif isinstance(op, ImmediateOperand):
        print(f"  Value: 0x{op.get_value():x}")
    elif isinstance(op, MemoryOperand):
        if op.is_direct_memory():
            print(f"  Memory: 0x{op.get_address():x}")

python
count = db.instructions.get_operands_count(insn)
operands = db.instructions.get_operands(insn)  # Operand对象列表

for op in operands:
    info = op.get_info()
    print(f"Operand {op.number}: {op.type.name}")

    if isinstance(op, RegisterOperand):
        print(f"  Register: {op.get_register_name()}")
    elif isinstance(op, ImmediateOperand):
        print(f"  Value: 0x{op.get_value():x}")
    elif isinstance(op, MemoryOperand):
        if op.is_direct_memory():
            print(f"  Memory: 0x{op.get_address():x}")

Segments

内存段

Iterating Segments

遍历内存段

python
for segment in db.segments:
    name = db.segments.get_name(segment)
    size = db.segments.get_size(segment)
    print(f"{name}: {segment.start_ea:#x} - {segment.end_ea:#x}")

count = len(db.segments)
python
for segment in db.segments:
    name = db.segments.get_name(segment)
    size = db.segments.get_size(segment)
    print(f"{name}: {segment.start_ea:#x} - {segment.end_ea:#x}")

count = len(db.segments)

Finding Segments

查找内存段

python
seg = db.segments.get_at(0x401000)      # Segment containing address
seg = db.segments.get_by_name(".text")  # By name
python
seg = db.segments.get_at(0x401000)      # 获取包含指定地址的内存段
seg = db.segments.get_by_name(".text")  # 通过名称查找内存段

Segment Properties

内存段属性

python
name = db.segments.get_name(segment)
size = db.segments.get_size(segment)
bitness = db.segments.get_bitness(segment)  # 16, 32, or 64
seg_class = db.segments.get_class(segment)   # "CODE", "DATA", etc.
python
name = db.segments.get_name(segment)
size = db.segments.get_size(segment)
bitness = db.segments.get_bitness(segment)  # 16、32或64位
seg_class = db.segments.get_class(segment)   # "CODE"、"DATA"等

Creating Segments

创建内存段

python
from ida_domain.segments import PredefinedClass, AddSegmentFlags
python
from ida_domain.segments import PredefinedClass, AddSegmentFlags

Add segment with explicit range

添加指定范围的内存段

seg = db.segments.add( seg_para=0, start_ea=0x1000, end_ea=0x2000, seg_name="MySegment", seg_class=PredefinedClass.CODE )
seg = db.segments.add( seg_para=0, start_ea=0x1000, end_ea=0x2000, seg_name="MySegment", seg_class=PredefinedClass.CODE )

Append segment after last one

在最后一个内存段后追加新段

seg = db.segments.append(seg_para=0, seg_size=0x1000, seg_name="NewSeg")
undefined
seg = db.segments.append(seg_para=0, seg_size=0x1000, seg_name="NewSeg")
undefined

Modifying Segments

修改内存段

python
from ida_domain.segments import SegmentPermissions, AddressingMode

db.segments.set_name(segment, "new_name")
db.segments.set_permissions(segment, SegmentPermissions.READ | SegmentPermissions.EXEC)
db.segments.add_permissions(segment, SegmentPermissions.WRITE)
db.segments.remove_permissions(segment, SegmentPermissions.WRITE)
db.segments.set_addressing_mode(segment, AddressingMode.BIT64)
db.segments.set_comment(segment, "Code section", repeatable=False)

python
from ida_domain.segments import SegmentPermissions, AddressingMode

db.segments.set_name(segment, "new_name")
db.segments.set_permissions(segment, SegmentPermissions.READ | SegmentPermissions.EXEC)
db.segments.add_permissions(segment, SegmentPermissions.WRITE)
db.segments.remove_permissions(segment, SegmentPermissions.WRITE)
db.segments.set_addressing_mode(segment, AddressingMode.BIT64)
db.segments.set_comment(segment, "Code section", repeatable=False)

Strings

字符串

Iterating Strings

遍历字符串

python
for string in db.strings:
    print(f"{string.address:#x}: {string}")
python
for string in db.strings:
    print(f"{string.address:#x}: {string}")

By index

通过索引获取

first_string = db.strings[0] count = len(db.strings)
undefined
first_string = db.strings[0] count = len(db.strings)
undefined

Finding Strings

查找字符串

python
string = db.strings.get_at(0x402000)  # String at address
python
string = db.strings.get_at(0x402000)  # 获取指定地址的字符串

Strings in range

获取地址范围内的字符串

for s in db.strings.get_between(start_ea, end_ea): print(s.contents)
undefined
for s in db.strings.get_between(start_ea, end_ea): print(s.contents)
undefined

String Properties

字符串属性

python
print(string.address)       # Address
print(string.length)        # Length in characters
print(string.type)          # StringType enum
print(string.encoding)      # Internal encoding
print(string.contents)      # UTF-8 bytes
print(str(string))          # Decoded string
python
print(string.address)       # 地址
print(string.length)        # 字符长度
print(string.type)          # StringType枚举
print(string.encoding)      # 内部编码
print(string.contents)      # UTF-8字节
print(str(string))          # 解码后的字符串

Rebuilding String List

重建字符串列表

python
from ida_domain.strings import StringListConfig, StringType

config = StringListConfig(
    string_types=[StringType.C, StringType.C_16],
    min_len=3,
    only_ascii_7bit=False
)
db.strings.rebuild(config)
db.strings.clear()  # Clear string list

python
from ida_domain.strings import StringListConfig, StringType

config = StringListConfig(
    string_types=[StringType.C, StringType.C_16],
    min_len=3,
    only_ascii_7bit=False
)
db.strings.rebuild(config)
db.strings.clear()  # 清空字符串列表

Xrefs

交叉引用

Getting References TO an Address

获取指向指定地址的引用

python
undefined
python
undefined

All xrefs to an address

获取指向指定地址的所有交叉引用

for xref in db.xrefs.to_ea(target_ea): print(f"{xref.from_ea:#x} -> {xref.to_ea:#x} ({xref.type.name})")
for xref in db.xrefs.to_ea(target_ea): print(f"{xref.from_ea:#x} -> {xref.to_ea:#x} ({xref.type.name})")

Just code references

仅获取代码引用

for ea in db.xrefs.code_refs_to_ea(target_ea, flow=False): print(f"Code ref from {ea:#x}")
for ea in db.xrefs.code_refs_to_ea(target_ea, flow=False): print(f"Code ref from {ea:#x}")

Just data references

仅获取数据引用

for ea in db.xrefs.data_refs_to_ea(target_ea): print(f"Data ref from {ea:#x}")
for ea in db.xrefs.data_refs_to_ea(target_ea): print(f"Data ref from {ea:#x}")

Call references only

仅获取调用引用

for ea in db.xrefs.calls_to_ea(func_ea): print(f"Called from {ea:#x}")
for ea in db.xrefs.calls_to_ea(func_ea): print(f"Called from {ea:#x}")

Detailed caller information

获取详细的调用者信息

for caller in db.xrefs.get_callers(func_ea): print(f"Called from {caller.name} at {caller.ea:#x}")
undefined
for caller in db.xrefs.get_callers(func_ea): print(f"Called from {caller.name} at {caller.ea:#x}")
undefined

Getting References FROM an Address

获取来自指定地址的引用

python
undefined
python
undefined

All xrefs from an address

获取来自指定地址的所有交叉引用

for xref in db.xrefs.from_ea(source_ea): print(f"{xref.from_ea:#x} -> {xref.to_ea:#x}")
for xref in db.xrefs.from_ea(source_ea): print(f"{xref.from_ea:#x} -> {xref.to_ea:#x}")

Code/data refs from

获取来自该地址的代码/数据引用

for ea in db.xrefs.code_refs_from_ea(source_ea): print(f"Code ref to {ea:#x}")
for ea in db.xrefs.calls_from_ea(source_ea): print(f"Calls {ea:#x}")
undefined
for ea in db.xrefs.code_refs_from_ea(source_ea): print(f"Code ref to {ea:#x}")
for ea in db.xrefs.calls_from_ea(source_ea): print(f"Calls {ea:#x}")
undefined

Data Access Analysis

数据访问分析

python
undefined
python
undefined

Who reads this data?

谁读取了该数据?

for ea in db.xrefs.reads_of_ea(data_ea): print(f"Read by {ea:#x}")
for ea in db.xrefs.reads_of_ea(data_ea): print(f"Read by {ea:#x}")

Who writes to this data?

谁写入了该数据?

for ea in db.xrefs.writes_to_ea(data_ea): print(f"Written by {ea:#x}")
undefined
for ea in db.xrefs.writes_to_ea(data_ea): print(f"Written by {ea:#x}")
undefined

XrefInfo Properties

XrefInfo属性

python
xref.is_call    # Is this a call reference?
xref.is_jump    # Is this a jump reference?
xref.is_read    # Is this a data read?
xref.is_write   # Is this a data write?
xref.is_flow    # Is this ordinary flow?
xref.user       # Is this user-defined?

python
xref.is_call    # 是否为调用引用?
xref.is_jump    # 是否为跳转引用?
xref.is_read    # 是否为数据读取引用?
xref.is_write   # 是否为数据写入引用?
xref.is_flow    # 是否为普通执行流引用?
xref.user       # 是否为用户定义的引用?

Names

符号名称

Iterating Names

遍历符号名称

python
for ea, name in db.names:
    print(f"{ea:#x}: {name}")

count = len(db.names)
python
for ea, name in db.names:
    print(f"{ea:#x}: {name}")

count = len(db.names)

Getting Names

获取符号名称

python
name = db.names.get_at(0x401000)
ea, name = db.names[0]  # By index
python
name = db.names.get_at(0x401000)
ea, name = db.names[0]  # 通过索引获取

Setting Names

设置符号名称

python
from ida_domain.names import SetNameFlags

db.names.set_name(ea, "my_function")
db.names.set_name(ea, "my_func", flags=SetNameFlags.CHECK)  # Validate chars
db.names.force_name(ea, "func")  # Creates func_2 if func exists
db.names.delete(ea)              # Remove name
python
from ida_domain.names import SetNameFlags

db.names.set_name(ea, "my_function")
db.names.set_name(ea, "my_func", flags=SetNameFlags.CHECK)  # 验证字符合法性
db.names.force_name(ea, "func")  # 若func已存在则创建func_2
db.names.delete(ea)              # 删除符号名称

Name Properties

符号名称属性

python
db.names.is_valid_name("my_name")   # Check if valid
db.names.is_public_name(ea)         # Is public?
db.names.is_weak_name(ea)           # Is weak?

db.names.make_name_public(ea)
db.names.make_name_non_public(ea)
db.names.make_name_weak(ea)
db.names.make_name_non_weak(ea)
python
db.names.is_valid_name("my_name")   # 检查名称是否合法
db.names.is_public_name(ea)         # 是否为公共名称?
db.names.is_weak_name(ea)           # 是否为弱名称?

db.names.make_name_public(ea)
db.names.make_name_non_public(ea)
db.names.make_name_weak(ea)
db.names.make_name_non_weak(ea)

Demangling

名称解混淆

python
from ida_domain.names import DemangleFlags

demangled = db.names.get_demangled_name(ea)
demangled = db.names.get_demangled_name(ea, DemangleFlags.NORETTYPE)
demangled = db.names.demangle_name("?main@@YAXXZ")

python
from ida_domain.names import DemangleFlags

demangled = db.names.get_demangled_name(ea)
demangled = db.names.get_demangled_name(ea, DemangleFlags.NORETTYPE)
demangled = db.names.demangle_name("?main@@YAXXZ")

Types

类型

Getting Types

获取类型

python
undefined
python
undefined

By name

通过名称获取

tinfo = db.types.get_by_name("MyStruct")
tinfo = db.types.get_by_name("MyStruct")

At address

通过地址获取

tinfo = db.types.get_at(ea)
tinfo = db.types.get_at(ea)

Iterate all types

遍历所有类型

for tinfo in db.types: print(tinfo)
undefined
for tinfo in db.types: print(tinfo)
undefined

Parsing Types

解析类型

python
undefined
python
undefined

Parse declarations from string

从字符串解析类型声明

errors = db.types.parse_declarations(None, "struct Point { int x; int y; };")
errors = db.types.parse_declarations(None, "struct Point { int x; int y; };")

Parse single declaration

解析单个类型声明

tinfo = db.types.parse_one_declaration(None, "int (callback)(void)", "callback_t")
tinfo = db.types.parse_one_declaration(None, "int (callback)(void)", "callback_t")

Parse header file

解析头文件

errors = db.types.parse_header_file(library, Path("header.h"))
undefined
errors = db.types.parse_header_file(library, Path("header.h"))
undefined

Applying Types

应用类型

python
from ida_domain.types import TypeApplyFlags

db.types.apply_at(tinfo, ea, flags=TypeApplyFlags.DEFINITE)
python
from ida_domain.types import TypeApplyFlags

db.types.apply_at(tinfo, ea, flags=TypeApplyFlags.DEFINITE)

Type Details

类型详情

python
details = db.types.get_details(tinfo)
print(details.name)
print(details.size)
print(details.attributes)
python
details = db.types.get_details(tinfo)
print(details.name)
print(details.size)
print(details.attributes)

For structs/unions

针对结构体/联合体

if details.udt: print(details.udt.num_members) print(details.udt.attributes)
if details.udt: print(details.udt.num_members) print(details.udt.attributes)

For functions

针对函数

if details.func: print(details.func.attributes)
undefined
if details.func: print(details.func.attributes)
undefined

Type Libraries

类型库

python
undefined
python
undefined

Load/create libraries

加载/创建类型库

lib = db.types.load_library(Path("types.til")) lib = db.types.create_library(Path("new.til"), "My Types")
lib = db.types.load_library(Path("types.til")) lib = db.types.create_library(Path("new.til"), "My Types")

Import/export types

导入/导出类型

db.types.import_type(source_lib, "MyStruct") db.types.export_type(dest_lib, "MyStruct")
db.types.import_type(source_lib, "MyStruct") db.types.export_type(dest_lib, "MyStruct")

Save library

保存类型库

db.types.save_library(lib, Path("output.til")) db.types.unload_library(lib)

---
db.types.save_library(lib, Path("output.til")) db.types.unload_library(lib)

---

Bytes

字节操作

Reading Values

读取值

python
byte = db.bytes.get_byte_at(ea)
word = db.bytes.get_word_at(ea)
dword = db.bytes.get_dword_at(ea)
qword = db.bytes.get_qword_at(ea)
float_val = db.bytes.get_float_at(ea)
double_val = db.bytes.get_double_at(ea)
python
byte = db.bytes.get_byte_at(ea)
word = db.bytes.get_word_at(ea)
dword = db.bytes.get_dword_at(ea)
qword = db.bytes.get_qword_at(ea)
float_val = db.bytes.get_float_at(ea)
double_val = db.bytes.get_double_at(ea)

Read multiple bytes

读取多个字节

data = db.bytes.get_bytes_at(ea, size=16) original = db.bytes.get_original_bytes_at(ea, size=16)
data = db.bytes.get_bytes_at(ea, size=16) original = db.bytes.get_original_bytes_at(ea, size=16)

Read strings

读取字符串

string = db.bytes.get_string_at(ea) cstring = db.bytes.get_cstring_at(ea, max_length=256)
undefined
string = db.bytes.get_string_at(ea) cstring = db.bytes.get_cstring_at(ea, max_length=256)
undefined

Writing Values

写入值

python
db.bytes.set_byte_at(ea, 0x90)
db.bytes.set_word_at(ea, 0x1234)
db.bytes.set_dword_at(ea, 0x12345678)
db.bytes.set_qword_at(ea, 0x123456789ABCDEF0)
db.bytes.set_bytes_at(ea, b"\x90\x90\x90")
python
db.bytes.set_byte_at(ea, 0x90)
db.bytes.set_word_at(ea, 0x1234)
db.bytes.set_dword_at(ea, 0x12345678)
db.bytes.set_qword_at(ea, 0x123456789ABCDEF0)
db.bytes.set_bytes_at(ea, b"\x90\x90\x90")

Patching (with History)

补丁操作(带历史记录)

python
db.bytes.patch_byte_at(ea, 0x90)     # Saves original
db.bytes.patch_bytes_at(ea, data)
db.bytes.revert_byte_at(ea)          # Restore original
python
db.bytes.patch_byte_at(ea, 0x90)     # 保存原始值
db.bytes.patch_bytes_at(ea, data)
db.bytes.revert_byte_at(ea)          # 恢复原始值

Get original values

获取原始值

orig = db.bytes.get_original_byte_at(ea)
undefined
orig = db.bytes.get_original_byte_at(ea)
undefined

Searching

搜索

python
from ida_domain.bytes import SearchFlags
python
from ida_domain.bytes import SearchFlags

Find bytes

查找字节序列

ea = db.bytes.find_bytes_between(b"\x55\x89\xe5", start_ea, end_ea)
ea = db.bytes.find_bytes_between(b"\x55\x89\xe5", start_ea, end_ea)

Find all occurrences

查找所有匹配项

addresses = db.bytes.find_binary_sequence(b"\x90\x90")
addresses = db.bytes.find_binary_sequence(b"\x90\x90")

Find text

查找文本

ea = db.bytes.find_text_between("error", flags=SearchFlags.DOWN)
ea = db.bytes.find_text_between("error", flags=SearchFlags.DOWN)

Find immediate value

查找立即数

ea = db.bytes.find_immediate_between(0x1234)
undefined
ea = db.bytes.find_immediate_between(0x1234)
undefined

Creating Data Items

创建数据项

python
from ida_domain.strings import StringType

db.bytes.create_byte_at(ea, count=4)
db.bytes.create_word_at(ea)
db.bytes.create_dword_at(ea, count=10)  # Array of 10 dwords
db.bytes.create_qword_at(ea)
db.bytes.create_float_at(ea)
db.bytes.create_double_at(ea)
db.bytes.create_string_at(ea, string_type=StringType.C)
db.bytes.create_struct_at(ea, count=1, tid=struct_tid)
python
from ida_domain.strings import StringType

db.bytes.create_byte_at(ea, count=4)
db.bytes.create_word_at(ea)
db.bytes.create_dword_at(ea, count=10)  # 创建10个双字的数组
db.bytes.create_qword_at(ea)
db.bytes.create_float_at(ea)
db.bytes.create_double_at(ea)
db.bytes.create_string_at(ea, string_type=StringType.C)
db.bytes.create_struct_at(ea, count=1, tid=struct_tid)

Querying Properties

查询属性

python
size = db.bytes.get_data_size_at(ea)
db.bytes.is_value_initialized_at(ea)
db.bytes.is_code_at(ea)
db.bytes.is_data_at(ea)
db.bytes.is_head_at(ea)
db.bytes.is_tail_at(ea)
db.bytes.is_unknown_at(ea)
python
size = db.bytes.get_data_size_at(ea)
db.bytes.is_value_initialized_at(ea)
db.bytes.is_code_at(ea)
db.bytes.is_data_at(ea)
db.bytes.is_head_at(ea)
db.bytes.is_tail_at(ea)
db.bytes.is_unknown_at(ea)

Get disassembly at address

获取指定地址的反汇编代码

disasm = db.bytes.get_disassembly_at(ea)
undefined
disasm = db.bytes.get_disassembly_at(ea)
undefined

Navigation

导航

python
next_head = db.bytes.get_next_head(ea)
prev_head = db.bytes.get_previous_head(ea)
next_addr = db.bytes.get_next_address(ea)
prev_addr = db.bytes.get_previous_address(ea)

python
next_head = db.bytes.get_next_head(ea)
prev_head = db.bytes.get_previous_head(ea)
next_addr = db.bytes.get_next_address(ea)
prev_addr = db.bytes.get_previous_address(ea)

Comments

注释

Regular Comments

常规注释

python
from ida_domain.comments import CommentKind
python
from ida_domain.comments import CommentKind

Get comment

获取注释

info = db.comments.get_at(ea, CommentKind.REGULAR) if info: print(info.comment)
info = db.comments.get_at(ea, CommentKind.REGULAR) if info: print(info.comment)

Set comment

设置注释

db.comments.set_at(ea, "This is important", CommentKind.REGULAR) db.comments.set_at(ea, "Shows everywhere", CommentKind.REPEATABLE)
db.comments.set_at(ea, "This is important", CommentKind.REGULAR) db.comments.set_at(ea, "Shows everywhere", CommentKind.REPEATABLE)

Delete comment

删除注释

db.comments.delete_at(ea, CommentKind.ALL)
undefined
db.comments.delete_at(ea, CommentKind.ALL)
undefined

Iterating Comments

遍历注释

python
for comment_info in db.comments:
    print(f"{comment_info.ea:#x}: {comment_info.comment}")
python
for comment_info in db.comments:
    print(f"{comment_info.ea:#x}: {comment_info.comment}")

All comment types

遍历所有类型的注释

for info in db.comments.get_all(CommentKind.ALL): print(f"{info.ea:#x} (repeatable={info.repeatable}): {info.comment}")
undefined
for info in db.comments.get_all(CommentKind.ALL): print(f"{info.ea:#x} (repeatable={info.repeatable}): {info.comment}")
undefined

Extra Comments (Anterior/Posterior)

额外注释(前置/后置)

python
from ida_domain.comments import ExtraCommentKind
python
from ida_domain.comments import ExtraCommentKind

Set extra comment

设置额外注释

db.comments.set_extra_at(ea, index=0, comment="Before line", kind=ExtraCommentKind.ANTERIOR) db.comments.set_extra_at(ea, index=0, comment="After line", kind=ExtraCommentKind.POSTERIOR)
db.comments.set_extra_at(ea, index=0, comment="Before line", kind=ExtraCommentKind.ANTERIOR) db.comments.set_extra_at(ea, index=0, comment="After line", kind=ExtraCommentKind.POSTERIOR)

Get extra comments

获取额外注释

comment = db.comments.get_extra_at(ea, index=0, kind=ExtraCommentKind.ANTERIOR) for comment in db.comments.get_all_extra_at(ea, ExtraCommentKind.ANTERIOR): print(comment)
comment = db.comments.get_extra_at(ea, index=0, kind=ExtraCommentKind.ANTERIOR) for comment in db.comments.get_all_extra_at(ea, ExtraCommentKind.ANTERIOR): print(comment)

Delete

删除额外注释

db.comments.delete_extra_at(ea, index=0, kind=ExtraCommentKind.ANTERIOR)

---
db.comments.delete_extra_at(ea, index=0, kind=ExtraCommentKind.ANTERIOR)

---

Entries

入口点

Iterating Entry Points

遍历入口点

python
for entry in db.entries:
    print(f"{entry.ordinal}: {entry.name} at {entry.address:#x}")

count = len(db.entries)
first = db.entries[0]
python
for entry in db.entries:
    print(f"{entry.ordinal}: {entry.name} at {entry.address:#x}")

count = len(db.entries)
first = db.entries[0]

Finding Entries

查找入口点

python
entry = db.entries.get_at(ea)              # By address
entry = db.entries.get_by_ordinal(1)       # By ordinal
entry = db.entries.get_by_name("main")     # By name
entry = db.entries.get_at_index(0)         # By index
python
entry = db.entries.get_at(ea)              # 通过地址查找
entry = db.entries.get_by_ordinal(1)       # 通过序号查找
entry = db.entries.get_by_name("main")     # 通过名称查找
entry = db.entries.get_at_index(0)         # 通过索引查找

Entry Properties

入口点属性

python
print(entry.ordinal)
print(entry.address)
print(entry.name)
print(entry.forwarder_name)
entry.has_forwarder()
python
print(entry.ordinal)
print(entry.address)
print(entry.name)
print(entry.forwarder_name)
entry.has_forwarder()

Modifying Entries

修改入口点

python
db.entries.add(address=ea, name="new_entry", ordinal=10)
db.entries.rename(ordinal=10, new_name="renamed_entry")
db.entries.set_forwarder(ordinal=10, forwarder_name="other.dll!func")
db.entries.exists(ordinal=10)
python
db.entries.add(address=ea, name="new_entry", ordinal=10)
db.entries.rename(ordinal=10, new_name="renamed_entry")
db.entries.set_forwarder(ordinal=10, forwarder_name="other.dll!func")
db.entries.exists(ordinal=10)

Utility Iterators

实用迭代器

python
for ordinal in db.entries.get_ordinals():
    print(ordinal)

for addr in db.entries.get_addresses():
    print(f"{addr:#x}")

for name in db.entries.get_names():
    print(name)

for fwd in db.entries.get_forwarders():
    print(f"{fwd.ordinal}: {fwd.name}")

python
for ordinal in db.entries.get_ordinals():
    print(ordinal)

for addr in db.entries.get_addresses():
    print(f"{addr:#x}")

for name in db.entries.get_names():
    print(name)

for fwd in db.entries.get_forwarders():
    print(f"{fwd.ordinal}: {fwd.name}")

Heads

头部项

Iterating Heads

遍历头部项

python
for ea in db.heads:
    print(f"Head at {ea:#x}")
python
for ea in db.heads:
    print(f"Head at {ea:#x}")

In range

遍历地址范围内的头部项

for ea in db.heads.get_between(start_ea, end_ea): print(ea)
undefined
for ea in db.heads.get_between(start_ea, end_ea): print(ea)
undefined

Navigation

导航

python
next_ea = db.heads.get_next(ea)
prev_ea = db.heads.get_previous(ea)
python
next_ea = db.heads.get_next(ea)
prev_ea = db.heads.get_previous(ea)

Head Properties

头部项属性

python
db.heads.is_head(ea)      # Is start of item?
db.heads.is_tail(ea)      # Is part of multi-byte item?
db.heads.is_code(ea)      # Is instruction?
db.heads.is_data(ea)      # Is data?
db.heads.is_unknown(ea)   # Is unclassified?

size = db.heads.size(ea)
start, end = db.heads.bounds(ea)

python
db.heads.is_head(ea)      # 是否为项的起始地址?
db.heads.is_tail(ea)      # 是否为多字节项的一部分?
db.heads.is_code(ea)      # 是否为指令?
db.heads.is_data(ea)      # 是否为数据?
db.heads.is_unknown(ea)   # 是否未分类?

size = db.heads.size(ea)
start, end = db.heads.bounds(ea)

Flowchart

流程图

Creating Flowcharts

创建流程图

python
from ida_domain.flowchart import FlowChart, FlowChartFlags
python
from ida_domain.flowchart import FlowChart, FlowChartFlags

From function

基于函数创建

flowchart = FlowChart(db, func=my_func)
flowchart = FlowChart(db, func=my_func)

From address range

基于地址范围创建

flowchart = FlowChart(db, bounds=(start_ea, end_ea))
flowchart = FlowChart(db, bounds=(start_ea, end_ea))

With predecessor info

包含前驱信息

flowchart = FlowChart(db, func=my_func, flags=FlowChartFlags.PREDS)
undefined
flowchart = FlowChart(db, func=my_func, flags=FlowChartFlags.PREDS)
undefined

Iterating Basic Blocks

遍历基本块

python
for block in flowchart:
    print(f"Block {block.id}: {block.start_ea:#x} - {block.end_ea:#x}")
python
for block in flowchart:
    print(f"Block {block.id}: {block.start_ea:#x} - {block.end_ea:#x}")

By index

通过索引获取

block = flowchart[0] count = len(flowchart)
undefined
block = flowchart[0] count = len(flowchart)
undefined

Block Navigation

基本块导航

python
for succ in block.get_successors():
    print(f"Successor: {succ.id}")

for pred in block.get_predecessors():
    print(f"Predecessor: {pred.id}")

succ_count = block.count_successors()
pred_count = block.count_predecessors()
python
for succ in block.get_successors():
    print(f"Successor: {succ.id}")

for pred in block.get_predecessors():
    print(f"Predecessor: {pred.id}")

succ_count = block.count_successors()
pred_count = block.count_predecessors()

Block Instructions

基本块指令

python
for insn in block.get_instructions():
    print(f"{insn.ea:#x}")

python
for insn in block.get_instructions():
    print(f"{insn.ea:#x}")

Enums Reference

枚举参考

XrefType

XrefType

python
from ida_domain.xrefs import XrefType

XrefType.OFFSET       # Offset reference
XrefType.WRITE        # Write access
XrefType.READ         # Read access
XrefType.CALL_FAR     # Far call
XrefType.CALL_NEAR    # Near call
XrefType.JUMP_FAR     # Far jump
XrefType.JUMP_NEAR    # Near jump
XrefType.ORDINARY_FLOW  # Sequential flow

xref_type.is_code_ref()  # Check if code ref
xref_type.is_data_ref()  # Check if data ref
python
from ida_domain.xrefs import XrefType

XrefType.OFFSET       # 偏移引用
XrefType.WRITE        # 写入访问
XrefType.READ         # 读取访问
XrefType.CALL_FAR     # 远调用
XrefType.CALL_NEAR    # 近调用
XrefType.JUMP_FAR     # 远跳转
XrefType.JUMP_NEAR    # 近跳转
XrefType.ORDINARY_FLOW  # 顺序执行流

xref_type.is_code_ref()  # 检查是否为代码引用
xref_type.is_data_ref()  # 检查是否为数据引用

FunctionFlags

FunctionFlags

python
from ida_domain.functions import FunctionFlags

FunctionFlags.NORET      # Doesn't return
FunctionFlags.LIB        # Library function
FunctionFlags.THUNK      # Thunk function
FunctionFlags.HIDDEN     # Hidden chunk
FunctionFlags.LUMINA     # From Lumina
FunctionFlags.FAR        # Far function
FunctionFlags.FRAME      # Uses frame pointer
python
from ida_domain.functions import FunctionFlags

FunctionFlags.NORET      # 不返回
FunctionFlags.LIB        # 库函数
FunctionFlags.THUNK      # 跳转函数
FunctionFlags.HIDDEN     # 隐藏块
FunctionFlags.LUMINA     # 来自Lumina
FunctionFlags.FAR        # 远函数
FunctionFlags.FRAME      # 使用帧指针

LocalVariableAccessType

LocalVariableAccessType

python
from ida_domain.functions import LocalVariableAccessType

LocalVariableAccessType.READ     # Variable is read
LocalVariableAccessType.WRITE    # Variable is written
LocalVariableAccessType.ADDRESS  # Address taken (&var)
python
from ida_domain.functions import LocalVariableAccessType

LocalVariableAccessType.READ     # 变量被读取
LocalVariableAccessType.WRITE    # 变量被写入
LocalVariableAccessType.ADDRESS  # 取变量地址(&var)

LocalVariableContext

LocalVariableContext

python
from ida_domain.functions import LocalVariableContext

LocalVariableContext.ASSIGNMENT    # var = expr
LocalVariableContext.CONDITION     # if (var)
LocalVariableContext.CALL_ARG      # func(var)
LocalVariableContext.RETURN        # return var
LocalVariableContext.ARITHMETIC    # var + 1
LocalVariableContext.COMPARISON    # var == x
LocalVariableContext.ARRAY_INDEX   # arr[var]
LocalVariableContext.POINTER_DEREF # *var
LocalVariableContext.CAST          # (type)var
python
from ida_domain.functions import LocalVariableContext

LocalVariableContext.ASSIGNMENT    # var = expr
LocalVariableContext.CONDITION     # if (var)
LocalVariableContext.CALL_ARG      # func(var)
LocalVariableContext.RETURN        # return var
LocalVariableContext.ARITHMETIC    # var + 1
LocalVariableContext.COMPARISON    # var == x
LocalVariableContext.ARRAY_INDEX   # arr[var]
LocalVariableContext.POINTER_DEREF # *var
LocalVariableContext.CAST          # (type)var

OperandType

OperandType

python
from ida_domain.operands import OperandType

OperandType.REGISTER      # Register
OperandType.MEMORY        # Direct memory
OperandType.PHRASE        # Register addressing
OperandType.DISPLACEMENT  # Reg + displacement
OperandType.IMMEDIATE     # Immediate value
OperandType.FAR_ADDRESS   # Far address
OperandType.NEAR_ADDRESS  # Near address
python
from ida_domain.operands import OperandType

OperandType.REGISTER      # 寄存器
OperandType.MEMORY        # 直接内存
OperandType.PHRASE        # 寄存器寻址
OperandType.DISPLACEMENT  # 寄存器+偏移
OperandType.IMMEDIATE     # 立即数
OperandType.FAR_ADDRESS   # 远地址
OperandType.NEAR_ADDRESS  # 近地址

StringType

StringType

python
from ida_domain.strings import StringType

StringType.C        # C-style null-terminated
StringType.C_16     # C-style 16-bit
StringType.C_32     # C-style 32-bit
StringType.PASCAL   # Pascal-style
StringType.LEN2     # 2-byte length prefix
StringType.LEN4     # 4-byte length prefix
python
from ida_domain.strings import StringType

StringType.C        # C风格空终止字符串
StringType.C_16     # C风格16位字符串
StringType.C_32     # C风格32位字符串
StringType.PASCAL   # Pascal风格字符串
StringType.LEN2     # 2字节长度前缀
StringType.LEN4     # 4字节长度前缀

SegmentPermissions

SegmentPermissions

python
from ida_domain.segments import SegmentPermissions

SegmentPermissions.READ
SegmentPermissions.WRITE
SegmentPermissions.EXEC
SegmentPermissions.ALL
python
from ida_domain.segments import SegmentPermissions

SegmentPermissions.READ
SegmentPermissions.WRITE
SegmentPermissions.EXEC
SegmentPermissions.ALL

AddressingMode

AddressingMode

python
from ida_domain.segments import AddressingMode

AddressingMode.BIT16  # 16-bit segment
AddressingMode.BIT32  # 32-bit segment
AddressingMode.BIT64  # 64-bit segment
python
from ida_domain.segments import AddressingMode

AddressingMode.BIT16  # 16位段
AddressingMode.BIT32  # 32位段
AddressingMode.BIT64  # 64位段

PredefinedClass

PredefinedClass

python
from ida_domain.segments import PredefinedClass

PredefinedClass.CODE
PredefinedClass.DATA
PredefinedClass.CONST
PredefinedClass.STACK
PredefinedClass.BSS
PredefinedClass.XTRN
python
from ida_domain.segments import PredefinedClass

PredefinedClass.CODE
PredefinedClass.DATA
PredefinedClass.CONST
PredefinedClass.STACK
PredefinedClass.BSS
PredefinedClass.XTRN

CommentKind

CommentKind

python
from ida_domain.comments import CommentKind

CommentKind.REGULAR     # Normal comment
CommentKind.REPEATABLE  # Shows at all refs
CommentKind.ALL         # Both types
python
from ida_domain.comments import CommentKind

CommentKind.REGULAR     # 普通注释
CommentKind.REPEATABLE  # 在所有引用处显示
CommentKind.ALL         # 两种类型

ExtraCommentKind

ExtraCommentKind

python
from ida_domain.comments import ExtraCommentKind

ExtraCommentKind.ANTERIOR   # Before the line
ExtraCommentKind.POSTERIOR  # After the line
python
from ida_domain.comments import ExtraCommentKind

ExtraCommentKind.ANTERIOR   # 行前注释
ExtraCommentKind.POSTERIOR  # 行后注释

TypeAttr

TypeAttr

python
from ida_domain.types import TypeAttr

TypeAttr.INT, TypeAttr.UINT
TypeAttr.FLOAT, TypeAttr.DOUBLE
TypeAttr.PTR, TypeAttr.ARRAY
TypeAttr.FUNC, TypeAttr.STRUCT
TypeAttr.UNION, TypeAttr.ENUM
TypeAttr.CONST, TypeAttr.VOLATILE
python
from ida_domain.types import TypeAttr

TypeAttr.INT, TypeAttr.UINT
TypeAttr.FLOAT, TypeAttr.DOUBLE
TypeAttr.PTR, TypeAttr.ARRAY
TypeAttr.FUNC, TypeAttr.STRUCT
TypeAttr.UNION, TypeAttr.ENUM
TypeAttr.CONST, TypeAttr.VOLATILE

FlowChartFlags

FlowChartFlags

python
from ida_domain.flowchart import FlowChartFlags

FlowChartFlags.NONE   # Default
FlowChartFlags.NOEXT  # Don't compute external blocks
FlowChartFlags.PREDS  # Compute predecessors

python
from ida_domain.flowchart import FlowChartFlags

FlowChartFlags.NONE   # 默认
FlowChartFlags.NOEXT  # 不计算外部块
FlowChartFlags.PREDS  # 计算前驱块

Common Patterns

常见模式

Find All Calls to a Function

查找对指定函数的所有调用

python
func = db.functions.get_function_by_name("malloc")
if func:
    for caller in db.xrefs.get_callers(func.start_ea):
        print(f"Called from {caller.name} at {caller.ea:#x}")
python
func = db.functions.get_function_by_name("malloc")
if func:
    for caller in db.xrefs.get_callers(func.start_ea):
        print(f"Called from {caller.name} at {caller.ea:#x}")

Rename Functions Based on Strings

根据字符串重命名函数

python
for func in db.functions:
    for insn in db.functions.get_instructions(func):
        for xref in db.xrefs.from_ea(insn.ea):
            string = db.strings.get_at(xref.to_ea)
            if string and "error" in str(string).lower():
                db.functions.set_name(func, f"func_with_error_{func.start_ea:x}")
                break
python
for func in db.functions:
    for insn in db.functions.get_instructions(func):
        for xref in db.xrefs.from_ea(insn.ea):
            string = db.strings.get_at(xref.to_ea)
            if string and "error" in str(string).lower():
                db.functions.set_name(func, f"func_with_error_{func.start_ea:x}")
                break

Analyze Function Complexity

分析函数复杂度

python
func = db.functions.get_at(ea)
flowchart = db.functions.get_flowchart(func)
print(f"Basic blocks: {len(flowchart)}")

total_edges = sum(block.count_successors() for block in flowchart)
print(f"Cyclomatic complexity: {total_edges - len(flowchart) + 2}")
python
func = db.functions.get_at(ea)
flowchart = db.functions.get_flowchart(func)
print(f"Basic blocks: {len(flowchart)}")

total_edges = sum(block.count_successors() for block in flowchart)
print(f"Cyclomatic complexity: {total_edges - len(flowchart) + 2}")

Export Function Pseudocode

导出函数伪代码

python
for func in db.functions:
    name = db.functions.get_name(func)
    try:
        pseudocode = db.functions.get_pseudocode(func)
        print(f"// {name}")
        for line in pseudocode:
            print(line)
    except RuntimeError:
        print(f"// Could not decompile {name}")
python
for func in db.functions:
    name = db.functions.get_name(func)
    try:
        pseudocode = db.functions.get_pseudocode(func)
        print(f"// {name}")
        for line in pseudocode:
            print(line)
    except RuntimeError:
        print(f"// Could not decompile {name}")

Find Cross-References to Strings

查找字符串的交叉引用

python
for string in db.strings:
    refs = list(db.xrefs.to_ea(string.address))
    if refs:
        print(f'"{string}" referenced from:')
        for xref in refs:
            print(f"  {xref.from_ea:#x}")
python
for string in db.strings:
    refs = list(db.xrefs.to_ea(string.address))
    if refs:
        print(f'"{string}" referenced from:')
        for xref in refs:
            print(f"  {xref.from_ea:#x}")

Legacy API (Avoid)

旧版API(避免使用)

The legacy
idc
,
idautils
,
ida_funcs
APIs still work but are harder to use. Prefer the Domain API for new analysis scripts. Only use legacy APIs when Domain API doesn't expose needed functionality.
旧版
idc
idautils
ida_funcs
API仍然可用,但使用难度更高。优先使用Domain API开发新的分析脚本。仅当Domain API未提供所需功能时,才使用旧版API。