关于 ida-cli
面向逆向工程人员的 ida-cli 技能,说明如何启动本地服务并通过命令行分析 IDA 数据库或二进制文件。内容还包括反编译、反汇编、结构恢复和分析记录方法。
主要功能
- 01自动安装与运行时探测
- 02查询函数、字符串和交叉引用
- 03反编译与反汇编分析
- 04通过 JSON-RPC 执行请求
- 05提供逆向分析工作流程
适用场景
- 01检查二进制文件的函数与段
- 02追踪函数调用和交叉引用
- 03从代码访问中恢复结构体
- 04核验算术逻辑与反编译结果
MCP 相关
ida-cli 可作为 MCP 服务通过 stdio 或 Streamable HTTP 提供服务。技能主要以客户端模式调用本地自动管理的服务。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ cpkt9762/ ida-cli --skill ida-cli安装后在 Claude Code 中输入/ida-cli确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/binary-analysis-patterns.mdcli-tool-reference.mdcounterfactual-patch.mdheadless-api.mdida-domain-api.mdidalib-headless.mdidapython-cheatsheet.mdobfuscation-triage.mdplugin-development.mdvm-devirt.mdscripts/ida-cli.shvm_devirt_requirements.txtvm_devirt.py详细介绍
ida-cli 逆向工程
通用逆向工程方法,以及实用的 ida-cli 初始化与工作流。该 CLI 是一个轻量客户端,运行在自动管理的本地服务之上,并通过每个数据库对应的工作进程与 IDA 通信。
第 0 部分:零配置初始化
只需安装一次此技能:
npx -y skills add https://github.com/cpkt9762/ida-cli --skill ida-cli --agent codex --yes --global
安装后,不要假设用户已将 ida-cli 添加到 PATH,或已有正在运行的服务。
启动规则
- 在新环境中首次使用时,运行
scripts/ida-cli.sh --help。 - 此包装脚本会检测 PATH 或
~/.local/bin/ida-cli中是否有ida-cli。 - 如果缺少二进制文件,包装脚本会下载并运行仓库安装程序,然后重新运行冒烟测试。
运行时规则
- 正式分析前,运行
scripts/ida-cli.sh probe-runtime。 - 不要猜测主机将选择
native-linked还是idat-compat。 - 如果存在多个 IDA 安装,请显式导出
IDADIR:export IDADIR="/Applications/IDA Professional 9.5.app/Contents/MacOS"export IDADIR=/opt/ida-pro-9.5
- 只有当运行时与二进制文件构建时使用的 SDK 匹配时,IDA 9.3 / 9.5 才会选择
native-linked;否则探测结果会报告idat-compat,它支持的方法较少。
使用规则
- 在此技能中,优先使用
scripts/ida-cli.sh作为唯一入口。 - 日常工作中不要让用户运行
serve或serve-http。任何客户端子命令都会自动启动一个绑定到随机端口的本地 HTTP 服务,并写入/tmp/ida-cli.socket以供发现。 - 只有在确实需要长期运行且可寻址的 HTTP 控制平面时,才显式运行
serve-http --bind ...。
零配置命令
# 1. install ida-cli or confirm it is available
scripts/ida-cli.sh --help
# 2. probe the selected runtime backend
scripts/ida-cli.sh probe-runtime
# 3. routine analysis (client mode, auto-starts a server)
scripts/ida-cli.sh --path /path/to/sample.bin list-functions --limit 20
scripts/ida-cli.sh --path /path/to/sample.bin decompile --addr 0x140001000
# 4. only when a shared HTTP endpoint is actually needed
scripts/ida-cli.sh serve-http --bind 127.0.0.1:8765
环境变量选项
- 安装目标:
~/.local/bin/ida-cli - 固定源代码仓库 / 引用:
IDA_CLI_REPO=cpkt9762/ida-cliIDA_CLI_INSTALL_REF=master
- 传递额外的安装程序参数:
IDA_CLI_INSTALL_ARGS="--add-path"
- 固定特定的 IDA 安装:
export IDADIR=/path/to/ida/Contents/MacOS
在此技能中,scripts/ida-cli.sh 是安装、下载、执行和验证的唯一入口。
第 1 部分:CLI 功能概览
ida-cli 有两种模式:
- 扁平客户端 — 此技能使用的模式。每次调用发送一个请求。
- 服务 —
serve(stdio MCP)、serve-http(Streamable HTTP MCP)、serve-worker(内部子进程)、probe-runtime(内部)。
当二进制文件名为 ida-cli 且第一个参数不是服务子命令时,CLI 会将参数解析为客户端调用,并通过本地套接字路由请求。
直接子命令(客户端模式)
ida-cli --path <file> list-functions [--filter NAME] [--limit 100] [--offset 0]
ida-cli --path <file> decompile --addr 0x1000
ida-cli --path <file> disasm --addr 0x1000 [--count 20]
ida-cli --path <file> disasm --name main [--count 20]
ida-cli --path <file> xrefs-to --addr 0x1000
ida-cli --path <file> list-strings [--query X] [--limit 100]
ida-cli --path <file> list-segments
服务 / 队列辅助命令:
ida-cli --path <file> prewarm [--keep-warm] [--queue]
ida-cli prewarm-many samples.txt [--jobs 4]
ida-cli --path <file> enqueue <method> [--priority 0] [--dedupe-key K] [--params '{...}']
ida-cli task-status <id>
ida-cli list-tasks
ida-cli cancel-task <id>
ida-cli status
ida-cli --path <file> close
ida-cli shutdown
其他所有操作:raw / pipe
扁平子命令涵盖了最常见的读取操作。其他操作可使用 raw 发送单个请求,或使用 pipe 批量处理标准输入。两者都接受 JSON-RPC 载荷,其中的 method 字段必须与 MCP 方法名匹配(参见
cli-tool-reference.md)。
ida-cli --path <file> raw '{"method":"get_function_by_name","params":{"name":"main"}}'
ida-cli --path <file> raw '{"method":"rename_symbol","params":{"address":"0x1000","new_name":"parse_header"}}'
ida-cli --path <file> raw '{"method":"batch_decompile","params":{"addresses":["0x1000","0x2000"]}}'
ida-cli --json --path <file> pipe <<'EOF'
{"method":"list_functions","params":{"limit":5}}
{"method":"get_xrefs_from","params":{"address":"0x1000"}}
EOF
输出模式
ida-cli --json --path <file> list-functions --limit 5 # pretty JSON
ida-cli --compact --path <file> list-functions --limit 5 # single-line JSON
文件类型
| 类型 | 行为 |
|---|---|
.i64 / .idb | 直接重新打开现有的 IDA 数据库 |
| 原始 PE / ELF / Mach-O | 分析后在输入文件旁缓存为 .i64 |
本地运行时路径
- 数据库缓存:
~/.ida/idb/ - 日志:
~/.ida/logs/server.log - 服务 Unix 套接字:
~/.ida/server.sock - PID 文件:
~/.ida/server.pid - 发现文件(将扁平 CLI 映射到套接字):
/tmp/ida-cli.socket - 大型响应缓存:
/tmp/ida-cli-out/
故障恢复
如果本地服务卡住:
ida-cli shutdown
pkill -9 -f "ida-cli"
rm -f ~/.ida/server.sock ~/.ida/server.pid ~/.ida/.startup.lock /tmp/ida-cli.socket
然后重新运行原始客户端子命令,让它重启服务。
第 2 部分:通用逆向工程方法
核心原则
- 先按 F5,再看反汇编(硬性规则)——先尝试一次反编译,再转向反汇编。
- 10 秒 F5 门槛(硬性规则)——如果反编译明显失败,或
decompile_function卡顿超过 10 秒,则视为目标目前无法反编译,并转向反汇编。 - 边分析边重命名(硬性规则)——一旦理解函数的用途,就立即重命名。不要积累
sub_XXXXX这样的名称。 - 积极迭代——F5 → 应用类型 → 重命名 → 再次按 F5 → 验证新偏移 → 重复。
- 按字面处理常量——如果 IDA 显示
0x6E,就写成110,直到有证据表明它具有更高层含义。 - 小幅差异使用反汇编——数值相差 1~10,通常意味着存在差一、饱和或位宽问题。
- 记录分析日志(硬性规则)——分析完每个函数后,记录地址、重命名结果和用途。
反编译策略
出现以下情况时,转向反汇编:
decompile_function返回错误decompile_function耗时超过 10 秒- 伪代码显然存在失真
达到门槛后,不要继续循环重试。转到下一层:
- 停止重复尝试反编译
- 基于反汇编和基本块进行分析
- 通过交叉引用和调用图还原控制流
- 根据反汇编证据重命名、添加注释并应用类型
- 只有理由明确时才修补或简化
- 排除阻碍后再尝试反编译
常见的“停止 F5 并转向反汇编”信号:
- 单个分发器块主导整个函数
- 存在大量间接分支或计算跳转
- 存在明显的扁平化状态变量
- 存在类似 VM 的解码、分发、执行循环
- 不透明谓词的结果看起来是常量
- 由异常驱动的控制流,或破坏 CFG 的控制流
专用指南:obfuscation-triage.md。
反编译器常见的错误表现:
| 症状 | 伪代码 | 实际指令模式 |
|---|---|---|
| 常量折叠 | result = x * 1718750 / 1000000 | MUL + UDIV,带有字面常量 |
隐藏的 +1/-1 | discount = bias * 110 / 64 | 除法后仍有 ADD #1 |
| 类型混淆 | int v10 = *(int *)(ctx + 0x1DC) | 实际加载指令是 LDR W8,行为上属于 u32 |
| 隐藏的饱和处理 | result = a - b | SUBS + 条件选择为零 |
命名策略
理解函数后,立即重命名。
| 前缀 | 含义 |
|---|---|
check_ / validate_ | 验证 |
parse_ / deserialize_ | 解析 / 反序列化 |
compute_ / calc_ | 计算 |
dispatch_ | 分发入口点 |
init_ / setup_ | 初始化 |
重命名被调用函数后,立即重新反编译调用方。可读性会迅速提升。
分析日志
实时记录发现。至少记录:
- 函数地址
- 旧名称 → 新名称
- 一句话说明用途
- 新恢复的结构体
- 恢复出的算术公式
- 错误代码映射
- 未解决的问题
建议格式:
## Analysis Log: <binary_name>
### Functions Reversed
| # | Address | Old Name | New Name | Purpose |
|---|---------|----------|----------|---------|
| 1 | 0x1234 | sub_1234 | parse_header | Parse the message header from the input buffer |
### Structs Identified
| Struct | Size | Key Fields | Used By |
|--------|------|-----------|---------|
| MsgHeader | 0x40 | +0x00 magic, +0x04 msg_type, +0x08 payload_len | parse_header |
### Open Questions
- sub_9ABC: likely initializes a lookup table, not yet proven
结构体恢复
根据重复出现的 *(ptr + 0xNNN) 模式恢复结构体。
常见的 ARM64 加载位宽映射:
LDR X8, [X0, #0x130] -> u64
LDR W8, [X0, #0x144] -> u32
LDRH W8, [X0, #0x168] -> u16
LDRB W8, [X0, #0x178] -> u8
建议流程:
- 反编译并收集指针 + 偏移的访问
- 在反汇编中确认位宽
- 按需读取实时值
- 声明结构体
- 应用类型
- 重新反编译,确认字段已替代原始偏移
- 使用结构体字段上的交叉引用来扩展理解
调用图导航
不要按顺序逐行阅读庞大的分发器。采用从叶节点开始的策略:
- 从入口点构建调用图
- 反编译叶函数
- 立即重命名每个叶函数
- 重新反编译调用方
- 向上重复
搜索策略
记住 x86 和 ARM64 的小端字节序:
ida-cli --path <file> raw '{"method":"search_bytes","params":{"pattern":"6E 00 00 00"}}'
ida-cli --path <file> raw '{"method":"search_text","params":{"targets":["110","10000"],"kind":"imm"}}'
ida-cli --path <file> raw '{"method":"search_pseudocode","params":{"pattern":"amount"}}'
ida-cli --path <file> raw '{"method":"search_instructions","params":{"patterns":["MUL","UDIV"]}}'
公式提取
规则:
- 按原样翻译常量
- 严格保留 IDA 显示的运算顺序
- 多步 64 位乘法链使用
u128 - 留意饱和行为
- 在反汇编中验证可疑的算术运算
差异排查:
| 差异范围 | 常见原因 | 修复方法 |
|---|---|---|
> 100 | 公式或缩放错误 | 根据常量重新构建 |
10-100 | 运算符或操作数错误 | 验证 MUL / DIV / ADD / SUB |
1-10 | 差一错误或饱和 | 逐条指令比较 |
0 | 完全匹配 | 完成 |
结构化反编译
当算术链过于复杂、无法手动比较时,使用 decompile_structured。
查找:
mul、div、add、sub节点__umulh、__multi3、__udivti3等辅助函数调用- 数值叶节点
- 变量引用
根据 AST 生成表达式,然后与反汇编交叉核对。
第 3 部分:常见工作流
工作流 1:二进制方向判断
ida-cli --path <file> raw '{"method":"get_database_info"}'
ida-cli --path <file> list-segments
ida-cli --path <file> raw '{"method":"list_exports"}'
ida-cli --path <file> raw '{"method":"list_imports"}'
ida-cli --path <file> list-functions --limit 50
ida-cli --path <file> raw '{"method":"build_callgraph","params":{"roots":["0x1000"],"max_depth":3}}'
工作流 2:结构体重建
- 反编译并收集偏移量
- 在反汇编中确认宽度
- 根据需要读取值
- 声明结构体
- 应用类型
- 重新反编译
- 跟进字段的 xref
工作流 3:算术验证
ida-cli --path <file> decompile --addr 0x1000
ida-cli --path <file> raw '{"method":"get_pseudocode_at","params":{"address":"0x1024"}}'
ida-cli --path <file> disasm --addr 0x1000 --count 200
ida-cli --path <file> raw '{"method":"search_instructions","params":{"patterns":["MUL","UDIV"]}}'
ida-cli --path <file> raw '{"method":"search_instruction_operands","params":{"patterns":["#0x6E"]}}'
工作流 3b:F5 失败后的混淆排查
如果反编译立即失败或超过 10 秒的门限:
- 停止重试反编译
- 使用
disasm --addr 0x... --count N获取完整函数体 - 根据基本块、xref 和调用图梳理控制流
- 标记分发器分支、不透明谓词和扁平化状态变量
- 直接根据反汇编重命名符号并注释其意图
- 仅在取得实质进展后重试反编译
工作流 3c:强混淆信号
出现以下任一情况时,立即切换到以反汇编为先的模式:
- 一个中央代码块根据状态变量进行分发
- 大多数边都返回到同一个控制器代码块
- 分支目标通过间接方式计算
- 函数看起来像字节码解释器或处理器 VM
- 分支依赖于无法在伪代码中简化的不透明算术运算
- 异常流或反分析逻辑导致反编译器不稳定
专用参考页面:obfuscation-triage.md。
工作流 3d:商业 VM 保护(Themida / VMProtect / Code Virtualizer / WinLicense)
如果目标是 Windows x86-64 PE,且符合以下任一情况,则目标使用的是商业 VM 保护器,而非普通混淆:
- 函数体只有一条
jmp/push+ret/call指令,并跳转到名为.themida、.vlizer、.vmp0/vmp1/vmp2、.winlice、.pelock、.svmp、.xxx或其他非标准 RX 节的节 - IAT 已被移除,API 通过
.rdata中隐蔽的指针表解析 - 伪代码退化为成千上万个经分发执行的处理器
- IDA 发生段错误、停滞,或显示类似字节码的解码循环
在这种情况下,不要尝试逆向处理器。运行随附的基于仿真的去虚拟化工具,在 IDA 中打开修补后的 PE,然后正常反编译:
pip install -r scripts/vm_devirt_requirements.txt
python3 scripts/vm_devirt.py protected.bin --auto -o protected-devirt.bin
ida-cli --path protected-devirt.bin list-functions --limit 20
ida-cli --path protected-devirt.bin decompile --addr 0x140001000
完整方法、能力矩阵和去虚拟化后的 IDA 工作流见 vm-devirt.md。
工作流 4:错误代码映射
- 搜索立即数
- 找到其所在函数
- 检查伪代码上下文
- 添加注释
- 搜索类似的返回位置
工作流 5:表和分发分析
- 搜索
factory或registry等字符串 - 跟进 xref
- 找出表的构建函数
- 扫描该表
- 解析并反编译每个函数指针
工作流 6:多数据库分析
- 打开多个数据库(每个请求使用一个
--path;服务会自动为每个数据库启动一个工作线程) - 在并发 Agent 之间共享
open_idb返回的句柄 - 并行执行读取密集型工作
- 串行执行写入密集型工作
- 使用
close_idb正常关闭(HTTP/SSE 需要提供open_idb返回的close_token)
工作流 7:批量注释
需要时通过 raw 分发:
batch_renameset_function_prototypeset_function_commentrename_stack_variableset_stack_variable_typecreate_enumbatch_decompile
工作流 8:动态调试
dbg_* 方法系列涵盖调试器加载、进程启动/附加、断点、单步执行、寄存器检查、内存读写和线程检查。只有在支持调试器的运行时环境中才能使用;无头 idat-compat 路径不支持。
启用 ASLR 时,基于地址的调试操作必须使用重定位后的运行时地址,除非该方法明确接受 IDB 地址。
第 4 部分:错误恢复
反编译失败
- 如果出现明确的失败,或反编译器卡住超过 10 秒,则将该函数归类为强混淆
- 停止反复尝试 F5
- 仅对范围较小且已有希望的代码段使用
get_pseudocode_at - 转而进行反汇编、基本块、交叉引用和调用图分析
- 仅在函数已被部分理清后重试反编译
自动分析未完成
如果 get_analysis_status 报告 auto_is_ok=false:
- 运行
run_auto_analysis - 或轮询直至分析完成
分析完成前,不要相信交叉引用或反编译质量。
超时处理
run_script默认超时为 120 秒,最长可设为 600 秒- 应将非常大的
batch_decompile调用拆分成更小的批次 - CLI 的
--timeout标志控制客户端每个请求的超时时间
常见错误
- 从最大的入口点着手,而不是从叶子函数开始
- 重命名被调用函数后,却没有重新反编译调用方
- 相信算术结果,却不检查反汇编
- 搜索时忘记字节序为小端序
- 忽略交叉引用扇出数量
- 相信有符号伪代码类型,却不检查加载宽度
- 重新打开原始二进制文件,而不是缓存的
.i64 - 自动分析完成前就发起查询
第 5 部分:参考资料
仅加载与当前任务匹配的参考资料。默认不要全部阅读。
| 参考资料 | 使用时机 |
|---|---|
| cli-tool-reference.md | CLI 命令模式和能力查询 |
| obfuscation-triage.md | F5 失败、控制流扁平化、VM 处理程序、不透明谓词、优先反汇编的工作 |
| vm-devirt.md | 商业 VM 保护器(Themida / VMProtect / Code Virtualizer / WinLicense)——使用 scripts/vm_devirt.py 进行基于仿真的去虚拟化 |
| counterfactual-patch.md | 反事实补丁工作流 |
| headless-api.md | 无头 IDA 执行和 API 选择 |
| idapython-cheatsheet.md | 编写 IDAPython 脚本 |
| ida-domain-api.md | 完整的 IDA Domain API 参考 |
| idalib-headless.md | idalib / idapro 无头用法 |
| binary-analysis-patterns.md | 恶意软件、漏洞研究、固件分析模式 |
| plugin-development.md | IDA 插件开发 |