
Server MCP per il diffing binario automatico.
Diaphora MCP è un server MCP (Model Context Protocol) per il diffing automatico di binari. Collega Diaphora (il motore di diffing) e IDA Pro (il disassemblatore) tramite il protocollo MCP, consentendo ad agenti AI (come Claude Code) di eseguire confronti di file binari, trovare patch di sicurezza e analizzare le modifiche.
.i64/.idb analizzati nel formato SQLite di Diaphora (tramite idat.exe in modalità headless)idat.exe)git clone https://github.com/xTeardx/diaphora-mcp.git
cd diaphora-mcp
pip install -e .
Il pacchetto tenta di trovare automaticamente IDA Pro e Diaphora nelle posizioni di installazione standard. Se non vengono trovati, è possibile impostare le seguenti variabili d'ambiente:
Per Claude Code, è possibile specificarle in ~/.claude.json (o nel file di configurazione corrispondente del proprio client MCP):
{
"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
}
}
}
Nota: Per binari molto grandi (>100 MB), assicurarsi che
timeoutsia almeno 7200 (2 ore).
Codex utilizza tipicamente due server MCP complementari:
diaphora-mcp — questo progetto: esportazione, diff Diaphora e analisi dei risultati;ida-pro-mcp — il server di ispezione IDA upstream per idb_open, decompilazione e analisi a livello di indirizzo.idalib-mcp è il backend headless di ida-pro-mcp, non un server Diaphora separato. Dopo averlo installato, riavvia Codex:
uv run ida-pro-mcp --install codex --transport streamable-http --scope global --ida-rpc http://127.0.0.1:8745/mcp
Per questo progetto, una configurazione stdio è sufficiente:
[mcp_servers.diaphora-mcp]
command = "python"
args = ["D:\\path\\to\\diaphora-mcp\\diaphora_mcp_server.py"]
startup_timeout_sec = 120
IDA Pro deve prima analizzare i binari (creando file .i64 o .idb). Dopodiché:
┃ export_idb_to_diaphora(idb_path="old_version.i64")
┃ export_idb_to_diaphora(idb_path="new_version.i64")
Oppure esegui l'intero pipeline in un unico comando:
┃ batch_export_and_diff(idb1="old.i64", idb2="new.i64")
Non passare .i64 direttamente agli strumenti dei risultati: è un database IDA, non SQLite. Esportalo prima.
┃ # 1. Full pipeline: export two .i64 → diff → summary report
┃ batch_export_and_diff(idb1="v1.0.i64", idb2="v1.1.i64")
┃ # 2. If databases are already exported
┃ diff_diaphora_dbs(db1="v1.0.sqlite", db2="v1.1.sqlite")
┃ # 3. Security analysis of diff results
┃ analyze_diff_results(results_path="v1.0_vs_v1.1.diaphora")
┃ # 4. Importance ranking of changes
┃ rank_changes(results_path="v1.0_vs_v1.1.diaphora", top_n=20)
┃ # 5. Find root-cause changes
┃ find_patch_root(results_path="v1.0_vs_v1.1.diaphora")
┃ # 6. Detect probable security patches
┃ detect_security_patches(results_path="v1.0_vs_v1.1.diaphora")
┃ # 7. Generate full report
┃ summarize_patch(results_path="v1.0_vs_v1.1.diaphora")
Vedi examples/basic-session.md per una trascrizione completa passo-passo di una sessione reale di Diaphora MCP — dall'esportazione di due database IDB al confronto di funzioni individuali. Disponibile anche in russo.
Ecco un'anteprima di ciò che il server restituisce:
Input — confronta due DLL SQLite3 (2015 vs 2023):
{"idb1_path": "old.i64", "idb2_path": "new.i64", "use_decompiler": false}
Output — riepilogo dopo export + diff:
{
"best_matches": 60,
"partial_matches": 993,
"multimatches": 52,
"unmatched_primary": 2647
}
La sessione esamina 6 chiamate a strumenti MCP, mostrando l'esatto JSON in/out per ogni passaggio, insieme al ragionamento dell'agente.
┃ # Get database export info
┃ get_export_info(db_path="app.sqlite")
┃ # Search for functions
┃ search_export_db(db_path="app.sqlite", name_pattern="%crypt%", min_instructions=50)
┃ # Retrieve pseudocode
┃ get_function_pseudocode(db_path="app.sqlite", address="401000")
diaphora-mcp/
├── diaphora_mcp_server.py # Main entrypoint
├── diaphora_mcp/
│ ├── diaphora_mcp_server.py # MCP tool registration
│ ├── config.py # Path configuration and auto-detection
│ ├── models.py # Constants and models
│ ├── core/
│ │ ├── export.py # Headless export, batch pipeline
│ │ ├── diff.py # Diffing and .diaphora results reader
│ │ ├── analysis.py # Function search, compare, explain
│ │ ├── security.py # Keyword matching, patch detection
│ │ ├── ranking.py # Importance ranking
│ │ ├── graph.py # Callgraph, BFS call trees, root cause
│ │ ├── metadata.py # Metadata preparation (names, comments)
│ │ └── report.py # Overall patch report generation
│ └── utils/
│ ├── sqlite.py # SQLite helpers
│ ├── format.py # Pseudocode diff, feature vector extraction
│ └── log.py # Export logging utilities
├── _diaphora_headless.py # idat.exe -S thin wrapper
└── logs/ # Automated export logs (created dynamically)
| Strumento | Descrizione |
|---|---|
export_idb_to_diaphora | Esporta il database .i64/.idb in formato SQLite utilizzando IDA headless |
batch_export_and_diff | Pipeline completo: esporta primario → esporta secondario → diff → riepilogo |
| Strumento | Descrizione |
|---|---|
diff_diaphora_dbs | Differenzia due database Diaphora SQLite esportati |
get_diff_results | Legge il file diff .diaphora con filtri |
get_diff_summary | Restituisce statistiche di corrispondenza |
| Strumento | Descrizione |
|---|---|
detect_security_patches | Rileva probabili correzioni di sicurezza (controlli di bounds, sicurezza della memoria, anti-debug, ecc.) |
| Strumento | Descrizione |
|---|---|
rank_changes | Classifica le funzioni modificate per importanza (punteggio 0-100) |
| Strumento | Descrizione |
|---|---|
get_changed_callgraph | Confronta le chiamate in entrata e in uscita di una funzione |
compare_call_path | Esamina il grafo delle chiamate da una funzione (confronto dei percorsi BFS, fino a N livelli) |
find_patch_root | Rileva le funzioni causa principale che generano cascate di chiamate |
| Strumento | Descrizione |
|---|---|
performance_report | Restituisce statistiche aggregate di memoria, cache e connessioni |
| Strumento | Descrizione |
|---|---|
transfer_metadata | Prepara nomi, commenti e prototipi per il trasferimento in blocco |
Il progetto include un'integrazione integrata con le sessioni GUI di IDA Pro in esecuzione, consentendo esportazioni istantanee direttamente dalle finestre IDA attive senza conflitti di blocco del database.
plugins/ di IDA Pro. Avvierà un server XML-RPC in background sulla porta 28652 ogni volta che IDA viene avviato.export_idb_to_diaphora, il server MCP controlla la porta 28652. Se una sessione è attiva, esegue l'esportazione direttamente nella GUI. Altrimenti, ricade automaticamente sull'esecuzione headless in background tramite idat.exe.Per istruzioni dettagliate sulla configurazione del bridge, vedere GUI_INSTRUCTIONS.md.
Quando si elaborano progetti estremamente grandi, Diaphora MCP applica ottimizzazioni specifiche:
100000 (sys.setrecursionlimit) per prevenire crash durante le traversate di grandi grafi di chiamate.diaphora_config.py, impostando COMMIT_AFTER_EACH_GUI_UPDATE = False si riducono le scritture su disco, accelerando l'esportazione GUI di 2x-3x.EXPORTING_USE_MICROCODE = False nella configurazione Diaphora) per un'esportazione più rapida quando il decompilatore non è strettamente richiesto.Strumenti come analyze_diff_results, compare_functions e find_function_match restituiscono un blocco ida_pro_mcp contenente indirizzi e percorsi. Queste informazioni possono essere passate direttamente agli strumenti ida-pro-mcp:
┃ # 1. Diaphora finds a suspicious function
┃ analyze_diff_results(results_path="diff.diaphora")
┃ → addr1="401000", db1="old.sqlite"
┃ # 2. IDA Pro MCP decompiles it
┃ decompile_function(address="401000")
Per vedere Diaphora MCP in azione, consulta i seguenti esempi:
Se sei un assistente di codifica AI (come Claude Code) che utilizza questo protocollo, tieni presenti le seguenti regole di compatibilità:
Schemi di esportazione GUI vs. Headless:
ida_mcp.py) produce uno schema personalizzato contenente tabelle come calls, strings, structures, ma nessuna tabella program.idat.exe) produce lo schema Diaphora ufficiale che contiene la tabella program.diff_diaphora_dbs) richiede lo schema ufficiale. Esporta sempre in modalità headless se intendi confrontare/differenziare database.Database bloccati nella GUI:
Evita collisioni di nomi dei database:
<basename>.diaphora.sqlite.I fixture controllati di IDA Pro 9.3 superano la suite di regressione: 16 passed, 1 xpassed. Sono state verificate anche un'esportazione reale e un diff Diaphora di due DLL SQLite3. Gli IDB grandi o aperti in GUI richiedono ancora un lock IDA libero, un DIAPHORA_OUTPUT_ROOT valido e un timeout del client MCP sufficientemente grande.
MIT
| Variabile | Descrizione | Esempio |
|---|
IDAT_PATH | Percorso completo per idat.exe | C:\Program Files\IDA Pro 9.3\idat.exe |
DIAPHORA_DIR | Cartella contenente diaphora.py | C:\Program Files\IDA Pro 9.3\plugins\diaphora-3.4.1 |
DIAPHORA_OUTPUT_ROOT | Directory root consentita per i nuovi file di export | D:\\diaphora-outputs |
DIAPHORA_PYTHON | Interprete Python per il diff | /usr/bin/python3 (default a sys.executable) |
| Strumento | Descrizione |
|---|
analyze_diff_results | Filtra i risultati usando parole chiave di sicurezza e filtri |
compare_functions | Confronto affiancato di una funzione in entrambi i database |
find_function_match | Trova una corrispondenza della funzione nel secondo binario con metriche di confidenza |
explain_similarity | Suddivide i fattori di similarità (mnemoniche, CFG, costanti, prototipo, hash) |
detect_behavior_change | Fornisce un riepilogo in linguaggio naturale delle modifiche alla logica della funzione |
summarize_patch | Produce un report completo dell'aggiornamento |
search_export_db | Interroga le funzioni esportate per nome/istruzioni/complessità |
get_function_pseudocode | Recupera pseudocodice e metadati per una funzione |
get_export_info | Recupera metadati generali del database |
<basename>.sqlite per le esportazioni Diaphora, poiché entra in conflitto con il database cache interno creato dal supervisore ida-pro-mcp.