# Kawaiidra MCP > A Ghidra MCP Server for Claude Code - Binary Analysis Made Adorable [![Ghidra](https://img.shields.io/badge/Ghidra-MCP-red)](https://ghidra-sre.org/) [![MCP](https://img.shields.io/badge/Model%20Context%20Protocol-Server-blue)](https://modelcontextprotocol.io/) [![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) **Keywords:** `ghidra` `mcp` `ghidra-mcp` `model-context-protocol` `binary-analysis` `reverse-engineering` `decompiler` `disassembler` `claude` `claude-code` A general-purpose **Ghidra MCP server** that brings the power of Ghidra's headless analyzer and decompiler to Claude Code and other MCP-compatible AI assistants. ## Features **266 tools.** Kawaiidra covers every endpoint of [bethington/ghidra-mcp](https://github.com/bethington/ghidra-mcp) v7.0.0 (209/209, see [PARITY.md](PARITY.md)) and adds Apple/iOS/kernel, JNI and other analysis tools it does not have. Parity tools live in `src/kawaiidra_mcp/parity/` and cover: program options and property maps, memory blocks, advanced data types, globals auditing, function tags and bulk variable editing, P-code and dataflow, the documentation workflow with cross-binary matching, P-code emulation, project/.gzf/.gar lifecycle, a session "current program", GUI-mode debugger tools, and Ghidra Server version control. Smoke results: [VALIDATION_REPORT.md](VALIDATION_REPORT.md). ### Core Features - **Analyze any binary**: PE (Windows), ELF (Linux), Mach-O (macOS), and raw firmware - **Decompile functions**: Get C code from compiled binaries - **Disassembly**: View assembly listings - **Cross-references**: Find function callers and callees - **String analysis**: Search and list strings in binaries - **Export results**: Save analysis to JSON for further processing - **Multi-project support**: Organize analyses into separate Ghidra projects ### Advanced Analysis (LLM-Optimized) - **Call graphs**: Extract hierarchical function relationships - **Library detection**: Identify OpenSSL, zlib, Qt, Windows API, and more - **Semantic search**: Find code by behavior (file I/O, network, crypto, memory ops) - **Context extraction**: Get functions with all dependencies for complete understanding - **Data structures**: Extract struct/class definitions and enums - **Control flow graphs**: Analyze function logic with basic blocks - **Vulnerability detection**: Pattern-based security analysis with CWE mapping - **Function similarity**: Find code reuse based on structural fingerprints - **Smart naming**: Suggest better symbol names based on usage patterns ### iOS Security Research Tools - **KPP/KTRR detection**: Identify kernel patch protection mechanisms - **Mach trap analysis**: Analyze syscall tables and trap handlers - **PAC gadget finder**: Locate pointer authentication gadgets for ARM64e - **Sandbox analysis**: Examine sandbox operations and policy checks - **IOKit class finder**: Map IOKit class hierarchies and user clients - **Entitlement checks**: Detect entitlement validation code paths - **Kernel symbols**: Find and analyze XNU kernel symbols - **Mach port analysis**: Analyze IPC and port operations ### Android & Mobile Analysis Tools - **Crypto constants**: Find AES S-boxes, CRC tables, and crypto magic numbers - **JNI methods**: Analyze JNI_OnLoad, Java_* exports, and RegisterNatives calls - **API endpoints**: Extract URLs, hostnames, IP addresses, and API paths - **Hardcoded secrets**: Find API keys, tokens, passwords, and credentials - **Binary comparison**: Diff two binaries to find added/removed/modified functions ### GUI Mode & Context Tracking - **Dual-mode support**: Works in both headless and GUI-connected modes - **Context tracking**: Automatically tracks current address/function from tool operations - **GUI integration**: Connect to running Ghidra GUI via ghidra_bridge for real-time selection - **Cursor-aware analysis**: Get/set current address and function for workflow continuity ## Performance Kawaiidra supports two execution modes: | Mode | Speed | Setup | |------|-------|-------| | **JPype Bridge** (default) | ~1-50ms per call | Requires Java JDK 17+ | | Subprocess (fallback) | ~5-15s per call | Works out of the box | The JPype bridge keeps a JVM running in-process, eliminating the ~5-15 second startup overhead of spawning `analyzeHeadless` for each operation. **This is 100-1000x faster for sequential operations.** ``` ┌────────────────────────────────────────────────────┐ │ 10 function decompilations: │ │ │ │ Subprocess mode: ~2-3 minutes │ │ JPype Bridge: ~0.5 seconds │ └────────────────────────────────────────────────────┘ ``` ## Requirements - **Python 3.10+** - **Ghidra 11.0+** (tested with 11.x and 12.0, fully compatible with Ghidra 12.0) - **MCP Python package**: `pip install mcp` ### For Maximum Performance (Recommended) - **Java JDK 17+** (for JPype bridge) - **JPype1**: `pip install JPype1` ## Quick Start ### 1. Install Ghidra **Option A: Homebrew (macOS/Linux) - Recommended** ```bash # macOS brew install ghidra # Linux (Homebrew) brew install ghidra ``` **Option B: Manual Installation** Download Ghidra from [ghidra-sre.org](https://ghidra-sre.org/) and extract it. ### 2. Install Dependencies ```bash cd kawaiidra-mcp pip install -r requirements.txt ``` ### 2b. Enable Fast Mode (Recommended) For 100-1000x faster operations, install JPype and ensure Java is available: ```bash # Install JPype pip install JPype1 # Verify Java JDK 17+ is installed java -version ``` **Installing Java if needed:** ```bash # macOS brew install openjdk@17 # Ubuntu/Debian sudo apt install openjdk-17-jdk # Windows (winget) winget install EclipseAdoptium.Temurin.17.JDK ``` The bridge auto-enables when both JPype and Java are available. Use the `bridge_status` tool to verify. ### 3. Configure Ghidra Path (Optional) The server auto-detects Ghidra installations in common locations. If auto-detection fails or you want to use a specific version, set `GHIDRA_INSTALL_DIR`: **Homebrew installations (usually auto-detected):** ```bash # macOS (Apple Silicon) export GHIDRA_INSTALL_DIR=/opt/homebrew # macOS (Intel) export GHIDRA_INSTALL_DIR=/usr/local # Linux export GHIDRA_INSTALL_DIR=/home/linuxbrew/.linuxbrew ``` **Manual installations:** ```bash # Windows set GHIDRA_INSTALL_DIR=C:\ghidra_11.2_PUBLIC # Linux/macOS export GHIDRA_INSTALL_DIR=/opt/ghidra export GHIDRA_INSTALL_DIR=/Applications/ghidra_11.2_PUBLIC ``` ### 4. Use with Claude Code Open the `kawaiidra-mcp` folder in Claude Code. The MCP server will automatically load from `.mcp.json`. Or add to your Claude Code config: ```json { "mcpServers": { "kawaiidra": { "type": "stdio", "command": "python", "args": ["/path/to/kawaiidra-mcp/run_server.py"], "env": { "GHIDRA_INSTALL_DIR": "/path/to/ghidra" } } } } ``` ### 5. Analyze a Binary 1. Place your binary in the `binaries/` folder, or use an absolute path 2. Use the `analyze_binary` tool to import and analyze 3. Use other tools to explore the analysis ## Available Tools ### Core Analysis Tools | Tool | Description | |------|-------------| | `analyze_binary` | Import and analyze a binary file | | `list_analyzed_binaries` | List binaries in current project | | `list_functions` | List all functions in a binary | | `find_functions` | Search functions by name pattern | | `get_function_decompile` | Decompile function to C code | | `get_function_disassembly` | Get assembly listing | | `get_function_xrefs` | Get cross-references to/from function | | `search_strings` | Search strings by pattern | | `list_strings` | List all defined strings | | `get_binary_info` | Get binary metadata (arch, format, etc.) | | `get_memory_map` | Get memory segments/sections | | `export_analysis` | Export analysis to JSON file | | `cache_stats` | View cache hit rate and performance statistics | | `cache_clear` | Clear cached results | | `bridge_status` | Check if fast JPype bridge mode is active | | `generate_report` | Generate comprehensive binary analysis report | | `list_exports` | List exported functions and symbols | | `list_imports` | List imported functions from external libraries | | `list_data_items` | List defined data labels and values | | `list_namespaces` | List all namespaces and classes | | `rename_function` | Rename a function in the analysis | | `rename_data` | Rename a data label at an address | | `rename_variable` | Rename a local variable within a function | | `set_comment` | Add comments at specific addresses | | `set_function_prototype` | Set a function's signature | | `set_local_variable_type` | Set the type of a local variable | ### Advanced Analysis Tools (LLM-Optimized) | Tool | Description | |------|-------------| | `get_call_graph` | Extract call hierarchy showing function relationships | | `detect_libraries` | Identify standard libraries, frameworks, and third-party code | | `semantic_code_search` | Search for code by behavior (file I/O, network, crypto, etc.) | | `get_function_with_context` | Get function with all dependencies for complete LLM understanding | | `get_data_structures` | Extract struct/class definitions and data types | | `get_control_flow_graph` | Extract CFG with basic blocks for logic flow analysis | | `detect_vulnerabilities` | Detect security vulnerabilities using pattern analysis | | `find_similar_functions` | Find functions similar to a reference based on structure | | `get_annotated_disassembly` | Get richly annotated disassembly with xrefs and comments | | `suggest_symbol_names` | Suggest better variable/function names based on usage | ### iOS Security Research Tools | Tool | Description | |------|-------------| | `detect_kpp_ktrr` | Detect KPP, KTRR, PPL, and AMFI kernel protections | | `analyze_mach_traps` | Analyze Mach trap table and syscall handlers | | `find_pac_gadgets` | Find PAC signing/authentication gadgets for ARM64e | | `analyze_sandbox_ops` | Analyze sandbox operations and policy enforcement | | `find_iokit_classes` | Find IOKit classes, vtables, and user clients | | `detect_entitlement_checks` | Detect entitlement validation and AMFI checks | | `find_kernel_symbols` | Find kernel symbols with pattern matching | | `analyze_mach_ports` | Analyze Mach port operations and IPC patterns | ### Android & Mobile Analysis Tools | Tool | Description | |------|-------------| | `find_crypto_constants` | Find AES S-boxes, CRC tables, and crypto magic numbers | | `analyze_jni_methods` | Find JNI methods (JNI_OnLoad, Java_*, RegisterNatives) | | `extract_api_endpoints` | Extract URLs, hostnames, IP addresses, and API paths | | `find_hardcoded_secrets` | Find API keys, tokens, passwords, and credentials | | `compare_binaries` | Compare two binaries to find added/removed/modified functions | ### GUI/Context Tools | Tool | Description | |------|-------------| | `get_current_address` | Get current address (from GUI cursor or context tracker) | | `get_current_function` | Get current function (from GUI cursor or context tracker) | | `set_current_address` | Set current address context for headless workflows | | `set_current_function` | Set current function context for headless workflows | | `get_current_selection` | Get selection range from Ghidra GUI (GUI mode only) | | `gui_status` | Check GUI mode connection status and context tracker state | ## Tool Examples ### Analyze a Windows Executable ``` analyze_binary file_path: "C:\path\to\target.exe" ``` ### Analyze Raw Firmware ``` analyze_binary file_path: "firmware.bin" processor: "ARM:LE:32:v7" base_address: "0x08000000" ``` ### Decompile a Function ``` get_function_decompile binary_name: "target.exe" function_name: "main" ``` ### Find Functions by Pattern ``` find_functions pattern: "crypt" binary_name: "target.exe" ``` ### Get Cross-References ``` get_function_xrefs binary_name: "target.exe" function_name: "main" direction: "from" ``` ### Get Call Graph ``` get_call_graph binary_name: "target.exe" function_name: "main" depth: 3 direction: "callees" ``` ### Detect Libraries ``` detect_libraries binary_name: "target.exe" detailed: true ``` ### Search for Crypto Code ``` semantic_code_search binary_name: "target.exe" pattern: "crypto" ``` ### Get Function with Full Context ``` get_function_with_context binary_name: "target.exe" function_name: "process_data" include_callees: true include_data_types: true ``` ### Detect Vulnerabilities ``` detect_vulnerabilities binary_name: "target.exe" severity: "high" ``` ### Get Control Flow Graph ``` get_control_flow_graph binary_name: "target.exe" function_name: "main" include_instructions: true ``` ### Find Similar Functions ``` find_similar_functions binary_name: "target.exe" function_name: "encrypt_block" threshold: 0.7 ``` ### Generate Comprehensive Report ``` generate_report binary_name: "target.exe" depth: "full" ``` Depth options: `quick` (metadata only), `standard` (+ functions/strings), `full` (+ decompilation), `exhaustive` (everything) ### Detect Kernel Protections (iOS) ``` detect_kpp_ktrr binary_name: "kernelcache" ``` ### Analyze Mach Traps (iOS/macOS) ``` analyze_mach_traps binary_name: "kernelcache" include_handlers: true ``` ### Find PAC Gadgets (ARM64e) ``` find_pac_gadgets binary_name: "kernelcache" gadget_type: "signing" max_results: 50 ``` ### Find IOKit Classes ``` find_iokit_classes binary_name: "IOKit.kext" include_vtables: true include_user_clients: true ``` ### Detect Entitlement Checks ``` detect_entitlement_checks binary_name: "amfid" include_context: true ``` ### Find Kernel Symbols ``` find_kernel_symbols binary_name: "kernelcache" pattern: "proc_" symbol_type: "function" ``` ### Analyze Mach Ports ``` analyze_mach_ports binary_name: "launchd" include_dangerous: true ``` ### Find Crypto Constants ``` find_crypto_constants binary_name: "libcrypto.so" include_context: true ``` ### Analyze JNI Methods ``` analyze_jni_methods binary_name: "libnative.so" include_signatures: true ``` ### Extract API Endpoints ``` extract_api_endpoints binary_name: "app.so" include_params: true ``` ### Find Hardcoded Secrets ``` find_hardcoded_secrets binary_name: "libnative.so" sensitivity: "high" ``` ### Compare Binaries ``` compare_binaries binary_name_a: "app_v1.so" binary_name_b: "app_v2.so" include_similarity: true ``` ### Get Current Address (Context-Aware) ``` get_current_address ``` Returns the current address from: - Ghidra GUI (if GUI mode enabled and connected) - Context tracker (last decompiled/analyzed address) ### Get Current Function ``` get_current_function ``` Returns the current function from: - Ghidra GUI cursor position - Context tracker (last decompiled function) ### Set Current Address (Headless Workflow) ``` set_current_address address: "0x401000" binary_name: "target.exe" ``` ### Check GUI Status ``` gui_status ``` Shows GUI mode configuration, connection status, and context tracker state. ## Configuration ### Environment Variables | Variable | Description | Default | |----------|-------------|---------| | `GHIDRA_INSTALL_DIR` | Path to Ghidra installation | Auto-detected | | `KAWAIIDRA_PROJECT_DIR` | Where Ghidra projects are stored | `./projects` | | `KAWAIIDRA_BINARIES_DIR` | Where input binaries are stored | `./binaries` | | `KAWAIIDRA_EXPORTS_DIR` | Where exports are written | `./exports` | | `KAWAIIDRA_LOG_DIR` | Where logs are written | `./logs` | | `KAWAIIDRA_TIMEOUT` | Analysis timeout in seconds | `300` | | `KAWAIIDRA_DECOMPILE_TIMEOUT` | Decompile timeout in seconds | `180` | | `KAWAIIDRA_MAX_MEMORY` | JVM max memory | `4G` | ### Cache Settings | Variable | Description | Default | |----------|-------------|---------| | `KAWAIIDRA_CACHE_ENABLED` | Enable result caching | `true` | | `KAWAIIDRA_CACHE_DIR` | Cache storage location | `~/.kawaiidra/cache` | | `KAWAIIDRA_CACHE_MAX_SIZE_MB` | Maximum cache size | `500` | ### JPype Bridge Settings (Performance) | Variable | Description | Default | |----------|-------------|---------| | `KAWAIIDRA_USE_BRIDGE` | Enable fast JPype bridge | `true` | | `KAWAIIDRA_BRIDGE_CACHE_PROGRAMS` | Keep programs loaded in memory | `true` | | `KAWAIIDRA_BRIDGE_MAX_PROGRAMS` | Max programs to cache | `5` | ### GUI Mode Settings | Variable | Description | Default | |----------|-------------|---------| | `KAWAIIDRA_GUI_MODE` | Enable GUI mode (connect to running Ghidra) | `false` | | `KAWAIIDRA_GUI_HOST` | Host for ghidra_bridge connection | `127.0.0.1` | | `KAWAIIDRA_GUI_PORT` | Port for ghidra_bridge connection | `4768` | | `KAWAIIDRA_GUI_TIMEOUT` | Timeout for GUI bridge operations (seconds) | `10` | #### Enabling GUI Mode GUI mode allows Kawaiidra to connect to a running Ghidra GUI instance, enabling real-time access to cursor position and selection. This is useful for interactive analysis workflows. **Setup Steps:** 1. **Enable GUI mode:** ```bash # Windows set KAWAIIDRA_GUI_MODE=true # Linux/macOS export KAWAIIDRA_GUI_MODE=true ``` 2. **Install ghidra_bridge (optional dependency):** ```bash pip install ghidra_bridge ``` 3. **Install the bridge server in Ghidra:** ```bash python -m kawaiidra_mcp.install_bridge_server ~/ghidra_scripts ``` Use this instead of `ghidra_bridge.install_server`: it works without `pkg_resources` and marks the server scripts `# @runtime Jython`, which Ghidra 12 requires (otherwise it tries to run them with PyGhidra). 4. **Start the bridge server in Ghidra:** - In Ghidra: `Tools > Ghidra Bridge > Run in Background` - Or run `ghidra_bridge_server_background.py` from Script Manager - For the `debugger_*` tools, run it from the **Debugger** tool so its trace/breakpoint/launcher services are available 5. **Verify connection:** ``` gui_status ``` **Note:** Even without GUI mode enabled, context tracking works in headless mode. The `get_current_address` and `get_current_function` tools automatically track context from your tool operations (e.g., last decompiled function becomes the current function). ## Testing Kawaiidra includes a comprehensive test suite with 166 tests covering all major modules: ```bash # Run all tests uv run pytest tests/ -v # Run specific test file uv run pytest tests/test_cache.py -v ``` | Test File | Tests | Coverage | |-----------|-------|----------| | `test_cache.py` | 57 | Cache operations, TTL, LRU eviction | | `test_index_parsing.py` | 30 | Ghidra index parsing, regex patterns | | `test_config.py` | 26 | Configuration, env vars, path detection | | `test_mcp_tools.py` | 22 | Tool definitions, schemas, utilities | | `test_mcp_handlers.py` | 22 | MCP handler integration | | `test_bridge.py` | 17 | Bridge availability, backend operations | ## Directory Structure ``` kawaiidra-mcp/ ├── .mcp.json # MCP server configuration ├── README.md # This file ├── requirements.txt # Python dependencies ├── run_server.py # Server entry point ├── src/ │ └── kawaiidra_mcp/ │ ├── server.py # MCP server implementation │ ├── config.py # Configuration management │ ├── cache.py # Result caching system │ ├── bridge/ # JPype bridge for fast execution │ │ ├── __init__.py │ │ ├── jpype_bridge.py # JVM lifecycle & Ghidra API │ │ └── backend.py # High-level backend abstraction │ └── scripts/ # Ghidra headless scripts (fallback) ├── tests/ # Unit test suite (166 tests) ├── projects/ # Ghidra project storage (gitignored) ├── binaries/ # Input binaries (gitignored) ├── exports/ # Exported analysis (gitignored) └── logs/ # Runtime logs (gitignored) ``` ## Supported Binary Formats | Format | Extensions | Auto-detected | |--------|------------|---------------| | PE (Windows) | .exe, .dll, .sys | Yes | | ELF (Linux) | .so, .o, (none) | Yes | | Mach-O (macOS) | .dylib, (none) | Yes | | Raw Binary | .bin, .fw | No (specify processor) | ## Common Processor IDs For raw binaries, specify the processor manually: | Architecture | Processor ID | |--------------|--------------| | x86 32-bit | `x86:LE:32:default` | | x86 64-bit (AMD64) | `x86:LE:64:default` | | ARM 32-bit | `ARM:LE:32:v7` | | ARM 64-bit (AArch64) | `AARCH64:LE:64:default` | | MIPS 32-bit BE | `MIPS:BE:32:default` | | MIPS 32-bit LE | `MIPS:LE:32:default` | | PowerPC 32-bit | `PowerPC:BE:32:default` | | RISC-V 32-bit | `RISCV:LE:32:default` | ## Troubleshooting ### "Ghidra not found" Ensure `GHIDRA_INSTALL_DIR` points to a valid Ghidra installation with `support/analyzeHeadless` script. ### "MCP SDK not installed" ```bash pip install mcp ``` ### Analysis Times Out Increase timeout with environment variable: ```bash # Windows set KAWAIIDRA_TIMEOUT=600 # Linux/macOS export KAWAIIDRA_TIMEOUT=600 ``` ### Large Binary Memory Issues Increase JVM memory: ```bash set KAWAIIDRA_MAX_MEMORY=8G ``` ### Function Not Found - Ensure the binary has been analyzed first with `analyze_binary` - Try using the function's address instead of name (e.g., `0x401000`) - Check if the function is in a different binary in the project ### JPype Bridge Not Starting Check bridge status: ``` bridge_status ``` If bridge shows as unavailable: 1. **Install JPype:** ```bash pip install JPype1 ``` 2. **Install Java JDK 17+:** ```bash # macOS brew install openjdk@17 # Ubuntu/Debian sudo apt install openjdk-17-jdk ``` 3. **Verify Java is in PATH:** ```bash java -version ``` 4. **Check JAVA_HOME (if needed):** ```bash export JAVA_HOME=/path/to/jdk ``` The server automatically falls back to subprocess mode if JPype is unavailable. ### Bridge Mode Slower Than Expected - First call per binary takes 2-5s (program loading) - Subsequent calls should be ~1-50ms - Use `bridge_status` to verify bridge is active - Check `KAWAIIDRA_BRIDGE_CACHE_PROGRAMS=true` is set ## Analysis Reports Binary analysis reports generated using Kawaiidra MCP can be stored in the [`md/`](md/) folder. See [md/README.md](md/README.md) for report structure guidelines. ## Why "Kawaiidra"? Because reverse engineering should be fun! This is a cute wrapper around serious tools. *Kawaii* (Japanese: cute) + *Ghidra* = **Kawaiidra** ## License MIT License ## See Also - [Ghidra](https://ghidra-sre.org/) - NSA's reverse engineering framework - [Model Context Protocol](https://modelcontextprotocol.io/) - MCP specification - [Claude Code](https://claude.ai/code) - AI coding assistant