从你的 AI 助手中比较两个经 IDA 分析的二进制文件。Diaphora MCP 导出已保存的 IDA 数据库,运行 Diaphora,并让 AI 检查对应的函数及其调用图。
默认接口包含 10 个工具,专注于比较。Diaphora 提供匹配结果;AI 阅读实际代码并解释变更。
old.i64 + new.i64 → headless export → SQLite exports + diff results
↓
summary → matched code → call graph
idat.exe/idat64 的 IDA Pro,以及已安装的 Diaphora 插件。.i64/.idb 数据库。IDA 和 Diaphora 需单独安装。Diff 模式验证目前针对 Diaphora 3.4.1;其他模式可能需要兼容性更新。用于 diff 的 Python 解释器必须安装 Diaphora 的独立依赖项。
git clone https://github.com/xTeardx/diaphora-mcp.git
cd diaphora-mcp
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e .
New-Item -ItemType Directory -Force C:\diaphora-outputs | Out-Null
将以下条目添加到你的客户端的 MCP 配置中。将仓库、IDA 和 Diaphora 路径替换为你的安装路径。使用你安装此项目所在环境的 Python 可执行文件。
{
"mcpServers": {
"diaphora": {
"command": "C:/src/diaphora-mcp/.venv/Scripts/python.exe",
"args": ["C:/src/diaphora-mcp/diaphora_mcp_server.py"],
"env": {
"IDAT_PATH": "C:/Program Files/IDA Professional 9.3/idat.exe",
"DIAPHORA_DIR": "C:/Program Files/IDA Professional 9.3/plugins/diaphora",
"DIAPHORA_OUTPUT_ROOT": "C:/diaphora-outputs"
}
}
}
}
客户端通过 stdio 启动服务器;无需启动单独的 Web 服务。更改其代码或环境后,请重启 MCP 服务器。成功连接后,将暴露下面列出的 10 个工具。
Use Diaphora to compare C:/analysis/old.i64 (old) against
C:/analysis/new.i64 (new). Save output under C:/diaphora-outputs/run-001.
Export headlessly with assembly detail, keep the exports, show a summary,
then inspect partial matches and explain the code changes in the interesting
functions. Use the result mapping when comparing functions and call graphs.
每次选择一个全新的运行目录。现有的生成目标绝不会被覆盖。
以下 JSON 块是 MCP 工具参数,而非 shell 命令。你的助手可以直接调用指定的工具。路径和 0x401000 是示例;请使用你自己运行返回的路径和地址。
工具:batch_export_and_diff。旧文件始终是第一个输入,新文件是第二个。
{
"idb1_path": "C:/analysis/old.i64",
"idb2_path": "C:/analysis/new.i64",
"output_dir": "C:/diaphora-outputs/run-001",
"export_mode": "headless",
"use_decompiler": false,
"summaries_only": false,
"cleanup": false,
"limit": 100,
"unmatched_limit": 50
}
这样可以在不需要 Hex-Rays 的情况下保留汇编细节。选择你需要的导出配置:
| 细节 | use_decompiler | summaries_only | 用途 |
|---|---|---|---|
| 匹配摘要 | false | true | 快速首轮;无详细代码 |
| 汇编 | false | false | 在没有反编译器的情况下比较反汇编 |
| 汇编 + 伪代码 | true | false | 使用兼容的 Hex-Rays 反编译器进行代码审查;较慢 |
始终从响应中获取输出路径:
OLD_SQLITE = steps.export1.output
NEW_SQLITE = steps.export2.output
RESULTS = steps.diff.output
对于此示例,生成的文件是 run-001 下的 old.diaphora.sqlite、new.diaphora.sqlite 和 old_vs_new.diaphora。相同的输入基名会产生不同的 old_/new_ 导出名称。保留 cleanup=false 以便后续检查函数。
工具:get_diff_summary。
{
"results_path": "C:/diaphora-outputs/run-001/old_vs_new.diaphora"
}
工具:get_diff_results。此页从较低比率的局部匹配开始。
{
"results_path": "C:/diaphora-outputs/run-001/old_vs_new.diaphora",
"match_type": "partial",
"min_ratio": 0.0,
"limit": 50,
"offset": 0,
"unmatched_limit": 50,
"unmatched_offset": 0,
"sort_by": "ratio",
"sort_order": "asc"
}
partial 选择的是 Diaphora 匹配类别,并不保证行为发生变化。使用 match_type="all" 获取所有支持的类别。响应包含类别计数、过滤后的总数、匹配项、未匹配行、next_offset 和 next_unmatched_offset。
要继续,请将返回的 next offsets 复制到下一次调用中,保持相同的过滤器和排序。例如,如果它们是 50 和 50,则使用 offset=50 和 unmatched_offset=50。null 的 next offset 表示该列表已结束;停止推进它。两个列表独立推进。页大小必须为正数,且上限为 5000。使用 sort_order="desc" 优先检查最强的匹配项。
工具:compare_functions。
{
"db1_path": "C:/diaphora-outputs/run-001/old.diaphora.sqlite",
"db2_path": "C:/diaphora-outputs/run-001/new.diaphora.sqlite",
"address": "0x401000",
"match_results_path": "C:/diaphora-outputs/run-001/old_vs_new.diaphora"
}
响应包含 function_old、function_new、可用的汇编/伪代码、测量到的差异以及身份证据。你可以使用 name 代替 address。如果同时提供两个选择器,地址优先;按名称选择时请省略它。
工具:get_changed_callgraph 接受上述相同的参数。它在报告更改之前会转换对应的调用者/被调用者地址,并将未解析的邻居与已确认的边差异分开。
优先使用 0x 前缀地址,以明确表示十六进制输入。在可用时提供 match_results_path:它处理重定位和重命名函数。仅地址相等并不能确立身份。模糊或缺失的匹配保持未解析状态,而不会被判定为删除。如果你已手动验证了一对,可以显式提供 address2 或 name2。
工具:search_export_db。name_pattern 使用 SQL LIKE:% 匹配任意序列。
{
"db_path": "C:/diaphora-outputs/run-001/old.diaphora.sqlite",
"name_pattern": "%parse%",
"min_instructions": 20,
"limit": 20
}
工具:get_function_pseudocode 尽管名称如此,但会返回可用的伪代码和汇编。
{
"db_path": "C:/diaphora-outputs/run-001/old.diaphora.sqlite",
"address": "0x401000"
}
如果伪代码为空,请使用兼容的反编译器,以 use_decompiler=true 和 summaries_only=false 重新导出到新的运行目录。使用 get_export_info 和 db_path 检查导出元数据。
工具:diff_diaphora_dbs。这会跳过 IDA 导出,并比较现有的官方 SQLite 导出。
{
"db1_path": "C:/diaphora-outputs/run-001/old.diaphora.sqlite",
"db2_path": "C:/diaphora-outputs/run-001/new.diaphora.sqlite",
"output_path": "C:/diaphora-outputs/another-diff.diaphora"
}
对于单个新导出,请使用 export_idb_to_diaphora,并提供 idb_path、新的 output_path 和 export_mode="headless"。
| 工具 | 用途 |
|---|---|
export_idb_to_diaphora | 导出一个已保存的 IDA 数据库 |
batch_export_and_diff | 导出两个数据库并比较它们 |
diff_diaphora_dbs | 比较现有导出 |
get_diff_summary | 匹配统计和有界示例 |
get_diff_results | 过滤、排序、分页的结果 |
get_export_info | 导出元数据和计数 |
search_export_db | 搜索函数 |
get_function_pseudocode | 读取汇编/伪代码 |
compare_functions | 比较已解析的旧/新配对 |
get_changed_callgraph | 比较映射的调用者/被调用者 |
确切的签名可通过 MCP tools/list 发现。参见工具参考。
| 模式 | 行为 |
|---|---|
headless | 无头启动 IDA 并验证 diff 模式;推荐用于比较 |
auto | 尝试活动的 GUI 桥接,然后回退到无头模式 |
gui | 要求正确的已打开 GUI 会话;无无头回退 |
batch_export_and_diff 需要 headless。
| 环境变量 | 含义 |
|---|---|
IDAT_PATH | IDA 无头可执行文件的绝对路径 |
DIAPHORA_DIR | 包含 Diaphora 脚本的目录 |
DIAPHORA_OUTPUT_ROOT | 新导出和 diff 结果的现有允许根目录 |
DIAPHORA_PYTHON | 可选的 diff 解释器;默认为 MCP 服务器的解释器 |
DIAPHORA_ENABLE_LEGACY_TOOLS | 恰好为 1 时启用之前的 21 工具接口 |
旧版匹配、特征评分、安全分类、报告、元数据和诊断仍为可选启用。要启用它们,请将以下条目添加到配置的 env 对象中并重启:
{
"DIAPHORA_ENABLE_LEGACY_TOOLS": "1"
}
这些工具使用启发式方法;它们的评分不能证明语义等价、安全修复或因果关系。配置 · GUI 设置。
| 症状 | 操作 |
|---|---|
| 目标已存在 | 使用新的运行目录或输出文件名 |
| 输出在允许根目录之外 | 选择 DIAPHORA_OUTPUT_ROOT 下的目标;先创建根目录 |
| 将 IDA 数据库传递给结果工具 | 根据情况使用返回的 .diaphora.sqlite 导出或 .diaphora 结果 |
| 缺失/模糊的对应项 | 检查旧/新顺序和映射;手动检查候选 |
| 汇编/伪代码为空 | 检查导出配置;获取新的详细导出 |
| 导出/diff 耗时很长 | 增加 MCP 客户端超时;检查本地 logs/;考虑先进行仅摘要的首轮 |
| IDB 被 IDA 会话锁定 | 关闭会话,或对单个导出使用匹配的 GUI 导出模式 |
| 不支持的模式 | 使用受支持的 Diaphora 版本重新导出;查看报告的缺失表/列 |
匹配仍然是启发式的;高比率是证据,而非证明。未匹配的函数不是已确认的新增/删除。将二进制文件、IDB、导出和日志排除在 Git 之外。参见工作流、限制和安全。
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
.\.venv\Scripts\python.exe -m pytest -q
.\.venv\Scripts\python.exe -m compileall -q .
git diff --check