
Servidor MCP para diffing binário automatizado.
[Versão em russo](https://github.com/xteardx/diaphora-mcp/blob/master/README.ru.md)
# Diaphora MCP
Compare dois binários analisados pelo IDA a partir do seu assistente de IA. O Diaphora MCP exporta os bancos de dados do IDA salvos, executa o [Diaphora](https://github.com/joxeankoret/diaphora) e permite que a IA inspecione funções correspondentes e seus grafos de chamadas.
A interface padrão possui **10 ferramentas** focadas na comparação. O Diaphora fornece as correspondências; a IA lê o código real e explica as mudanças.
[Início rápido](#quick-start) · [Exemplos](#examples) · [Ferramentas](#tools) · [Solução de problemas](#troubleshooting)
```text
old.i64 + new.i64 → exportação headless → exportações SQLite + resultados de diff
↓
resumo → código correspondente → grafo de chamadas
```
## Requisitos
- Python 3.10+, IDA Pro com `idat.exe`/`idat64` e um plugin Diaphora instalado.
- Ambos os binários analisados e salvos como bancos de dados `.i64`/`.idb`.
- Um cliente MCP local, como Codex, Claude Code ou Cursor.
- Um descompilador Hex-Rays compatível apenas se você quiser pseudocódigo.
O IDA e o Diaphora são instalados separadamente. A validação do esquema de diff atualmente tem como alvo o Diaphora **3.4.1**; outros esquemas podem precisar de atualizações de compatibilidade. O interpretador Python usado para o diff deve ter as dependências standalone do Diaphora instaladas.
## Início rápido
### 1. Instale e crie um diretório de saída
```powershell
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
```
### 2. Conecte o servidor MCP
Adicione esta entrada à configuração MCP do seu cliente. Substitua os caminhos do repositório, do IDA e do Diaphora pelos caminhos da sua instalação. Use o executável Python do ambiente onde você instalou este projeto.
```json
{
"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"
}
}
}
}
```
O cliente inicia o servidor via stdio; não há um serviço web separado para iniciar. Reinicie o servidor MCP após alterar seu código ou ambiente. Uma conexão bem-sucedida expõe as 10 ferramentas listadas abaixo.
### 3. Peça ao seu assistente para comparar os arquivos
```text
Use o Diaphora para comparar C:/analysis/old.i64 (antigo) com
C:/analysis/new.i64 (novo). Salve a saída em C:/diaphora-outputs/run-001.
Exporte em modo headless com detalhes de assembly, mantenha as exportações, mostre um resumo,
depois inspecione correspondências parciais e explique as mudanças de código nas funções
interessantes. Use o mapeamento de resultados ao comparar funções e grafos de chamadas.
```
Escolha um **diretório de execução novo** a cada vez. Alvos gerados existentes nunca são sobrescritos.
## Exemplos
Os blocos JSON a seguir são **argumentos de ferramentas MCP**, não comandos de shell. Seu assistente pode chamar as ferramentas nomeadas diretamente. Os caminhos e `0x401000` são exemplos; use os caminhos e endereços retornados pela sua própria execução.
### 1. Exporte e compare dois bancos de dados do IDA
Ferramenta: **`batch_export_and_diff`**. O antigo é sempre a primeira entrada, o novo a segunda.
```json
{
"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
}
```
Isso mantém os detalhes de assembly sem exigir o Hex-Rays. Selecione o perfil de exportação que você precisa:
| Detalhe | `use_decompiler` | `summaries_only` | Uso |
| --- | --- | --- | --- |
| Resumos de correspondência | `false` | `true` | Primeira passagem rápida; sem código detalhado |
| Assembly | `false` | `false` | Comparar desmontagem sem um descompilador |
| Assembly + pseudocódigo | `true` | `false` | Revisão de código com um descompilador Hex-Rays compatível; mais lento |
Sempre obtenha os caminhos de saída a partir da resposta:
```text
OLD_SQLITE = steps.export1.output
NEW_SQLITE = steps.export2.output
RESULTS = steps.diff.output
```
Para este exemplo, os arquivos gerados são `old.diaphora.sqlite`, `new.diaphora.sqlite` e `old_vs_new.diaphora` em `run-001`. Nomes base de entrada iguais produzem nomes de exportação distintos `old_`/`new_`. Mantenha `cleanup=false` para inspeção posterior das funções.
### 2. Obtenha um resumo e inspecione correspondências alteradas
Ferramenta: **`get_diff_summary`**.
```json
{
"results_path": "C:/diaphora-outputs/run-001/old_vs_new.diaphora"
}
```
Ferramenta: **`get_diff_results`**. Esta página começa com correspondências parciais de proporção mais baixa.
```json
{
"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` seleciona uma categoria de correspondência do Diaphora, não uma garantia de mudança comportamental. Use `match_type="all"` para todas as categorias suportadas. A resposta inclui contagens por categoria, o total filtrado, correspondências, linhas não correspondidas, `next_offset` e `next_unmatched_offset`.
Para continuar, copie os próximos offsets retornados para a próxima chamada, mantendo os mesmos filtros e ordenação. Por exemplo, se forem `50` e `50`, use `offset=50` e `unmatched_offset=50`. Um próximo offset `null` significa que essa lista terminou; pare de avançá-la. As duas listas progridem independentemente. Os tamanhos de página devem ser positivos e são limitados a 5000. Use `sort_order="desc"` para inspecionar primeiro as correspondências mais fortes.
### 3. Compare uma função correspondida e seu grafo
Ferramenta: **`compare_functions`**.
```json
{
"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"
}
```
A resposta contém `function_old`, `function_new`, assembly/pseudocódigo disponível, diferenças medidas e evidências de identidade. Você pode usar `name` em vez de `address`. Se ambos os seletores forem fornecidos, o endereço tem precedência; omita-o ao selecionar por nome.
Ferramenta: **`get_changed_callgraph`** aceita os mesmos argumentos acima. Ela traduz os endereços correspondentes de chamadores/chamados antes de relatar mudanças, e separa vizinhos não resolvidos de diferenças de arestas confirmadas.
Prefira **endereços com prefixo `0x`** para tornar a entrada hexadecimal explícita. Forneça `match_results_path` quando disponível: ele lida com rebase e funções renomeadas. Endereços iguais por si só não estabelecem identidade. Correspondências ambíguas ou ausentes permanecem não resolvidas em vez de serem chamadas de exclusões. Se você verificou manualmente um par, pode fornecer `address2` ou `name2` explicitamente.
### 4. Encontre uma função e leia seu código
Ferramenta: **`search_export_db`**. `name_pattern` usa SQL LIKE: `%` corresponde a qualquer sequência.
```json
{
"db_path": "C:/diaphora-outputs/run-001/old.diaphora.sqlite",
"name_pattern": "%parse%",
"min_instructions": 20,
"limit": 20
}
```
Ferramenta: **`get_function_pseudocode`** retorna pseudocódigo **e assembly** disponíveis, apesar do nome.
```json
{
"db_path": "C:/diaphora-outputs/run-001/old.diaphora.sqlite",
"address": "0x401000"
}
```
Se o pseudocódigo estiver vazio, execute novamente a exportação em um novo diretório de execução com `use_decompiler=true` e `summaries_only=false`, usando um descompilador compatível. Use `get_export_info` com `db_path` para inspecionar os metadados da exportação.
### 5. Compare exportações que você já possui
Ferramenta: **`diff_diaphora_dbs`**. Isso ignora a exportação do IDA e compara as exportações SQLite oficiais existentes.
```json
{
"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"
}
```
Para uma nova exportação, use `export_idb_to_diaphora` com `idb_path`, um `output_path` novo e `export_mode="headless"`.
## Ferramentas
| Ferramenta | Propósito |
| --- | --- |
| `export_idb_to_diaphora` | Exporta um banco de dados do IDA salvo |
| `batch_export_and_diff` | Exporta ambos os bancos de dados e os compara |
| `diff_diaphora_dbs` | Compara exportações existentes |
| `get_diff_summary` | Estatísticas de correspondência e exemplos limitados |
| `get_diff_results` | Resultados filtrados, ordenados e paginados |
| `get_export_info` | Metadados e contagens da exportação |
| `search_export_db` | Pesquisa funções |
| `get_function_pseudocode` | Lê assembly/pseudocódigo |
| `compare_functions` | Compara um par antigo/novo resolvido |
| `get_changed_callgraph` | Compara chamadores/chamados mapeados |
As assinaturas exatas podem ser descobertas via MCP `tools/list`. Veja [Referência de ferramentas](https://github.com/xteardx/diaphora-mcp/blob/master/docs/TOOLS.md).
## Modos de exportação e configuração
| Modo | Comportamento |
| --- | --- |
| `headless` | Inicia o IDA em modo headless e valida o esquema de diff; recomendado para comparações |
| `auto` | Tenta a ponte GUI ativa, depois o fallback headless |
| `gui` | Exige a sessão GUI correta aberta; sem fallback headless |
`batch_export_and_diff` requer `headless`.
| Variável de ambiente | Significado |
| --- | --- |
| `IDAT_PATH` | Caminho absoluto para o executável headless do IDA |
| `DIAPHORA_DIR` | Diretório contendo os scripts do Diaphora |
| `DIAPHORA_OUTPUT_ROOT` | Raiz permitida existente para novas exportações e resultados de diff |
| `DIAPHORA_PYTHON` | Interpretador de diff opcional; usa por padrão o interpretador do servidor MCP |
| `DIAPHORA_ENABLE_LEGACY_TOOLS` | Exatamente `1` habilita a interface anterior de 21 ferramentas |
Correspondência legada, pontuações de recursos, triagem de segurança, relatórios, metadados e diagnósticos permanecem opcionais. Para habilitá-los, adicione a seguinte entrada ao objeto `env` da configuração e reinicie:
```json
{
"DIAPHORA_ENABLE_LEGACY_TOOLS": "1"
}
```
Essas ferramentas usam heurísticas; suas pontuações não provam equivalência semântica, correções de segurança ou causalidade. [Configuração](https://github.com/xteardx/diaphora-mcp/blob/master/docs/CONFIGURATION.md) · [Configuração da GUI](https://github.com/xteardx/diaphora-mcp/blob/master/GUI_INSTRUCTIONS.md).
## Solução de problemas
| Sintoma | Ação |
| --- | --- |
| O alvo já existe | Use um diretório de execução ou nome de arquivo de saída novo |
| Saída fora da raiz permitida | Escolha um destino sob `DIAPHORA_OUTPUT_ROOT`; crie a raiz primeiro |
| Banco de dados do IDA passado para uma ferramenta de resultados | Use as exportações `.diaphora.sqlite` retornadas ou os resultados `.diaphora`, conforme apropriado |
| Contraparte ausente/ambígua | Verifique a ordem antigo/novo e o mapeamento; inspecione o candidato manualmente |
| Assembly/pseudocódigo vazio | Verifique o perfil de exportação; obtenha uma nova exportação detalhada |
| Exportação/diff demora muito | Aumente o timeout do cliente MCP; inspecione os `logs/` locais; considere uma primeira passagem apenas com resumos |
| IDB bloqueado por uma sessão do IDA | Feche a sessão ou use o modo de exportação GUI correspondente para uma única exportação |
| Esquema não suportado | Reexporte com a versão suportada do Diaphora; veja as tabelas/colunas ausentes relatadas |
A correspondência permanece heurística; uma proporção alta é evidência, não prova. Funções não correspondidas não são adições/exclusões confirmadas. Mantenha binários, IDBs, exportações e logs fora do Git. Veja [Fluxos de trabalho](https://github.com/xteardx/diaphora-mcp/blob/master/docs/WORKFLOWS.md), [Limitações](https://github.com/xteardx/diaphora-mcp/blob/master/docs/LIMITATIONS.md) e [Segurança](https://github.com/xteardx/diaphora-mcp/blob/master/SECURITY.md).
## Desenvolvimento
```powershell
.\.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
```
A suíte de regressão usa bancos de dados sintéticos e processos do IDA simulados. A exportação real do IDA requer validação de integração local. [Contribuindo](https://github.com/xteardx/diaphora-mcp/blob/master/CONTRIBUTING.md) · [Instruções para agentes](https://github.com/xteardx/diaphora-mcp/blob/master/AGENTS.md).