
Servidor MCP para diffing binario automatizado.
Compara dos binarios analizados con IDA desde tu asistente de IA. Diaphora MCP exporta las bases de datos de IDA guardadas, ejecuta Diaphora y permite que la IA inspeccione las funciones correspondientes y sus grafos de llamadas.
La interfaz predeterminada tiene 10 herramientas centradas en la comparación. Diaphora proporciona las coincidencias; la IA lee el código real y explica los cambios.
Inicio rápido · Ejemplos · Herramientas · Solución de problemas
old.i64 + new.i64 → headless export → SQLite exports + diff results
↓
summary → matched code → call graph
idat.exe/idat64, y un plugin Diaphora instalado..i64/.idb.IDA y Diaphora se instalan por separado. La validación del esquema de diff actualmente apunta a Diaphora 3.4.1; otros esquemas pueden necesitar actualizaciones de compatibilidad. El intérprete de Python usado para el diff debe tener instaladas las dependencias independientes de Diaphora.
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
Añade esta entrada a la configuración MCP de tu cliente. Reemplaza las rutas del repositorio, IDA y Diaphora con las rutas de tu instalación. Usa el ejecutable de Python del entorno donde instalaste este proyecto.
{
"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"
}
}
}
}
El cliente lanza el servidor por stdio; no hay un servicio web separado que iniciar. Reinicia el servidor MCP después de cambiar su código o entorno. Una conexión exitosa expone las 10 herramientas listadas a continuación.
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.
Elige un directorio de ejecución nuevo cada vez. Los destinos generados existentes nunca se sobrescriben.
Los siguientes bloques JSON son argumentos de herramientas MCP, no comandos de shell. Tu asistente puede llamar directamente a las herramientas nombradas. Las rutas y 0x401000 son ejemplos; usa las rutas y direcciones devueltas por tu propia ejecución.
Herramienta: batch_export_and_diff. El antiguo es siempre la primera entrada, el nuevo la 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
}
Esto conserva el detalle de ensamblador sin requerir Hex-Rays. Selecciona el perfil de exportación que necesites:
| Detalle | use_decompiler | summaries_only | Uso |
|---|---|---|---|
| Resúmenes de coincidencias | false | true | Primera pasada rápida; sin código detallado |
| Ensamblador | false | false | Comparar desensamblado sin un descompilador |
| Ensamblador + pseudocódigo | true | false | Revisión de código con un descompilador Hex-Rays compatible; más lento |
Toma siempre las rutas de salida de la respuesta:
OLD_SQLITE = steps.export1.output
NEW_SQLITE = steps.export2.output
RESULTS = steps.diff.output
Para este ejemplo, los archivos generados son old.diaphora.sqlite, new.diaphora.sqlite y old_vs_new.diaphora bajo run-001. Nombres base de entrada iguales producen nombres de exportación distintos old_/new_. Mantén cleanup=false para la inspección posterior de funciones.
Herramienta: get_diff_summary.
{
"results_path": "C:/diaphora-outputs/run-001/old_vs_new.diaphora"
}
Herramienta: get_diff_results. Esta página comienza con coincidencias parciales de menor ratio.
{
"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 selecciona una categoría de coincidencia de Diaphora, no una garantía de cambio de comportamiento. Usa match_type="all" para todas las categorías compatibles. La respuesta incluye recuentos por categoría, el total filtrado, coincidencias, filas no coincidentes, next_offset y next_unmatched_offset.
Para continuar, copia los siguientes offsets devueltos en la siguiente llamada, manteniendo los mismos filtros y orden. Por ejemplo, si son 50 y 50, usa offset=50 y unmatched_offset=50. Un siguiente offset null significa que esa lista ha terminado; deja de avanzarla. Las dos listas progresan de forma independiente. Los tamaños de página deben ser positivos y están limitados a 5000. Usa sort_order="desc" para inspeccionar primero las coincidencias más fuertes.
Herramienta: 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 respuesta contiene function_old, function_new, ensamblador/pseudocódigo disponible, diferencias medidas y evidencia de identidad. Puedes usar name en lugar de address. Si se proporcionan ambos selectores, la dirección tiene prioridad; omítela cuando selecciones por nombre.
Herramienta: get_changed_callgraph acepta los mismos argumentos anteriores. Traduce las direcciones correspondientes de llamadores/llamados antes de informar cambios, y separa los vecinos no resueltos de las diferencias de aristas confirmadas.
Prefiere direcciones con prefijo 0x para hacer explícita la entrada hexadecimal. Proporciona match_results_path cuando esté disponible: maneja el reajuste de base y las funciones renombradas. Direcciones iguales por sí solas no establecen identidad. Las coincidencias ambiguas o ausentes permanecen sin resolver en lugar de considerarse eliminaciones. Si has verificado manualmente un par, puedes proporcionar address2 o name2 explícitamente.
Herramienta: search_export_db. name_pattern usa SQL LIKE: % coincide con cualquier secuencia.
{
"db_path": "C:/diaphora-outputs/run-001/old.diaphora.sqlite",
"name_pattern": "%parse%",
"min_instructions": 20,
"limit": 20
}
Herramienta: get_function_pseudocode devuelve el pseudocódigo disponible y el ensamblador, a pesar de su nombre.