
Servidor MCP para diffing binário automatizado.
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 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 · Exemplos · Ferramentas · Solução de problemas
old.i64 + new.i64 → exportação headless → exportações SQLite + resultados de diff
↓
resumo → código correspondente → grafo de chamadas
idat.exe/idat64 e um plugin Diaphora instalado..i64/.idb.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.
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
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.
{
"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.
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.
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.
Ferramenta: batch_export_and_diff. O antigo é sempre a primeira entrada, o novo a segunda.
{
"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:
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.
Ferramenta: get_diff_summary.
{
"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.
{
"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.
Ferramenta: 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"
}
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.
Ferramenta: search_export_db. name_pattern usa SQL LIKE: % corresponde a qualquer sequência.
{
"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.
{
"db_path": "C:/diaphora-outputs/run-001/old.diaphora.sqlite",
"address": "0x401000"
}