
KI-gestützter Reverse-Engineering-Assistent, der IDA Pro über MCP mit Sprachmodellen verbindet.
Einfacher MCP-Server für Vibe-Reversing in IDA Pro.
https://github.com/user-attachments/assets/6ebeaa92-a9db-43fa-b756-eececce2aca0
Die Binaries und der Prompt für das Video sind im Repository mcp-reversing-dataset verfügbar.
idapyswitch, um zur neuesten Python-Version zu wechselnida-pro-mcp --config aus, um die JSON-Konfiguration für deinen Client zu erhalten.Hinweis: Dafür muss idalib global aktiviert und uv installiert sein:
# 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"
So installierst du das neueste IDA Pro MCP in Claude Code:
claude plugin marketplace add mrexodia/claude-marketplace
claude plugin uninstall ida-pro-mcp@mrexodia
claude plugin install ida-pro-mcp@mrexodia
So installierst du das neueste IDA Pro MCP in Codex:
codex plugin marketplace add mrexodia/codex-marketplace
codex plugin remove ida-pro-mcp@mrexodia
codex plugin add ida-pro-mcp@mrexodia
Um das neueste IDA Pro MCP in Kimi Code zu installieren, führe diesen Slash-Befehl im Chat aus:
/plugins install https://github.com/mrexodia/ida-pro-mcp/tree/main
/reload
Dies installiert den idalib-MCP-Server und den idapython-Skill. Die Plugins werden nach $KIMI_CODE_HOME/plugins/managed/ kopiert, daher muss sich uv in deinem PATH befinden. Die erste Sitzung nach der Installation ist langsamer, da uv die Abhängigkeiten auflöst, bevor der Server antwortet.
Hinweis: Das MCP-Plugin wird nicht mehr empfohlen und wird schließlich als veraltet eingestuft werden. Verwende stattdessen idalib-mcp.
Wenn du den MCP-Server manuell über die IDA-GUI konfigurieren möchtest:
pip uninstall ida-pro-mcp
pip install https://github.com/mrexodia/ida-pro-mcp/archive/refs/heads/main.zip
Konfiguriere die MCP-Server und installiere das IDA-Plugin:
ida-pro-mcp --install
Wichtig: Stelle sicher, dass du IDA und deinen MCP-Client vollständig neu startest, damit die Installation wirksam wird. Manche Clients (wie Claude) laufen im Hintergrund und müssen über das Tray-Symbol beendet werden.
LLMs neigen zu Halluzinationen, und man muss beim Prompting sehr präzise sein. Beim Reverse Engineering ist besonders die Umrechnung zwischen Ganzzahlen und Bytes problematisch. Unten findest du einen minimalen Beispiel-Prompt. Wenn du mit einem anderen Prompt gute Ergebnisse erzielst, starte gerne eine Diskussion oder eröffne ein Issue:
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
Dieser Prompt war nur das erste Experiment. Bitte teile mit, wenn du Möglichkeiten gefunden hast, die Ausgabe zu verbessern!
Ein weiterer Prompt von @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
Live-Stream mit Diskussion über Prompting und einer Demonstration realer Malware-Analyse:
Große Sprachmodelle (LLMs) sind leistungsfähige Werkzeuge, aber sie können manchmal mit komplexen mathematischen Berechnungen Schwierigkeiten haben oder „Halluzinationen“ (das Erfinden von Fakten) aufweisen. Stelle sicher, dass das LLM das MCP-Tool int_convert verwendet, und für bestimmte Operationen benötigst du möglicherweise auch math-mcp.
Ein weiterer Punkt, den man im Hinterkopf behalten sollte: LLMs liefern bei verschleiertem (obfuskiertem) Code keine guten Ergebnisse. Bevor du versuchst, ein LLM zur Lösung des Problems einzusetzen, schau dich in der Binary um und verbringe etwas Zeit damit, die folgenden Dinge (automatisch) zu entfernen:
Du solltest außerdem ein Tool wie Lumina oder FLIRT verwenden, um den gesamten Open-Source-Bibliothekscode und die C++-STL aufzulösen; das verbessert die Genauigkeit weiter.
Du kannst einen SSE-Server ausführen, um dich wie folgt mit der Benutzeroberfläche zu verbinden:
uv run ida-pro-mcp --transport http://127.0.0.1:8744/sse
Nach der Installation von idalib kannst du auch einen Headless-MCP-Server ausführen. Du kannst mit einer anfänglichen Binary starten:
uv run idalib-mcp --host 127.0.0.1 --port 8745 path/to/executable
Oder starte ohne Binary und öffne später beliebige Dateien mit idb_open(...):
uv run idalib-mcp --host 127.0.0.1 --port 8745
Für stdio-basierte Clients verwende:
uv run idalib-mcp --stdio
Datenbank-Worker sind persistent: Jeder läuft als abgekoppelter Prozess, der den Supervisor, der ihn erzeugt hat, überlebt. Wenn ein neuer Supervisor (über stdio oder HTTP) idb_open für eine Binary aufruft, die bereits unter einem Worker auf diesem Host geöffnet ist, übernimmt der Supervisor diesen Worker transparent — es gibt keinen separaten „shared“-Modus, den man aktivieren müsste. Worker beenden sich selbst, wenn sie für einen Leerlaufzeitraum keine Anfrage erhalten haben.
Hinweis: Die idalib-Funktion wurde von Willi Ballenthin beigetragen.
idalib-mcp ist ein Supervisor, der jede geöffnete Datenbank in einem eigenen idalib-Workerprozess hält. Worker registrieren sich in einem host-lokalen Discovery-Verzeichnis und überleben den Supervisor, der sie erzeugt hat; jeder nachfolgende Supervisor, der denselben Pfad verwenden möchte, übernimmt den laufenden Worker. Ein Worker beendet sich selbst, wenn er für seine Idle-TTL (Standard: 1 Stunde) keine Anfrage erhalten hat. Rufe idb_close auf, um einen Worker vorzeitig freizugeben (wodurch ein Platz in Richtung --max-workers freigegeben wird); übernommene GUI-/Worker-Instanzen werden abgekoppelt, nicht beendet.
idb_open wählt das Backend über seinen mode-Parameter:
prefer_headless (Standard): startet einen idalib-Worker (oder übernimmt einen, der die Datei bereits geöffnet hat).force_headless: dasselbe, übernimmt aber niemals eine laufende GUI, selbst wenn eine die Datei geöffnet hat.prefer_gui: übernimmt eine laufende GUI für die Datei; andernfalls wird ein idalib-Worker gestartet.force_gui: übernimmt eine laufende GUI für die Datei; andernfalls wird ein neuer IDA-GUI-Prozess gestartet.Jeder Tool-Aufruf muss ein explizites database-Argument enthalten. Es gibt keine implizite „aktuelle Datenbank“ — Aufrufer benennen die Sitzung, auf der sie arbeiten möchten.
uv run idalib-mcp --stdio --max-workers 4
Typischer Ablauf:
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 muss die von idb_open zurückgegebene Sitzungs-ID sein (oder die in idb_list angezeigte); Dateinamen und Pfade werden nicht akzeptiert.
idb_open(input_path, mode="prefer_headless", run_auto_analysis=True, build_caches=True, init_hexrays=True, preferred_session_id=""): Öffnet eine Binary, wärmt Subsysteme auf (Strings-Cache, Hex-Rays) und gibt ihre Sitzungs-ID zurück. Wenn für diesen Pfad bereits ein Worker oder eine GUI auf dem Host läuft, wird diese Instanz übernommen und preferred_session_id ignoriert.idb_list(): Listet offene Sitzungen und laufende IDA-GUI-Instanzen auf. Jeder Eintrag hat adopted (True, wenn dieser Supervisor sie verwaltet, False für GUIs/Worker, die entdeckt, aber noch nicht über idb_open geöffnet wurden), backend (worker oder gui), is_active und Prozess-IDs.idb_close(database, save=True): Speichert (optional), meldet die Sitzung ab und beendet den zugehörigen Worker, wodurch ein Platz in Richtung --max-workers freigegeben wird. Übernommene GUI-/Worker-Instanzen werden abgekoppelt, nicht beendet.Worker-Optionen:
--max-workers N: maximale Anzahl gleichzeitiger Datenbank-Worker (0 = unbegrenzt, Standard 4).IDA_MCP_MAX_WORKERS: Umgebungsstandard für --max-workers.Resources repräsentieren durchsuchbaren Zustand (schreibgeschützte Daten) gemäß der MCP-Philosophie.
Zentraler IDB-Zustand:
ida://idb/metadata – IDB-Dateiinformationen (Pfad, Architektur, Basis, Größe, Hashes)ida://idb/segments – Speichersegmente mit Berechtigungenida://idb/entrypoints – Einstiegspunkte (main, TLS-Callbacks usw.)UI-Zustand:
ida://cursor – Aktuelle Cursorposition und Funktionida://selection – Aktueller AuswahlbereichTypinformationen:
ida://types – Alle lokalen Typenida://structs – Alle Strukturen/Unionsida://struct/{name} – Strukturdefinition mit FeldernNachschlagen:
ida://import/{name} – Importdetails nach Nameida://export/{name} – Exportdetails nach Nameida://xrefs/from/{addr} – Querverweise ab Adresselookup_funcs(queries): Ruft Funktion(en) per Adresse oder Name ab (automatische Erkennung, akzeptiert Liste oder kommagetrennten String).int_convert(inputs): Konvertiert Zahlen in verschiedene Formate (dezimal, hex, Bytes, ASCII, binär).list_funcs(queries): Listet Funktionen auf (paginiert, gefiltert).list_globals(queries): Listet globale Variablen auf (paginiert, gefiltert).imports(offset, count): Listet alle importierten Symbole mit Modulnamen auf (paginiert).decompile(addr): Dekompiliert die Funktion an der angegebenen Adresse.disasm(addr): Disassembliert die Funktion mit vollständigen Details (Argumente, Stack-Frame usw.).xrefs_to(addrs): Ruft alle Querverweise auf die Adresse(n) ab.xrefs_to_field(queries): Ruft Querverweise auf bestimmte Strukturfelder ab.callees(addrs): Ruft Funktionen ab, die von der/den Funktion(en) an den Adresse(n) aufgerufen werden.add_bookmark(addr, name, prefix): Fügt ein IDA-Lesezeichen an einer Adresse hinzu oder ersetzt es; setze prefix="" für kein Präfix.set_comments(items): Setzt Kommentare an Adresse(n) sowohl in der Disassembly- als auch in der Dekompilierer-Ansicht.patch_asm(items): Patcht Assembler-Anweisungen an Adresse(n).declare_type(decls): Deklariert C-Typ(en) in der lokalen Typbibliothek.define_func(items): Definiert Funktion(en) an Adresse(n). Optional end für explizite Grenzen angeben.define_code(items): Konvertiert Bytes in Code-Anweisung(en) an Adresse(n).undefine(items): Macht Element(e) an Adresse(n) wieder undefiniert und wandelt sie zurück in rohe Bytes. Optional end oder size angeben.get_bytes(addrs): Liest rohe Bytes an Adresse(n).get_int(queries): Liest Ganzzahlwerte mit ty (i8/u64/i16le/i16be usw.).get_string(addrs): Liest nullterminierte Zeichenkette(n).get_global_value(queries): Liest Wert(e) globaler Variablen per Adresse oder Name (automatische Erkennung, Compile-Zeit-Werte).stack_frame(addrs): Ruft Stack-Frame-Variablen für Funktion(en) ab.declare_stack(items): Erstellt Stack-Variable(n) an angegebenen Offsets.delete_stack(items): Löscht Stack-Variable(n) per Name.read_struct(queries): Liest Strukturfeldwerte an bestimmten Adresse(n).search_structs(filter): Durchsucht Strukturen nach Namensmuster.Debugger-Tools sind standardmäßig ausgeblendet. Aktiviere sie mit dem Abfrageparameter ?ext=dbg:
http://127.0.0.1:13337/mcp?ext=dbg
Steuerung:
dbg_start(): Startet den Debugger-Prozess.dbg_exit(): Beendet den Debugger-Prozess.dbg_continue(): Setzt die Ausführung fort.dbg_run_to(addr): Führt bis zur Adresse aus.dbg_step_into(): Einzelschritt in die Anweisung.dbg_step_over(): Einzelschritt über die Anweisung.Haltepunkte:
dbg_bps(): Listet alle Haltepunkte auf.dbg_add_bp(addrs): Fügt Haltepunkt(e) hinzu.dbg_delete_bp(addrs): Löscht Haltepunkt(e).dbg_toggle_bp(items): Aktiviert/deaktiviert Haltepunkt(e).Register:
dbg_regs(): Alle Register, aktueller Thread.dbg_regs_all(): Alle Register, alle Threads.dbg_regs_remote(tids): Alle Register, bestimmte Thread(s).dbg_gpregs(): GP-Register, aktueller Thread.dbg_gpregs_remote(tids): GP-Register, bestimmte Thread(s).dbg_regs_named(names): Benannte Register, aktueller Thread.dbg_regs_named_remote(tid, names): Benannte Register, bestimmter Thread.Stack & Speicher:
dbg_stacktrace(): Aufrufstapel mit Modul-/Symbolinformationen.dbg_read(regions): Liest Speicher aus dem zu debuggenden Prozess.dbg_write(regions): Schreibt Speicher in den zu debuggenden Prozess.py_eval(code): Führt beliebigen Python-Code im IDA-Kontext aus (gibt ein dict mit result/stdout/stderr zurück, unterstützt Jupyter-artige Auswertung).analyze_funcs(addrs): Umfassende Funktionsanalyse (Dekompilierung, Assembly, Xrefs, Callees, Caller, Strings, Konstanten, Basisblöcke).find_regex(queries): Durchsucht Zeichenketten mit case-insensitiver Regex (paginiert).find_bytes(patterns, limit=1000, offset=0): Findet Byte-Muster in der Binary (z. B. "48 8B ?? ??"). Max. Limit: 10000.find_insns(sequences, limit=1000, offset=0): Findet Anweisungssequenz(en) im Code. Max. Limit: 10000.find(type, targets, limit=1000, offset=0): Erweiterte Suche (unmittelbare Werte, Zeichenketten, Daten-/Code-Referenzen). Max. Limit: 10000.basic_blocks(addrs): Ruft Basisblöcke mit Nachfolgern und Vorgängern ab.set_type(edits): Wendet Typ(en) auf Funktionen, Globals, Locals oder Stack-Variablen an.infer_types(addrs): Leitet Typen an Adresse(n) mithilfe von Hex-Rays oder Heuristiken ab.export_funcs(addrs, format): Exportiert Funktion(en) im angegebenen Format (json, c_header oder Prototypen).callgraph(roots, max_depth): Erstellt einen Aufrufgraphen ausgehend von Wurzelfunktion(en) mit konfigurierbarer Tiefe.rename(batch): Einheitliche Batch-Umbenennungsoperation für Funktionen, Globals, Locals und Stack-Variablen (akzeptiert ein Dict mit optionalen Schlüsseln func, data, local, stack).patch(patches): Patcht mehrere Byte-Sequenzen auf einmal.put_int(items): Schreibt Ganzzahlwerte mit ty (i8/u64/i16le/i16be usw.).Wichtige Funktionen:
[{..., error: null|string}, ...] zurückcursor: {next: offset} oder {done: true} zurück (Standard-Limit: 1000, erzwungenes Maximum: 10000, um Token-Überlauf zu verhindern)build_strlist-Aufrufe in großen Projekten zu vermeidenDas Hinzufügen neuer Funktionen ist ein super einfacher und schlanker Prozess. Du musst nur eine neue @tool-Funktion zu den modularen API-Dateien in src/ida_pro_mcp/ida_mcp/api_*.py hinzufügen, und deine Funktion ist ohne weiteren Boilerplate-Code im MCP-Server verfügbar! Unten ist ein Video, in dem ich die get_metadata-Funktion in weniger als 2 Minuten hinzufüge (inklusive Testen):
https://github.com/user-attachments/assets/951de823-88ea-4235-adcb-9257e316ae64
Um den MCP-Server selbst zu testen:
npx -y @modelcontextprotocol/inspector
Dadurch wird eine Weboberfläche unter http://localhost:5173 geöffnet, über die du für Tests mit den MCP-Tools interagieren kannst.
Für Tests erstelle ich einen symbolischen Link zum IDA-Plugin und sende dann eine JSON-RPC-Anfrage direkt an http://localhost:13337/mcp. Nach dem Aktivieren symbolischer Links kannst du den folgenden Befehl ausführen:
uv run ida-pro-mcp --install
Erzeuge das Änderungsprotokoll der direkten Commits auf main:
git log --first-parent --no-merges 1.2.0..main "--pretty=- %s"
idb_save(session_id, path=""): Speichert die IDB einer Sitzung auf der Festplatte. Wird als reguläres Worker-Tool weitergeleitet (database=<id> eingefügt) — gleiche Signatur in beiden Backends.server_health(database=<id>) aufrufen (weitergeleitet). idb_list() meldet is_active vom TCP/RPC-Probing des Supervisors.