
Serveur MCP pour le diffing binaire automatisé.
Comparez deux binaires analysés par IDA depuis votre assistant IA. Diaphora MCP exporte les bases de données IDA enregistrées, exécute Diaphora, et permet à l'IA d'inspecter les fonctions correspondantes et leurs graphes d'appels.
L'interface par défaut comporte 10 outils axés sur la comparaison. Diaphora fournit les correspondances ; l'IA lit le code réel et explique les changements.
Démarrage rapide · Exemples · Outils · Dépannage
old.i64 + new.i64 → headless export → SQLite exports + diff results
↓
summary → matched code → call graph
idat.exe/idat64, et un plugin Diaphora installé..i64/.idb.IDA et Diaphora sont installés séparément. La validation du schéma de diff cible actuellement Diaphora 3.4.1 ; d'autres schémas peuvent nécessiter des mises à jour de compatibilité. L'interpréteur Python utilisé pour le diff doit avoir les dépendances autonomes de Diaphora installées.
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
Ajoutez cette entrée à la configuration MCP de votre client. Remplacez les chemins du dépôt, d'IDA et de Diaphora par vos chemins d'installation. Utilisez l'exécutable Python de l'environnement où vous avez installé ce projet.
{
"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"
}
}
}
}
Le client lance le serveur via stdio ; il n'y a pas de service web séparé à démarrer. Redémarrez le serveur MCP après avoir modifié son code ou son environnement. Une connexion réussie expose les 10 outils listés ci-dessous.
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.
Choisissez un répertoire d'exécution neuf à chaque fois. Les cibles générées existantes ne sont jamais écrasées.
Les blocs JSON suivants sont des arguments d'outils MCP, et non des commandes shell. Votre assistant peut appeler directement les outils nommés. Les chemins et 0x401000 sont des exemples ; utilisez les chemins et adresses renvoyés par votre propre exécution.
Outil : batch_export_and_diff. L'ancien est toujours la première entrée, le nouveau la seconde.
{
"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
}
Cela conserve le détail de l'assembleur sans nécessiter Hex-Rays. Sélectionnez le profil d'export dont vous avez besoin :
| Détail | use_decompiler | summaries_only | Utilisation |
|---|---|---|---|
| Résumés de correspondance | false | true | Première passe rapide ; pas de code détaillé |
| Assembleur | false | false | Comparer le désassemblage sans décompilateur |
| Assembleur + pseudocode | true | false | Revue de code avec un décompilateur Hex-Rays compatible ; plus lent |
Récupérez toujours les chemins de sortie depuis la réponse :
OLD_SQLITE = steps.export1.output
NEW_SQLITE = steps.export2.output
RESULTS = steps.diff.output
Pour cet exemple, les fichiers générés sont old.diaphora.sqlite, new.diaphora.sqlite et old_vs_new.diaphora sous run-001. Des noms de base d'entrée identiques produisent des noms d'export distincts old_/new_. Conservez cleanup=false pour l'inspection ultérieure des fonctions.
Outil : get_diff_summary.
{
"results_path": "C:/diaphora-outputs/run-001/old_vs_new.diaphora"
}
Outil : get_diff_results. Cette page commence par les correspondances partielles à ratio plus faible.
{
"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 sélectionne une catégorie de correspondance Diaphora, et non une garantie de changement comportemental. Utilisez match_type="all" pour toutes les catégories prises en charge. La réponse inclut les décomptes par catégorie, le total filtré, les correspondances, les lignes non appariées, next_offset et next_unmatched_offset.
Pour continuer, copiez les prochains décalages renvoyés dans l'appel suivant, en conservant les mêmes filtres et le même tri. Par exemple, s'ils valent 50 et 50, utilisez offset=50 et unmatched_offset=50. Un prochain décalage null signifie que cette liste est terminée ; cessez de la faire avancer. Les deux listes progressent indépendamment. Les tailles de page doivent être positives et sont plafonnées à 5000. Utilisez sort_order="desc" pour inspecter d'abord les correspondances les plus fortes.
Outil : 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"
}
La réponse contient function_old, function_new, l'assembleur/pseudocode disponible, les différences mesurées et les preuves d'identité. Vous pouvez utiliser name au lieu de address. Si les deux sélecteurs sont fournis, l'adresse est prioritaire ; omettez-la lors d'une sélection par nom.
Outil : get_changed_callgraph accepte les mêmes arguments ci-dessus. Il traduit les adresses correspondantes des appelants/appelés avant de signaler les changements, et sépare les voisins non résolus des différences d'arêtes confirmées.
Préférez les adresses préfixées par 0x pour rendre l'entrée hexadécimale explicite. Fournissez match_results_path lorsqu'il est disponible : il gère le rebasage et les fonctions renommées. Des adresses égales seules n'établissent pas l'identité. Les correspondances ambiguës ou manquantes restent non résolues plutôt que d'être qualifiées de suppressions. Si vous avez vérifié manuellement une paire, vous pouvez fournir explicitement address2 ou name2.
Outil : search_export_db. name_pattern utilise SQL LIKE : % correspond à n'importe quelle séquence.
{
"db_path": "C:/diaphora-outputs/run-001/old.diaphora.sqlite",
"name_pattern": "%parse%",
"min_instructions": 20,
"limit": 20
}