IDA Pro MCP

Servidor MCP para ingeniería inversa automatizada con IDA Pro.

Documentación

IDA Pro MCP

Servidor MCP sencillo para permitir reverso "vibe" en IDA Pro.

https://github.com/user-attachments/assets/6ebeaa92-a9db-43fa-b756-eececce2aca0

Los binarios y el prompt para el video están disponibles en el repositorio mcp-reversing-dataset.

Requisitos previos

Nota: Esto requiere tener idalib activado globalmente y uv instalado:

# windows
uv run "C:\Program Files\IDA Professional 9.3\idalib\python\py-activate-idalib.py"
# macos
uv run "/Applications/IDA Professional 9.3.app/Contents/MacOS/idalib/python/py-activate-idalib.py"
# linux
uv run "/path/to/idapro-9.3/idalib/python/py-activate-idalib.py"

Instalación (Claude Code)

Para instalar la última versión de IDA Pro MCP en Claude Code:

claude plugin marketplace add mrexodia/claude-marketplace
claude plugin uninstall ida-pro-mcp@mrexodia
claude plugin install ida-pro-mcp@mrexodia

Instalación (Codex)

Para instalar la última versión de IDA Pro MCP en Codex:

codex plugin marketplace add mrexodia/codex-marketplace
codex plugin remove ida-pro-mcp@mrexodia
codex plugin add ida-pro-mcp@mrexodia

Instalación (Kimi Code)

Para instalar la última versión de IDA Pro MCP en Kimi Code, ejecuta este comando de barra en el chat:

/plugins install https://github.com/mrexodia/ida-pro-mcp/tree/main
/reload

Esto instala el servidor MCP idalib y la habilidad idapython. Los plugins se copian a $KIMI_CODE_HOME/plugins/managed/, por lo que uv debe estar en tu PATH. La primera sesión después de instalar es más lenta, porque uv resuelve las dependencias antes de que el servidor responda.

Instalación (GUI)

Nota: el plugin MCP ya no se recomienda y eventualmente quedará obsoleto. Usa idalib-mcp en su lugar.

Si deseas configurar el servidor MCP manualmente desde la GUI de IDA:

pip uninstall ida-pro-mcp
pip install https://github.com/mrexodia/ida-pro-mcp/archive/refs/heads/main.zip

Configura los servidores MCP e instala el Plugin de IDA:

ida-pro-mcp --install

Importante: Asegúrate de reiniciar completamente IDA y tu cliente MCP para que la instalación surta efecto. Algunos clientes (como Claude) se ejecutan en segundo plano y deben cerrarse desde el icono de la bandeja.

Ingeniería de Prompts

Los LLM son propensos a alucinaciones y debes ser específico con tus prompts. Para la ingeniería inversa, la conversión entre enteros y bytes es especialmente problemática. A continuación se muestra un ejemplo mínimo de prompt; no dudes en iniciar una discusión o abrir un issue si obtienes buenos resultados con un prompt diferente:

Your task is to analyze a crackme in IDA Pro. You can use the MCP tools to retrieve information. In general use the following strategy:

- Inspect the decompilation and add comments with your findings
- Rename variables to more sensible names
- Change the variable and argument types if necessary (especially pointer and array types)
- Change function names to be more descriptive
- If more details are necessary, disassemble the function and add comments with your findings
- NEVER convert number bases yourself. Use the `int_convert` MCP tool if needed!
- Do not attempt brute forcing, derive any solutions purely from the disassembly and simple python scripts
- Create a report.md with your findings and steps taken at the end
- When you find a solution, prompt to user for feedback with the password you found

Este prompt fue solo el primer experimento; ¡comparte si encontraste formas de mejorar el resultado!

Otro prompt de @can1357:

Your task is to create a complete and comprehensive reverse engineering analysis. Reference AGENTS.md to understand the project goals and ensure the analysis serves our purposes.

Use the following systematic methodology:

1. **Decompilation Analysis**
   - Thoroughly inspect the decompiler output
   - Add detailed comments documenting your findings
   - Focus on understanding the actual functionality and purpose of each component (do not rely on old, incorrect comments)

2. **Improve Readability in the Database**
   - Rename variables to sensible, descriptive names
   - Correct variable and argument types where necessary (especially pointers and array types)
   - Update function names to be descriptive of their actual purpose

3. **Deep Dive When Needed**
   - If more details are necessary, examine the disassembly and add comments with findings
   - Document any low-level behaviors that aren't clear from the decompilation alone
   - Use sub-agents to perform detailed analysis

4. **Important Constraints**
   - NEVER convert number bases yourself - use the int_convert MCP tool if needed
   - Use MCP tools to retrieve information as necessary
   - Derive all conclusions from actual analysis, not assumptions

5. **Documentation**
   - Produce comprehensive RE/*.md files with your findings
   - Document the steps taken and methodology used
   - When asked by the user, ensure accuracy over previous analysis file
   - Organize findings in a way that serves the project goals outlined in AGENTS.md or CLAUDE.md

Transmisión en vivo que analiza prompts y muestra análisis de malware del mundo real:

Consejos para Mejorar la Precisión del LLM

Los Modelos de Lenguaje Grande (LLM) son herramientas potentes, pero a veces pueden tener dificultades con cálculos matemáticos complejos o exhibir "alucinaciones" (inventar hechos). Asegúrate de indicar al LLM que use la herramienta MCP int_convert y es posible que también necesites math-mcp para ciertas operaciones.

Otra cosa a tener en cuenta es que los LLM no se desempeñarán bien con código ofuscado. Antes de intentar usar un LLM para resolver el problema, examina el binario y dedica tiempo a eliminar (automáticamente) lo siguiente:

  • Cifrado de cadenas
  • Hashing de importaciones
  • Aplanamiento del flujo de control
  • Cifrado de código
  • Trucos anti-descompilación

También deberías usar una herramienta como Lumina o FLIRT para intentar resolver todo el código de bibliotecas de código abierto y la STL de C++; esto mejorará aún más la precisión.

Transportes y MCP sin Interfaz

Puedes ejecutar un servidor SSE para conectarte a la interfaz de usuario de esta manera:

uv run ida-pro-mcp --transport http://127.0.0.1:8744/sse

Después de instalar idalib también puedes ejecutar un servidor MCP sin interfaz. Puedes comenzar con un binario inicial:

uv run idalib-mcp --host 127.0.0.1 --port 8745 path/to/executable

O comenzar sin un binario y abrir archivos arbitrarios más tarde con idb_open(...):

uv run idalib-mcp --host 127.0.0.1 --port 8745

Para clientes basados en stdio, usa:

uv run idalib-mcp --stdio

Los trabajadores de base de datos son persistentes: cada uno se ejecuta como un proceso separado que sobrevive al supervisor que lo creó. Cuando un nuevo supervisor (a través de stdio o HTTP) llama a idb_open para un binario que ya está abierto bajo un trabajador en este host, el supervisor adopta ese trabajador de forma transparente; no hay un modo "compartido" separado que activar. Los trabajadores se cierran solos cuando no han recibido ninguna solicitud durante un intervalo de inactividad.

Nota: La función idalib fue contribuida por Willi Ballenthin.

Modelo de Sesión idalib sin Interfaz

idalib-mcp es un supervisor que mantiene cada base de datos abierta en su propio proceso trabajador idalib. Los trabajadores se registran en un directorio de descubrimiento local del host y sobreviven al supervisor que los creó; cualquier supervisor posterior que quiera la misma ruta adopta al trabajador en ejecución. Un trabajador se cierra solo cuando no ha recibido ninguna solicitud durante su TTL de inactividad (por defecto 1 hora). Llama a idb_close para liberar un trabajador de inmediato (liberando un espacio hacia --max-workers); las instancias GUI/trabajador adoptadas se separan en lugar de eliminarse.

idb_open elige el backend mediante su parámetro mode:

  • prefer_headless (por defecto): genera un trabajador idalib (o adopta uno que ya tenga el archivo abierto).
  • force_headless: igual, pero nunca adopta una GUI en ejecución incluso si alguien tiene el archivo.
  • prefer_gui: adopta una GUI en ejecución para el archivo; de lo contrario, genera un trabajador idalib.
  • force_gui: adopta una GUI en ejecución para el archivo; de lo contrario, inicia un nuevo proceso GUI de IDA.

Cada llamada a herramienta debe llevar un argumento explícito database. No hay una "base de datos actual" implícita: los llamadores nombran la sesión en la que desean operar.

uv run idalib-mcp --stdio --max-workers 4

Flujo típico:

idb_open("/path/to/binary_a.exe", preferred_session_id="binary_a")
idb_open("/path/to/library.dll", preferred_session_id="library")

decompile("main", database="binary_a")
xrefs_to("ImportantExport", database="library")

database debe ser el ID de sesión devuelto por idb_open (o mostrado en idb_list); no se aceptan nombres de archivo ni rutas.

Herramientas de gestión

  • idb_open(input_path, mode="prefer_headless", run_auto_analysis=True, build_caches=True, init_hexrays=True, preferred_session_id=""): Abre un binario, prepara subsistemas (caché de cadenas, Hex-Rays) y devuelve su ID de sesión. Si ya se está ejecutando un trabajador o GUI para esta ruta en el host, esa instancia se adopta y preferred_session_id se ignora.
  • idb_list(): Lista sesiones abiertas e instancias GUI de IDA en ejecución. Cada entrada tiene adopted (True si este supervisor la gestiona, False para GUI/trabajadores descubiertos pero aún no abiertos mediante idb_open), backend (worker o gui), is_active e IDs de proceso.
  • idb_close(database, save=True): Guarda (opcionalmente), anula el registro de la sesión y termina su trabajador propiedad, liberando un espacio hacia --max-workers. Las instancias GUI/trabajador adoptadas se separan, no se eliminan.
  • idb_save(session_id, path=""): Guarda el IDB de una sesión en disco. Se reenvía como herramienta de trabajador regular (database=<id> inyectado): misma firma en ambos backends.
  • Salud por base de datos: llama a server_health(database=<id>) (reenviado). idb_list() informa is_active desde la sonda TCP/RPC del supervisor.

Controles del trabajador:

  • --max-workers N: máximo de trabajadores de base de datos simultáneos (0 = ilimitado, por defecto 4).
  • IDA_MCP_MAX_WORKERS: valor predeterminado de entorno para --max-workers.

El plugin Codex incluido reenvía las variables de configuración IDA_MCP_* del entorno del host de Codex:

  • Capacidad y ciclo de vida: IDA_MCP_MAX_WORKERS, IDA_MCP_OPEN_TIMEOUT, IDA_MCP_WEDGED_GRACE_SEC, IDA_MCP_WORKER_CALL_TIMEOUT.
  • Sondas de salud: IDA_MCP_HEALTH_TCP_TIMEOUT, IDA_MCP_HEALTH_RPC_TIMEOUT, IDA_MCP_HEALTH_RETRIES, IDA_MCP_HEALTH_RETRY_BACKOFF.
  • Comportamiento del trabajador: IDA_MCP_TOOL_TIMEOUT_SEC, IDA_MCP_ANALYSIS_PROMPT, IDA_MCP_URL.
  • Registro de solicitudes: IDA_MCP_LOG_REQUESTS, IDA_MCP_LOG_SKIP_METHODS.

Recursos MCP

Los recursos representan estado navegable (datos de solo lectura) siguiendo la filosofía de MCP.

Estado central del IDB:

  • ida://idb/metadata - Información del archivo IDB (ruta, arquitectura, base, tamaño, hashes)
  • ida://idb/segments - Segmentos de memoria con permisos
  • ida://idb/entrypoints - Puntos de entrada (main, callbacks TLS, etc.)

Estado de la interfaz:

  • ida://cursor - Posición actual del cursor y función
  • ida://selection - Rango de selección actual

Información de tipos:

  • ida://types - Todos los tipos locales
  • ida://structs - Todas las estructuras/uniones
  • ida://struct/{name} - Definición de estructura con campos

Búsquedas:

  • ida://import/{name} - Detalles de importación por nombre
  • ida://export/{name} - Detalles de exportación por nombre
  • ida://xrefs/from/{addr} - Referencias cruzadas desde una dirección

Funciones principales

  • lookup_funcs(queries): Obtiene función(es) por dirección o nombre (detección automática, acepta lista o cadena separada por comas).
  • int_convert(inputs): Convierte números a diferentes formatos (decimal, hexadecimal, bytes, ASCII, binario).
  • list_funcs(queries): Lista funciones (paginado, filtrado).
  • list_globals(queries): Lista variables globales (paginado, filtrado).
  • imports(offset, count): Lista todos los símbolos importados con nombres de módulo (paginado).
  • decompile(addr): Descompila la función en la dirección dada.
  • disasm(addr): Desensambla la función con detalles completos (argumentos, marco de pila, etc.).
  • xrefs_to(addrs): Obtiene todas las referencias cruzadas a dirección(es).
  • xrefs_to_field(queries): Obtiene referencias cruzadas a campo(s) de estructura específico(s).
  • callees(addrs): Obtiene funciones llamadas por función(es) en dirección(es).

Operaciones de modificación

  • add_bookmark(addr, name, prefix): Agrega o reemplaza el marcador de IDA en una dirección; establece prefix="" para sin prefijo.
  • set_comments(items): Establece comentarios en dirección(es) tanto en las vistas de desensamblado como de descompilador.
  • patch_asm(items): Parchea instrucciones de ensamblador en dirección(es).
  • declare_type(decls): Declara tipo(s) C en la biblioteca de tipos local.
  • define_func(items): Define función(es) en dirección(es). Opcionalmente especifica end para límites explícitos.
  • define_code(items): Convierte bytes a instrucción(es) de código en dirección(es).
  • undefine(items): Indefine elemento(s) en dirección(es), convirtiendo de nuevo a bytes sin procesar. Opcionalmente especifica end o size.

Operaciones de lectura de memoria

  • get_bytes(addrs): Lee bytes sin procesar en dirección(es).
  • get_int(queries): Lee valores enteros usando ty (i8/u64/i16le/i16be/etc).
  • get_string(addrs): Lee cadena(s) terminada(s) en nulo.
  • get_global_value(queries): Lee valor(es) de variable global por dirección o nombre (detección automática, valores en tiempo de compilación).

Operaciones de marco de pila

  • stack_frame(addrs): Obtiene variables del marco de pila para función(es).
  • declare_stack(items): Crea variable(s) de pila en desplazamiento(s) especificado(s).
  • delete_stack(items): Elimina variable(s) de pila por nombre.

Operaciones de estructura

  • read_struct(queries): Lee valores de campo de estructura en dirección(es) específica(s).
  • search_structs(filter): Busca estructuras por patrón de nombre.

Operaciones de depurador (Extensión)

Las herramientas del depurador están ocultas por defecto. Habilítalas con el parámetro de consulta ?ext=dbg:

http://127.0.0.1:13337/mcp?ext=dbg

Control:

  • dbg_start(): Inicia el proceso del depurador.
  • dbg_exit(): Sale del proceso del depurador.
  • dbg_continue(): Continúa la ejecución.
  • dbg_run_to(addr): Ejecuta hasta la dirección.
  • dbg_step_into(): Paso a paso dentro de la instrucción.
  • dbg_step_over(): Paso a paso sobre la instrucción.

Puntos de interrupción:

  • dbg_bps(): Lista todos los puntos de interrupción.
  • dbg_add_bp(addrs): Agrega punto(s) de interrupción.
  • dbg_delete_bp(addrs): Elimina punto(s) de interrupción.
  • dbg_toggle_bp(items): Habilita/deshabilita punto(s) de interrupción.

Registros:

  • dbg_regs(): Todos los registros, hilo actual.
  • dbg_regs_all(): Todos los registros, todos los hilos.
  • dbg_regs_remote(tids): Todos los registros, hilo(s) específico(s).
  • dbg_gpregs(): Registros GP, hilo actual.
  • dbg_gpregs_remote(tids): Registros GP, hilo(s) específico(s).
  • dbg_regs_named(names): Registros nombrados, hilo actual.
  • dbg_regs_named_remote(tid, names): Registros nombrados, hilo(s) específico(s). Stack & Memory:
  • dbg_stacktrace(): Pila de llamadas con información de módulos/símbolos.
  • dbg_read(regions): Leer memoria del proceso depurado.
  • dbg_write(regions): Escribir memoria en el proceso depurado.

Operaciones Avanzadas de Análisis

  • py_eval(code): Ejecutar código Python arbitrario en el contexto de IDA (devuelve un dict con resultado/stdout/stderr, admite evaluación estilo Jupyter).
  • analyze_funcs(addrs): Análisis integral de funciones (descompilación, ensamblador, referencias cruzadas, funciones llamadas, llamadores, cadenas, constantes, bloques básicos).

Búsqueda y Coincidencia de Patrones

  • find_regex(queries): Buscar cadenas con regex insensible a mayúsculas/minúsculas (paginado).
  • find_bytes(patterns, limit=1000, offset=0): Encontrar patrones de bytes en el binario (p. ej., "48 8B ?? ??"). Límite máximo: 10000.
  • find_insns(sequences, limit=1000, offset=0): Encontrar secuencias de instrucciones en el código. Límite máximo: 10000.
  • find(type, targets, limit=1000, offset=0): Búsqueda avanzada (valores inmediatos, cadenas, referencias de datos/código). Límite máximo: 10000.

Análisis de Flujo de Control

  • basic_blocks(addrs): Obtener bloques básicos con sucesores y predecesores.

Operaciones de Tipos

  • set_type(edits): Aplicar tipo(s) a funciones, globales, locales o variables de pila.
  • infer_types(addrs): Inferir tipos en dirección(es) usando Hex-Rays o heurísticas.

Operaciones de Exportación

  • export_funcs(addrs, format): Exportar función(es) en el formato especificado (json, c_header o prototypes).

Operaciones de Grafos

  • callgraph(roots, max_depth): Construir grafo de llamadas desde la(s) función(es) raíz con profundidad configurable.

Operaciones por Lotes

  • rename(batch): Operación unificada de renombrado por lotes para funciones, globales, locales y variables de pila (acepta un dict con claves opcionales func, data, local, stack).
  • patch(patches): Aplicar parches a múltiples secuencias de bytes a la vez.
  • put_int(items): Escribir valores enteros usando ty (i8/u64/i16le/i16be/etc).

Características clave:

  • API con seguridad de tipos: Todas las funciones usan parámetros fuertemente tipados con esquemas TypedDict para mejor soporte de IDE y salidas estructuradas para LLM
  • Diseño orientado a lotes: La mayoría de las operaciones aceptan tanto elementos individuales como listas
  • Manejo de errores consistente: Todas las operaciones por lotes devuelven [{..., error: null|string}, ...]
  • Paginación basada en cursor: Las funciones de búsqueda devuelven cursor: {next: offset} o {done: true} (límite predeterminado: 1000, máximo impuesto: 10000 para evitar desbordamiento de tokens)
  • Rendimiento: Las cadenas se almacenan en caché con invalidación basada en MD5 para evitar llamadas repetidas a build_strlist en proyectos grandes

Desarrollo

Agregar nuevas funciones es un proceso súper fácil y simplificado. Todo lo que tienes que hacer es agregar una nueva función @tool a los archivos de API modulares en src/ida_pro_mcp/ida_mcp/api_*.py y tu función estará disponible en el servidor MCP sin ningún código adicional. A continuación hay un video donde agrego la función get_metadata en menos de 2 minutos (incluyendo pruebas):

https://github.com/user-attachments/assets/951de823-88ea-4235-adcb-9257e316ae64

Para probar el servidor MCP en sí:

npx -y @modelcontextprotocol/inspector

Esto abrirá una interfaz web en http://localhost:5173 y te permitirá interactuar con las herramientas MCP para realizar pruebas.

Para las pruebas, creo un enlace simbólico al plugin de IDA y luego envío una solicitud JSON-RPC directamente a http://localhost:13337/mcp. Después de habilitar enlaces simbólicos puedes ejecutar el siguiente comando:

uv run ida-pro-mcp --install

Genera el registro de cambios de los commits directos a main:

git log --first-parent --no-merges 1.2.0..main "--pretty=- %s"