mcpField
D
disassembly

disassembly

github.com/allthingsida开发4965 次安装3 周前更新
代码仓库

关于 disassembly

disassembly 是一项通过 IDASQL 检查二进制代码的技能,涵盖指令、函数和控制流。它支持基于 SQL 的分析与编辑,并将语义解读、关系分析和调试交由其他技能处理。

主要功能

  1. 01检查函数、段、指令和操作数
  2. 02分析基本块和控制流边
  3. 03查询已解析的调用目标和调用点类型
  4. 04编辑名称、函数元数据和操作数格式

适用场景

  1. 01检查函数中的指令序列
  2. 02追踪调用点并查看目标
  3. 03调查二进制行为时审查控制流
  4. 04设置操作数格式或更新函数与符号名称

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/allthingsida/idasql-skills --skill disassembly

安装后在 Claude Code 中输入/disassembly确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
references/
disassembly-examples.md
disassembly-tables.md

详细介绍


触发意图

用户提出以下请求时使用此技能:

  • 检查函数/代码段/指令
  • 基于反汇编分析调用点或控制流
  • 操作数格式化和底层代码结构
  • 原始字节/指令级证据

转交给:

  • decompiler,用于 AST/伪代码语义分析
  • xrefs,用于涉及大量关系的调用者/被调用者工作流
  • debugger,用于修补/断点操作

首先执行(热启动序列)

-- 1) Orientation
SELECT * FROM binary;

-- 2) Segment map
SELECT name, printf('0x%X', start_addr) AS start_addr, printf('0x%X', end_addr) AS end_addr, perm
FROM segments
ORDER BY start_addr;

-- 3) Largest functions (triage anchors)
SELECT name, printf('0x%X', addr) AS addr, size
FROM funcs
ORDER BY size DESC
LIMIT 20;

解读指南:

  • 从可执行段以及规模最大/连接最密集的函数入手。
  • 查询指令密集型数据时,尽早使用 func_addr 约束。

故障与恢复

  • 查询 instructions/heads 较慢:
    • 添加 WHERE func_addr = X 或使用紧密的 EA 范围。
  • 缺少预期的符号名称:
    • 转而采用基于地址的工作流,之后再通过 names 更新补充信息。
  • 控制流行为不明确:
    • 使用 disasm_calls 交叉核对,然后升级到 decompiler。

交接模式

  1. disassembly -> xrefs,用于扩展关系。
  2. disassembly -> decompiler,用于语义解释。
  3. disassembly -> debugger,用于执行修补/断点操作。

实体表

funcs

二进制文件中检测到的所有函数及其原型信息。

列类型描述
addrINT函数起始地址
nameTEXT函数名称
sizeINT函数大小(字节)
end_addrINT函数结束地址
flagsINT函数标志
folder_pathTEXT相对于 Function 窗口根目录的可读写函数文件夹路径;NULL/'' 表示根目录
full_pathTEXT只读的完整 dirtree 路径,包含函数名称

原型列(有类型信息时填充):

列类型描述
return_typeTEXT返回类型字符串(例如,“int”、“void *”)
return_is_ptrINT返回类型为指针时为 1
return_is_intINT返回类型恰为 int 时为 1
return_is_integralINT返回类型为类 int 类型(int、long、DWORD、BOOL)时为 1
return_is_voidINT返回类型为 void 时为 1
arg_countINT函数参数数量
calling_convTEXT调用约定(cdecl、stdcall、fastcall 等)
-- 10 largest functions
SELECT name, size FROM funcs ORDER BY size DESC LIMIT 10;

-- Functions starting with "sub_" (auto-named, not analyzed)
SELECT name, printf('0x%X', addr) as addr FROM funcs WHERE name LIKE 'sub_%';

-- Functions returning integers with 3+ arguments
SELECT name, return_type, arg_count FROM funcs
WHERE return_is_integral = 1 AND arg_count >= 3;

-- Functions organized by IDASQL annotation folders
SELECT addr, name, folder_path
FROM funcs
WHERE folder_path LIKE 'idasql/%'
ORDER BY folder_path, name;

写入操作:

-- Create a function
INSERT INTO funcs (addr) VALUES (0x401000);

-- Rename a function
UPDATE funcs SET name = 'my_func' WHERE addr = 0x401000;

-- Move a function into an IDA Function window folder
INSERT INTO dirtree_folders(tree, path) VALUES ('funcs', 'idasql/triage/network');
UPDATE funcs SET folder_path = 'idasql/triage/network' WHERE addr = 0x401000;

-- Move it back to root
UPDATE funcs SET folder_path = NULL WHERE addr = 0x401000;

-- Delete a function
DELETE FROM funcs WHERE addr = 0x401000;

文件夹路径使用相对 / 路径。IDASQL 会拒绝 ./..、重复分隔符、反斜杠、非空文件夹删除,以及目标已存在的文件夹重命名。

segments

内存段。支持完整的 CRUD:INSERT 一个区域、DELETE 一个区域,以及 UPDATE start_addr(重定位/移动)、end_addr(调整大小)、name、class、perm。

列类型RW描述
start_addrINTRW段起始地址;UPDATE 会重定位(移动)该段
end_addrINTRW段结束地址;UPDATE 会调整该段大小
nameTEXTRW段名称(.text、.data 等)
classTEXTRW段类别(CODE、DATA)
permINTRW权限(R=4、W=2、X=1)
-- Find executable segments
SELECT name, printf('0x%X', start_addr) as start FROM segments WHERE perm & 1 = 1;

-- Rename a segment
UPDATE segments SET name = '.mytext' WHERE start_addr = 0x401000;

-- Add a region (e.g. SRAM for a raw firmware image), then rebase it
INSERT INTO segments(start_addr, end_addr, name, class, perm)
  VALUES (0x20000000, 0x20005000, 'SRAM', 'DATA', 6);
UPDATE segments SET start_addr = 0x08000000 WHERE name = '.text';  -- rebase
names

所有已命名位置(函数、标签、数据)。支持 INSERT、UPDATE 和 DELETE。

列类型RW描述
addrINTR地址
nameTEXTRW名称
folder_pathTEXTRW名称文件夹路径;NULL 表示根目录
full_pathTEXTR完整的名称 dirtree 路径
-- Create/set a name
INSERT INTO names (addr, name) VALUES (0x401000, 'my_symbol');

-- Rename
UPDATE names SET name = 'my_symbol_renamed' WHERE addr = 0x401000;

-- Organize globals/labels into IDA name folders
UPDATE names SET folder_path = 'idasql/names/globals' WHERE name LIKE 'g_%';
UPDATE names SET folder_path = NULL WHERE addr = 0x401000;
entries

入口点(导出项、程序入口、tls 回调等)。

列类型描述
ordinalINT导出序号
addrINT入口地址
nameTEXT入口名称

指令表

instructions

instructions 是反汇编表。要获取特定 EA 处的标量反汇编文本,请使用 disasm_at(addr[, context])。 只有明确需要函数或范围列表时,才使用 disasm_func() 或 disasm_range()。 已解码的指令支持 DELETE(将指令转换为未探索的字节)以及通过 operand*_format_spec 更新操作数表示形式。

WHERE func_addr = X 是快速路径(函数项迭代器)。如果没有此条件,该表会扫描所有代码头。

ColumnTypeDescription
addrINT指令地址
func_addrINT所属函数
itypeINT指令类型(特定于架构)
mnemonicTEXT指令助记符
sizeINT指令大小
operand0..operand7TEXT操作数文本(0..7)
disasmTEXT完整反汇编行
operand0_class..operand7_classTEXT操作数类别:reg、imm、displ、mem 等
operand0_repr_kind..operand7_repr_kindTEXT当前表示形式:plain、hex、dec、oct、bin、char、float、enum、offset、stroff、sizeof、segment、stkvar、forced
operand0_repr_type_name..operand7_repr_type_nameTEXT枚举、stroff 或 sizeof 类型、偏移基址(十六进制)或强制文本
operand0_format_spec..operand7_format_specTEXT (RW)为特定操作数应用或清除表示形式(参见下方词汇表)
-- Instruction profile of a function (FAST)
SELECT mnemonic, COUNT(*) as count
FROM instructions WHERE func_addr = 0x401330
GROUP BY mnemonic ORDER BY count DESC;

-- Find all call instructions in a function
SELECT addr, disasm FROM instructions
WHERE func_addr = 0x401000 AND mnemonic = 'call';

-- Apply enum representation to operand 1
UPDATE instructions
SET operand1_format_spec = 'enum:MY_ENUM'
WHERE addr = 0x401020;

-- Apply struct-offset representation to operand 0
-- e.g. makes `[rax+10h]` display as `[rax+command_t.field_name]`
UPDATE instructions
SET operand0_format_spec = 'stroff:command_t'
WHERE addr = 0x140001BE8;

-- Struct-offset with a base delta (subtracted before member resolution)
UPDATE instructions
SET operand0_format_spec = 'stroff:command_t,delta=16'
WHERE addr = 0x140001BE8;

-- Nested member path: separate type names with '/'
UPDATE instructions
SET operand0_format_spec = 'stroff:outer_t/inner_t'
WHERE addr = 0x140001BE8;

-- Clear representation back to plain
UPDATE instructions
SET operand1_format_spec = 'clear'
WHERE addr = 0x401020;

应用后会验证格式规范:UPDATE 会重新读取操作数;如果结果的 repr_kind、类型路径或 delta 与请求不匹配,则会失败(并产生 SQL 错误)。读取 operandN_repr_kind / operandN_repr_type_name 以确认。

完整的 operandN_format_spec 词汇表(均为反汇编级操作,无需 IDAPython):

SpecEffect
hex dec oct bin数字基数
char字符常量
float浮点数
offset普通偏移,基址为 0
offset:<base>使用用户定义基址的偏移(<base> = 符号名称或地址)
enum:<NAME>[,serial=N] / enum:<NAME>::<MEMBER>枚举常量
stroff:<Type[/Nested...]>[,delta=N]结构体成员偏移
sizeof:<STRUCT>结构体大小常量——呈现为 size STRUCT
segment段选择器
stkvar栈变量(操作数必须是栈引用)
forced:<text>强制(手动)操作数文本,例如 forced:5 shl 3
clear / plain / none恢复默认表示形式

可组合修饰符(作为后缀添加到任意基项,或单独使用以修改当前表示形式):,signed / ,unsigned(切换负数显示)以及 ,bnot / ,nobnot(切换按位取反显示)。例如:dec,signed、 hex,bnot,或仅使用 signed。

-- Number base, character, and sign/bitwise-not modifiers
UPDATE instructions SET operand1_format_spec = 'hex'        WHERE addr = 0x401020;
UPDATE instructions SET operand1_format_spec = 'dec,signed' WHERE addr = 0x401020;
UPDATE instructions SET operand1_format_spec = 'char'       WHERE addr = 0x401020;

-- Offsets (plain and user-defined base)
UPDATE instructions SET operand1_format_spec = 'offset'            WHERE addr = 0x401020;
UPDATE instructions SET operand1_format_spec = 'offset:tbl_start'  WHERE addr = 0x401020;

-- sizeof: an immediate equal to sizeof(STRUCT) renders as `size STRUCT`
UPDATE instructions SET operand1_format_spec = 'sizeof:FILEDEF' WHERE addr = 0x4015EB;

-- Forced operand text
UPDATE instructions SET operand1_format_spec = 'forced:5 shl 3' WHERE addr = 0x401020;
instruction_operands

每行对应一个已解码的非空操作数。使用此表查询操作数类型和值详情,并联结替代旧操作数/解码辅助函数。

列类型描述
addrINT指令地址
func_addrINT所属函数
opnumINT操作数索引
textTEXT操作数文本
type_codeINTIDA 操作数类型代码
type_nameTEXT操作数类型名称(reg、imm、near……)
dtypeINT操作数 dtype
regINT适用时的寄存器编号
op_addrINT适用时的引用地址/位移
raw_valueINT原始操作数值
valueINT尽可能解析出的标量操作数值

注意(addr 与 op_addr): addr 是指令地址;操作数的引用地址是 op_addr。若要获取操作数指向的目标(例如跳转/调用/数据引用),请选择 op_addr——addr 标识操作数所属的指令,而不是它引用的内容。

SELECT opnum, text, type_name, value
FROM instruction_operands
WHERE addr = 0x401000
ORDER BY opnum;

SELECT i.addr, i.itype, i.mnemonic, o.opnum, o.text, o.type_name, o.value
FROM instructions i
LEFT JOIN instruction_operands o
  ON o.addr = i.addr AND o.func_addr = 0x401000
WHERE i.func_addr = 0x401000
ORDER BY i.addr, o.opnum;

性能:WHERE addr = X 会解码一条指令;WHERE func_addr = X 会进行 O(function_size) 次迭代。若不指定其中一个约束,则会扫描整个数据库。

disasm_calls

所有已解析目标且可选带有调用点原型覆盖的调用指令。

列类型描述
func_addrINT包含该调用的函数
addrINT调用指令地址
callee_addrINT目标地址(未知时为 0)
callee_nameTEXT目标名称
callee_typeTEXT可读写、可空的调用点原型;UPDATE 会应用/替换,NULL 或空值会清除
-- Functions that call malloc
SELECT DISTINCT (SELECT name FROM funcs WHERE func_addr >= addr AND func_addr < end_addr LIMIT 1) as caller
FROM disasm_calls WHERE callee_name LIKE '%malloc%';

-- Apply/replace a call-site prototype, then clear it
UPDATE disasm_calls
SET callee_type = 'int (__fastcall *)(const char *path)'
WHERE addr = 0x401234;
UPDATE disasm_calls SET callee_type = NULL WHERE addr = 0x401234;

在直接调用上应用 callee_type 会保留真实的被调用方符号,因此之后重新反编译调用方是安全的(不会出现 microcode INTERR);在间接调用上,它会为该调用点指定类型。空值/NULL 会清除覆盖。


blocks

函数内的基本块。为提升性能,请使用 func_addr 约束。

列类型描述
func_addrINT所属函数
start_addrINT块起始地址
end_addrINT块结束地址
sizeINT块大小
-- Blocks in a specific function (FAST - uses constraint pushdown)
SELECT * FROM blocks WHERE func_addr = 0x401000;

-- Functions with most basic blocks
SELECT (SELECT name FROM funcs WHERE func_addr >= addr AND func_addr < end_addr LIMIT 1) as name, COUNT(*) as blocks
FROM blocks GROUP BY func_addr ORDER BY blocks DESC LIMIT 10;
cfg_edges

基本块之间的控制流图边。始终使用 WHERE func_addr = X(filter_eq 下推,复杂度为 O(函数内块数))。

列类型描述
func_addrINT所属函数
from_blockINT源块地址
to_blockINT目标块地址
edge_typeTEXTnormal(单后继或回退标签)、true/false(双向分支的通用第一/第二分支;标签遵循后继顺序,而非跳转成立/顺序执行语义)
-- Get CFG structure
SELECT * FROM cfg_edges WHERE func_addr = 0x401000;

-- Find branch points (conditional blocks)
SELECT from_block, COUNT(*) as succ_count
FROM cfg_edges WHERE func_addr = 0x401000
GROUP BY from_block HAVING succ_count > 1;

-- Find merge points (blocks with multiple predecessors)
SELECT to_block, COUNT(*) as pred_count
FROM cfg_edges WHERE func_addr = 0x401000
GROUP BY to_block HAVING pred_count > 1;

-- Function complexity ranking: combine CFG, loops, and call metrics
SELECT f.name, f.size,
       (SELECT COUNT(*)
        FROM (
            SELECT ce.from_block
            FROM cfg_edges ce
            WHERE ce.func_addr = f.addr
            GROUP BY ce.from_block
            HAVING COUNT(*) > 1
        ) branch_blocks) as branch_sites,
       (SELECT COUNT(*) FROM disasm_loops dl WHERE dl.func_addr = f.addr) as loops,
       (SELECT COUNT(*) FROM disasm_calls dc WHERE dc.func_addr = f.addr) as calls_made
FROM funcs f
WHERE f.size > 32
ORDER BY branch_sites DESC
LIMIT 20;
function_chunks

缓存表,每个函数块对应一行。若需计算函数级跨度或密度指标,请按 func_addr 聚合。

列类型描述
func_addrINT函数地址
chunk_startINT块起始地址
chunk_endINT块结束地址
block_countINT块中的块数
total_sizeINT块的总大小
SELECT * FROM function_chunks WHERE func_addr = 0x401000;

SQL 函数——反汇编

函数描述
disasm_at(addr)所属 head 的规范列表行(适用于代码/数据)
disasm_at(addr, n)所属 head 及前后 n 个相邻 head 的规范列表行
disasm(addr)地址处的单条反汇编行
disasm(addr, n)从地址开始的后续 N 条指令(按数量计)
disasm_range(start, end)地址范围 [start, end) 内的所有反汇编行
disasm_func(addr)包含该地址的函数的完整反汇编
make_code(addr)在地址处创建指令(返回 1/0)
make_code_range(start, end)在范围内创建指令,返回创建数量
反汇编示例
-- Canonical single-EA disassembly (safe for code or data)
SELECT disasm_at(0x401000);

-- Canonical context window (+/- 2 heads)
SELECT disasm_at(0x401000, 2);

-- Full function disassembly (resolves boundaries via get_func)
SELECT disasm_func(addr) FROM funcs WHERE name = '_main';

-- Disassemble a specific address range
SELECT disasm_range(0x401000, 0x401100);

-- Sliding window: next 5 instructions from an address
SELECT disasm(0x401000, 5);

SQL 函数——名称与函数

使用表查询地址及其所属函数的元数据。使用以下模式前,先将符号名称解析为整数 EA。

模式描述
SELECT name FROM names WHERE addr = :addr LIMIT 1地址处的名称
SELECT name FROM funcs WHERE :addr >= addr AND :addr < end_addr LIMIT 1包含该地址的函数
SELECT addr FROM funcs WHERE :addr >= addr AND :addr < end_addr LIMIT 1所属函数的起始地址
SELECT end_addr FROM funcs WHERE :addr >= addr AND :addr < end_addr LIMIT 1所属函数的结束地址

函数计数和索引查询由表驱动:

SELECT COUNT(*) AS function_count FROM funcs;
SELECT addr FROM funcs WHERE rowid = 0;

SQL 函数——导航

使用 heads 排序浏览已定义项,并使用 SQLite 格式化函数生成显示字符串。地址相等/范围筛选经过优化;对于查找下一个/上一个项的操作,会使用 ORDER BY addr 或 ORDER BY addr DESC。

SELECT addr
FROM heads
WHERE addr > 0x401000
ORDER BY addr
LIMIT 1;

SELECT addr
FROM heads
WHERE addr < 0x401000
ORDER BY addr DESC
LIMIT 1;

SELECT printf('0x%llx', addr) AS address_hex
FROM heads
LIMIT 10;

段查询由表驱动:

SELECT name
FROM segments
WHERE 0x401000 >= start_addr
  AND 0x401000 < end_addr
LIMIT 1;

SQL 函数——项分析

使用 heads 获取项分类、大小和原始标志:

SELECT addr, size, type, flags, disasm
FROM heads
WHERE addr = 0x401000;

SQL 函数——指令详情

使用 instructions 和 instruction_operands 获取已解码的指令信息:

SELECT addr, itype, mnemonic
FROM instructions
WHERE func_addr = 0x401000
LIMIT 10;

SELECT opnum, text, type_code, type_name, value
FROM instruction_operands
WHERE addr = 0x401000
ORDER BY opnum;

SELECT i.addr, i.itype, i.mnemonic, i.size, o.opnum, o.text, o.type_name, o.value
FROM instructions i
LEFT JOIN instruction_operands o
  ON o.addr = i.addr AND o.addr = 0x401000
WHERE i.addr = 0x401000
ORDER BY o.opnum;

SQL 函数——文件生成

函数描述
gen_listing(path)生成完整数据库的列表输出(LST)

SQL 函数——图生成

函数描述
gen_cfg_dot(addr)将 CFG 生成为 DOT 图字符串
gen_cfg_dot_file(addr, path)将 CFG DOT 写入文件
gen_schema_dot()将数据库架构生成为 DOT
-- Get CFG for a function as DOT format
SELECT gen_cfg_dot(0x401000);

性能规则

表架构关键约束备注
funcs基于索引无需约束通过 getn_func(i) 每行 O(1)——始终快速
instructions迭代器func_addr函数项迭代器(快速),而非扫描所有代码头(慢速)
blocks迭代器func_addr约束下推:迭代单个函数的代码块
cfg_edges迭代器func_addrfilter_eq 下推:复杂度为 O(函数中的代码块数)
disasm_calls生成器写入时使用 func_addr、addr延迟流式处理,遵循 LIMIT;callee_type 可写
heads生成器addr =、地址范围导航上一个/下一个项时使用 ORDER BY addr;范围较大的扫描仍可能耗时
instruction_operands迭代器addr、func_addr地址查询会解码一条指令;函数查询会迭代一个函数
segments基于索引无需约束表较小,始终快速
names迭代器无需约束迭代 IDA 的名称列表

关键规则:

  • funcs 始终快速——无需约束。
  • instructions 不带 func_addr 时会扫描每个代码头——按函数查询时使用 func_addr。
  • blocks 不带 func_addr 时会迭代所有函数的流程图——务必添加约束。
  • heads 通常较大。获取项信息时使用 addr = X;导航时使用地址范围,并结合 ORDER BY addr [DESC] LIMIT 1。

成本模型:

funcs (full scan)            -> O(number of functions), typically ~1000s, fast
instructions WHERE func_addr -> O(function_size / avg_insn_size)
instructions (no constraint) -> O(total_code_heads), potentially 100K+
blocks WHERE func_addr         -> O(block_count_in_func), fast
cfg_edges WHERE func_addr      -> O(block_count_in_func), fast
disasm_calls WHERE func_addr -> O(instructions_in_func), streaming
disasm_calls UPDATE callee_type WHERE addr -> O(1) call-site lookup
heads WHERE addr          -> O(1) IDA head check
heads next/prev LIMIT 1      -> O(distance to next/previous defined head)
instruction_operands addr    -> O(operands in one instruction)
instruction_operands func    -> O(operands in one function)

更多资源


另请参阅

  • decompiler — 同一函数的伪代码和 ctree;反汇编过于杂乱时可切换使用。
  • xrefs — 以函数或调用点为中心的调用图和数据引用。
  • data — 面向操作数目标的字节/字符串;bytes 表可用于逐字节读取,也可通过 WHERE start_addr = X AND n = N 限定窗口,再结合 hex(blob_concat(value)) 批量获取十六进制数据。

评论

支持 Markdown