Ghidra RE Assistant
You are performing reverse engineering tasks using Ghidra via the GhidraMCP server. The user's request: $ARGUMENTS
Ghidra MCP Connectivity
Architecture
The GhidraMCP stack has three layers:
- MCP bridge (
bridge_mcp_ghidra.py) — translates MCP protocol to HTTP calls. Providesmcp__ghidra__*tools. - HTTP server (port 8089) — REST API exposed by either the GUI plugin or the headless server.
- Ghidra backend — GUI (with plugin) or headless (no GUI).
The MCP bridge talks to port 8089 regardless of which backend serves it.
Always prefer mcp__ghidra__* tools over raw curl — they provide structured parameters, validation, and discoverability.
Fall back to curl only if the MCP bridge is unavailable.
Headless Mode (preferred — fully autonomous)
The bridge can launch the headless Ghidra backend with --ghidra-home:
bridge_mcp_ghidra.py --ghidra-home /path/to/ghidra_12.0.3_PUBLIC
This starts the headless server (no binary loaded) and registers all MCP tools,
including headless-specific tools like load_program and close_program.
The server is cleaned up automatically on exit.
Optional: --java-opts "-Xmx8g" for large binaries.
GUI Backend (alternative)
If the Ghidra GUI is already running with the MCP plugin and a program loaded in CodeBrowser, the bridge connects to it the same way — no special flags needed.
Verifying Connection
mcp__ghidra__check_connection()
Headless Workflow (load → analyze → work)
In headless mode, no binary is loaded at startup. You must load one explicitly:
# Step 1: Load a binary (absolute path)
mcp__ghidra__load_program(file="/path/to/binary.exe")
# Step 2: Switch to the loaded program (makes it the active context)
mcp__ghidra__switch_program(name="binary.exe")
# Step 3: Run auto-analysis (required before decompilation works)
mcp__ghidra__run_analysis(program="binary.exe")
# Step 4: Now all other tools work — list functions, decompile, rename, etc.
mcp__ghidra__list_functions(program="binary.exe")
When done, unload with:
mcp__ghidra__close_program(name="binary.exe")
Key Operations (MCP Tools)
Always use mcp__ghidra__* tools. These work identically whether the backend is GUI or headless.
Listing Functions
mcp__ghidra__list_functions(program="binary.exe")
Decompiling
mcp__ghidra__decompile_function(name="FUN_1000_065c", program="binary.exe")
# For large functions, paginate:
mcp__ghidra__decompile_function(name="...", offset=0, limit=200, program="...")
# After type changes, force re-decompile:
mcp__ghidra__decompile_function(name="...", force=true, program="...")
Renaming Functions
mcp__ghidra__rename_function_by_address(function_address="0x1065c", new_name="check_protection", program="...")
Cross-References
mcp__ghidra__get_function_callers(name="...", program="...")
mcp__ghidra__get_function_callees(name="...", program="...")
Disassembly
mcp__ghidra__disassemble_function(address="0x1065c", program="...")
Strings
mcp__ghidra__list_strings(filter="*", program="...", limit=100)
Program Metadata
mcp__ghidra__get_current_program_info(program="...")
Saving (GUI mode only — headless is in-memory)
mcp__ghidra__save_program(program="...")
Curl Fallback
If MCP tools are unavailable (bridge down), the same endpoints are accessible via HTTP:
curl -s "http://127.0.0.1:8089/list_functions"
curl -s "http://127.0.0.1:8089/decompile_function?address=FUN_name"
curl -s "http://127.0.0.1:8089/rename_function?old_name=X&new_name=Y"
Address Formats
Different Ghidra tools expect different address formats. This is a common source of errors.
- Function names (e.g.,
FUN_1000_065c,main,entry): Always work for decompilation. - Flat hex (e.g.,
0x1065c,0x401000): Required for rename-by-address, comments, type application. - Segmented (e.g.,
1000:065c): Display-only in function listings. Do NOT pass to tools — they will reject it.
Segmented to Flat Conversion (16-bit real mode)
flat = (segment << 4) + offset
Example: 1000:065c → (0x1000 * 16) + 0x065c = 0x1065c
For 32/64-bit PE binaries, addresses are already flat (e.g., 0x00401000).
Tips
- Batch operations: When renaming many functions, batch them to avoid excessive round-trips.
- Large functions: Use pagination (offset/limit) for functions with hundreds of lines.
- Force re-decompile: After changing types, names, or signatures, always re-decompile with
force=trueto see the effect. - Headless is stateless: The headless server doesn't persist changes to disk. Export/document findings in project files.
- Port conflicts: If port 8089 is busy, kill stale processes:
pkill -f GhidraMCPHeadless; sleep 3 - The decompiler is only as good as the analysis: If output looks wrong, check if the function boundaries are correct, if the calling convention is right, and if types have been applied.