mcpField
I
ida-cli

ida-cli

github.com/cpkt9762安全3144 次安装3 天前更新
代码仓库

关于 ida-cli

面向逆向工程人员的 ida-cli 技能,说明如何启动本地服务并通过命令行分析 IDA 数据库或二进制文件。内容还包括反编译、反汇编、结构恢复和分析记录方法。

主要功能

  1. 01自动安装与运行时探测
  2. 02查询函数、字符串和交叉引用
  3. 03反编译与反汇编分析
  4. 04通过 JSON-RPC 执行请求
  5. 05提供逆向分析工作流程

适用场景

  1. 01检查二进制文件的函数与段
  2. 02追踪函数调用和交叉引用
  3. 03从代码访问中恢复结构体
  4. 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.md
cli-tool-reference.md
counterfactual-patch.md
headless-api.md
ida-domain-api.md
idalib-headless.md
idapython-cheatsheet.md
obfuscation-triage.md
plugin-development.md
vm-devirt.md
scripts/
ida-cli.sh
vm_devirt_requirements.txt
vm_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-cli
    • IDA_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 有两种模式:

  1. 扁平客户端 — 此技能使用的模式。每次调用发送一个请求。
  2. 服务 — 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 秒
  • 伪代码显然存在失真

达到门槛后,不要继续循环重试。转到下一层:

  1. 停止重复尝试反编译
  2. 基于反汇编和基本块进行分析
  3. 通过交叉引用和调用图还原控制流
  4. 根据反汇编证据重命名、添加注释并应用类型
  5. 只有理由明确时才修补或简化
  6. 排除阻碍后再尝试反编译

常见的“停止 F5 并转向反汇编”信号:

  • 单个分发器块主导整个函数
  • 存在大量间接分支或计算跳转
  • 存在明显的扁平化状态变量
  • 存在类似 VM 的解码、分发、执行循环
  • 不透明谓词的结果看起来是常量
  • 由异常驱动的控制流,或破坏 CFG 的控制流

专用指南:obfuscation-triage.md。

反编译器常见的错误表现:

症状伪代码实际指令模式
常量折叠result = x * 1718750 / 1000000MUL + UDIV,带有字面常量
隐藏的 +1/-1discount = bias * 110 / 64除法后仍有 ADD #1
类型混淆int v10 = *(int *)(ctx + 0x1DC)实际加载指令是 LDR W8,行为上属于 u32
隐藏的饱和处理result = a - bSUBS + 条件选择为零
命名策略

理解函数后,立即重命名。

前缀含义
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

建议流程:

  1. 反编译并收集指针 + 偏移的访问
  2. 在反汇编中确认位宽
  3. 按需读取实时值
  4. 声明结构体
  5. 应用类型
  6. 重新反编译,确认字段已替代原始偏移
  7. 使用结构体字段上的交叉引用来扩展理解
调用图导航

不要按顺序逐行阅读庞大的分发器。采用从叶节点开始的策略:

  1. 从入口点构建调用图
  2. 反编译叶函数
  3. 立即重命名每个叶函数
  4. 重新反编译调用方
  5. 向上重复
搜索策略

记住 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"]}}'
公式提取

规则:

  1. 按原样翻译常量
  2. 严格保留 IDA 显示的运算顺序
  3. 多步 64 位乘法链使用 u128
  4. 留意饱和行为
  5. 在反汇编中验证可疑的算术运算

差异排查:

差异范围常见原因修复方法
> 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:结构体重建
  1. 反编译并收集偏移量
  2. 在反汇编中确认宽度
  3. 根据需要读取值
  4. 声明结构体
  5. 应用类型
  6. 重新反编译
  7. 跟进字段的 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 秒的门限:

  1. 停止重试反编译
  2. 使用 disasm --addr 0x... --count N 获取完整函数体
  3. 根据基本块、xref 和调用图梳理控制流
  4. 标记分发器分支、不透明谓词和扁平化状态变量
  5. 直接根据反汇编重命名符号并注释其意图
  6. 仅在取得实质进展后重试反编译
工作流 3c:强混淆信号

出现以下任一情况时,立即切换到以反汇编为先的模式:

  1. 一个中央代码块根据状态变量进行分发
  2. 大多数边都返回到同一个控制器代码块
  3. 分支目标通过间接方式计算
  4. 函数看起来像字节码解释器或处理器 VM
  5. 分支依赖于无法在伪代码中简化的不透明算术运算
  6. 异常流或反分析逻辑导致反编译器不稳定

专用参考页面:obfuscation-triage.md。

工作流 3d:商业 VM 保护(Themida / VMProtect / Code Virtualizer / WinLicense)

如果目标是 Windows x86-64 PE,且符合以下任一情况,则目标使用的是商业 VM 保护器,而非普通混淆:

  1. 函数体只有一条 jmp / push+ret / call 指令,并跳转到名为 .themida、.vlizer、.vmp0/vmp1/vmp2、.winlice、.pelock、.svmp、.xxx 或其他非标准 RX 节的节
  2. IAT 已被移除,API 通过 .rdata 中隐蔽的指针表解析
  3. 伪代码退化为成千上万个经分发执行的处理器
  4. 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:错误代码映射
  1. 搜索立即数
  2. 找到其所在函数
  3. 检查伪代码上下文
  4. 添加注释
  5. 搜索类似的返回位置
工作流 5:表和分发分析
  1. 搜索 factory 或 registry 等字符串
  2. 跟进 xref
  3. 找出表的构建函数
  4. 扫描该表
  5. 解析并反编译每个函数指针
工作流 6:多数据库分析
  1. 打开多个数据库(每个请求使用一个 --path;服务会自动为每个数据库启动一个工作线程)
  2. 在并发 Agent 之间共享 open_idb 返回的句柄
  3. 并行执行读取密集型工作
  4. 串行执行写入密集型工作
  5. 使用 close_idb 正常关闭(HTTP/SSE 需要提供 open_idb 返回的 close_token)
工作流 7:批量注释

需要时通过 raw 分发:

  • batch_rename
  • set_function_prototype
  • set_function_comment
  • rename_stack_variable
  • set_stack_variable_type
  • create_enum
  • batch_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 标志控制客户端每个请求的超时时间
常见错误
  1. 从最大的入口点着手,而不是从叶子函数开始
  2. 重命名被调用函数后,却没有重新反编译调用方
  3. 相信算术结果,却不检查反汇编
  4. 搜索时忘记字节序为小端序
  5. 忽略交叉引用扇出数量
  6. 相信有符号伪代码类型,却不检查加载宽度
  7. 重新打开原始二进制文件,而不是缓存的 .i64
  8. 自动分析完成前就发起查询

第 5 部分:参考资料

仅加载与当前任务匹配的参考资料。默认不要全部阅读。

参考资料使用时机
cli-tool-reference.mdCLI 命令模式和能力查询
obfuscation-triage.mdF5 失败、控制流扁平化、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.mdidalib / idapro 无头用法
binary-analysis-patterns.md恶意软件、漏洞研究、固件分析模式
plugin-development.mdIDA 插件开发

评论

支持 Markdown