内容
[阅读中文版](README.zh.md)
# Diaphora MCP
**Diaphora MCP** 是一个用于自动化二进制差异分析的 MCP(模型上下文协议)服务器。它通过 MCP 协议连接 [Diaphora](https://github.com/joxeankoret/diaphora)(差异引擎)和 IDA Pro(反编译器),允许 AI 代理(如 Claude Code)执行二进制文件比较、查找安全补丁和分析一系列变化。
## 功能特点
- **导出**: 将分析后的 `.i64` / `.idb` 数据库转换为 Diaphora SQLite 格式(通过 `idat.exe` 无头模式)
- **差异分析**: 比较两个导出的数据库,按匹配类型和比率筛选结果
- **漏洞分析**: 使用关键词匹配和启发式方法搜索与安全相关的变化
- **补丁检测**: 自动检测新的边界检查、空指针检查、错误处理和加密变化
- **排名**: 根据 CFG、复杂度跳跃和安全指标按重要性对变化的函数进行排名
- **调用图**: 比较调用路径(BFS,最大 N 级),并检测调用级联中的根本原因变化
- **元数据传输**: 准备在数据库之间传输的名称、注释和原型
- **IDA Pro MCP 集成**: 所有工具返回的地址和数据库路径均可直接传递给 IDA Pro MCP 工具
## 安装
### 1. 依赖项
- Python 3.10+
- [IDA Pro](https://hex-rays.com/IDA-pro/) 8.x / 9.x(用于通过 `idat.exe` 无头导出)
- [Diaphora](https://github.com/joxeankoret/diaphora) 插件已安装在 IDA 中
- [Claude Code](https://claude.ai/code)(或任何其他符合 MCP 协议的客户端)
### 2. 软件包安装
```bash
git clone https://github.com/xTeardx/diaphora-mcp.git
cd diaphora-mcp
pip install -e .
```
### 3. 路径配置
软件包尝试在标准安装位置**自动查找** IDA Pro 和 Diaphora。如果未找到,可以设置以下环境变量:
| 变量名 | 描述 | 示例 |
|-----------|-------------|---------|
| `IDAT_PATH` | idat.exe 的完整路径 | `C:\Program Files\IDA Pro 9.3\idat.exe` |
| `DIAPHORA_DIR` | 包含 diaphora.py 的文件夹 | `C:\Program Files\IDA Pro 9.3\plugins\diaphora-3.4.1` |
| `DIAPHORA_PYTHON` | 用于差异计算的 Python 解释器 | `/usr/bin/python3`(默认为 sys.executable) |
对于 Claude Code,可以在 `~/.claude.json`(或 MCP 客户端的相应配置文件)中指定它们:
```json
{
"mcpServers": {
"diaphora": {
"command": "python",
"args": ["path/to/repo/diaphora_mcp_server.py"],
"env": {
"IDAT_PATH": "C:\\Program Files\\IDA Pro 9.3\\idat.exe",
"DIAPHORA_DIR": "C:\\Program Files\\IDA Pro 9.3\\plugins\\diaphora-3.4.1"
},
"timeout": 7200
}
}
}
```
> **注意:** 对于非常大的二进制文件(>100 MB),请确保 `timeout` 至少为 **7200**(2 小时)。
### 4. 准备用于差异分析的数据库
IDA Pro 必须首先分析二进制文件(创建 `.i64` 或 `.idb` 文件)。之后:
```
┃ export_idb_to_diaphora(idb_path="old_version.i64")
┃ export_idb_to_diaphora(idb_path="new_version.i64")
```
或在一条命令中运行整个流程:
```
┃ batch_export_and_diff(idb1="old.i64", idb2="new.i64")
```
## 快速入门
```
┃ # 1. 完整流程:导出两个 .i64 → 差异分析 → 摘要报告
┃ batch_export_and_diff(idb1="v1.0.i64", idb2="v1.1.i64")
┃ # 2. 如果数据库已经导出
┃ diff_diaphora_dbs(db1="v1.0.sqlite", db2="v1.1.sqlite")
┃ # 3. 安全分析差异结果
┃ analyze_diff_results(results_path="v1.0_vs_v1.1.diaphora")
┃ # 4. 变化重要性排名
┃ rank_changes(results_path="v1.0_vs_v1.1.diaphora", top_n=20)
┃ # 5. 查找根本原因变化
┃ find_patch_root(results_path="v1.0_vs_v1.1.diaphora")
┃ # 6. 检测可能的安全补丁
┃ detect_security_patches(results_path="v1.0_vs_v1.1.diaphora")
┃ # 7. 生成完整报告
┃ summarize_patch(results_path="v1.0_vs_v1.1.diaphora")
```
## 示例(实时会话记录)
参见 **[examples/basic-session.md](examples/basic-session.md)** 以获取完整的 Diaphora MCP 会话逐步记录示例,从导出两个 IDB 数据库到比较各个函数。也可以在 [Russian](examples/basic-session.ru.md) 中查看。
以下是服务器返回内容的预览:
**输入 — 比较两个 SQLite3 DLL(2015 vs 2023):**
```json
{"idb1_path": "old.i64", "idb2_path": "new.i64", "use_decompiler": false}
```
**输出 — 导出 + 差异分析后的摘要:**
```json
{
"best_matches": 60,
"partial_matches": 993,
"multimatches": 52,
"unmatched_primary": 2647
}
```
会话记录了 6 次 MCP 工具调用,展示了每一步的精确 JSON 输入/输出,以及代理的推理。
### 调查单个数据库
```
┃ # 获取数据库导出信息
┃ get_export_info(db_path="app.sqlite")
┃ # 搜索函数
┃ search_export_db(db_path="app.sqlite", name_pattern="%crypt%", min_instructions=50)
┃ # 获取伪代码
┃ get_function_pseudocode(db_path="app.sqlite", address="401000")
```
## 项目结构
```
diaphora-mcp/
├── diaphora_mcp_server.py # 主入口
├── diaphora_mcp/
│ ├── diaphora_mcp_server.py # MCP 工具注册
│ ├── config.py # 路径配置和自动检测
│ ├── models.py # 常量和模型
│ ├── core/
│ │ ├── export.py # 无头导出,批量处理
│ │ ├── diff.py # 差异分析和 .diaphora 结果读取
│ │ ├── analysis.py # 函数搜索、比较、解释
│ │ ├── security.py # 关键词匹配、补丁检测
│ │ ├── ranking.py # 重要性排名
│ │ ├── graph.py # 调用图、BFS 调用树、根本原因
│ │ ├── metadata.py # 元数据准备(名称、注释)
│ │ └── report.py # 整体补丁报告生成
│ └── utils/
│ ├── sqlite.py # SQLite 助手
│ ├── format.py # 伪代码差异、特征向量提取
│ └── log.py # 导出日志实用工具
├── _diaphora_headless.py # idat.exe -S 封装
└── logs/ # 自动导出日志(动态创建)
```
## MCP 工具参考(20 个工具)
### 导出
| 工具 | 描述 |
|------|-------------|
| `export_idb_to_diaphora` | 使用 IDA 无头模式将 `.i64`/`.idb` 数据库导出到 SQLite 格式 |
| `batch_export_and_diff` | 完整流程:导出主要 → 导出次要 → 差异分析 → 摘要 |
### 差异分析
| 工具 | 描述 |
|------|-------------|
| `diff_diaphora_dbs` | 差异分析两个导出的 Diaphora SQLite 数据库 |
| `get_diff_results` | 读取 `.diaphora` 差异文件并过滤 |
| `get_diff_summary` | 返回匹配统计信息 |
### 分析
| 工具 | 描述 |
|------|-------------|
| `analyze_diff_results` | 使用安全关键词和过滤器筛选结果 |
| `compare_functions` | 两个数据库中函数的并排比较 |
| `find_function_match` | 匹配第二个二进制文件中的函数并提供置信度指标 |
| `explain_similarity` | 分解相似性因素(助记符、CFG、常量、原型、哈希) |
| `detect_behavior_change` | 提供函数逻辑变化的自然语言摘要 |
| `summarize_patch` | 生成全面更新报告 |
| `search_export_db` | 按名称/指令/复杂度查询导出的函数 |
| `get_function_pseudocode` | 获取函数的伪代码和元数据 |
| `get_export_info` | 检索常规数据库元数据 |
### 安全
| 工具 | 描述 |
|------|-------------|
| `detect_security_patches` | 检测可能的 安全修复(边界检查、内存安全、防调试等) |
### 排名
| 工具 | 描述 |
|------|-------------|
| `rank_changes` | 按重要性对变化的函数进行排名(0-100 分) |
### 调用图
| 工具 | 描述 |
|------|-------------|
| `get_changed_callgraph` | 比较函数的调用者和被调用者 |
| `compare_call_path` | 从函数遍历调用图(BFS 调用路径比较,最大 N 级) |
| `find_patch_root` | 检测导致调用级联的根本原因函数 |
### 元数据
| 工具 | 描述 |
|------|-------------|
| `transfer_metadata` | 准备批量传输的名称、注释和原型 |
## IDA Pro GUI 集成(XML-RPC 桥接)
该项目包含与正在运行的 GUI IDA Pro 会话的内置集成,使得可以直接从活动 IDA 窗口导出数据,而不会发生数据库锁定冲突。
1. **自动启动**:将 [diaphora_gui_listener.py](diaphora_gui_listener.py) 复制到 IDA Pro 的 `plugins/` 目录中。它将在 IDA 启动时启动一个后台 XML-RPC 服务器,监听端口 `28652`。
2. **智能导出**:调用 `export_idb_to_diaphora` 时,MCP 服务器会检查端口 `28652`。如果活动会话存在,它将直接在 GUI 中运行导出。否则,它将自动回退到通过 `idat.exe` 的无头后台执行。
有关配置桥的详细说明,请参见 [GUI_INSTRUCTIONS.md](GUI_INSTRUCTIONS.md)。
## 处理巨大的数据库(10 万+ 函数)
处理极大型项目时,Diaphora MCP 会应用特定的优化:
- **递归限制**:Python 递归限制会自动提高到 `100000`(`sys.setrecursionlimit`),以防止在大型调用图遍历过程中崩溃。
- **SQLite 事务优化**:在您的 `diaphora_config.py` 中,设置 `COMMIT_AFTER_EACH_GUI_UPDATE = False` 可以减少磁盘写入,加速 GUI 导出 2 倍至 3 倍。
- **Hex-Rays 微代码**:禁用微代码导出(Diaphora 配置中的 `EXPORTING_USE_MICROCODE = False`),在不严格需要反编译器的情况下,可以加快导出速度。
## IDA Pro MCP 集成
像 `analyze_diff_results`、`compare_functions` 和 `find_function_match` 这样的工具会返回一个包含地址和路径的 `ida_pro_mcp` 块。这些信息可以直接传递给 `ida-pro-mcp` 工具:
```
┃ # 1. Diaphora 发现一个可疑函数
┃ analyze_diff_results(results_path="diff.diaphora")
┃ → addr1="401000", db1="old.sqlite"
┃ # 2. IDA Pro MCP 反编译它
┃ decompile_function(address="401000")
```
## 示例
要查看 Diaphora MCP 的实际操作,请查看以下示例:
- [基本会话记录](examples/basic-session.md):一个真实的 MCP 会话逐步记录,包含每次工具调用的精确 JSON 输入/输出 — 从导出到函数比较。也可以在 [Russian](examples/basic-session.ru.md) 中查看。
## AI 代理指南(重要)
如果您是使用此协议的 AI 编程助手(如 Claude Code),请记住以下兼容性规则:
1. **GUI 与无头导出模式**:
- 通过活动 GUI 会话(`ida_mcp.py` 插件)导出会生成一个自定义模式,其中包含 `calls`、`strings`、`structures` 等表格,但 **没有 `program` 表格**。
- 无头导出(通过 `idat.exe`)生成官方 Diaphora 模式,其中包含 `program` 表格。
- **关键**:差异引擎(`diff_diaphora_dbs`)需要官方模式。**如果您打算比较/差异数据库,请始终无头导出**。
2. **GUI 中锁定数据库**:
- 当前在 GUI IDA Pro 中打开的数据库被锁定。尝试无头导出它将失败。
- 如果您需要差异分析当前打开的数据库,请让用户在 GUI 中关闭它(或打开一个虚拟数据库)以释放文件锁,然后触发无头导出。
3. **避免数据库名称冲突**:
- Diaphora 导出数据库默认为 `<basename>.diaphora.sqlite`。
- 永远不要为 Diaphora 导出使用 `<basename>.sqlite`,因为这会与 `ida-pro-mcp` 监管器创建的内部缓存数据库发生冲突。
## 许可证
MIT