
# MCP-Link for Ghidra

**AI-Powered Reverse Engineering with 100% Ghidra API Access**

A Ghidra extension that connects to the Aura Friday MCP-Link server, making Ghidra available as a remote tool that AI agents can fully control via Java reflection. Unlike hardcoded MCP tools with limited operations, this gives AI **unlimited access** to every Ghidra API.

---

## 🚀 What Makes This Different

### Traditional MCP Tools (Limited)
```
AI → get_functions() → hardcoded list
AI → decompile_function(name) → hardcoded call
... maybe 10-40 hardcoded endpoints ...
```

### MCP-Link for Ghidra (Unlimited)
```java
AI → eval("currentProgram.getFunctionManager().getFunctions(true)") → Full API
AI → eval("new DecompInterface().decompileFunction(func, 60, null)") → Any operation
AI → eval("memory.getByte(addr)") → Read raw bytes
AI → list_methods("currentProgram") → Discover 150+ methods
... 100% of Ghidra's Java API via reflection ...
```

**The AI can call ANY method, access ANY field, instantiate ANY class.** No limits, no waiting for us to add features.

---

## ✨ Features

### 🔬 Full Java Reflection Execution
- Execute **any expression** via `eval` operation
- **Method chaining**: `obj.method1().method2().field`
- **Object instantiation**: `new ghidra.app.decompiler.DecompInterface()`
- **Static method calls**: `@ghidra.util.Msg.info(plugin, "Hello!")`
- **Array/List access**: `list[0]`, `map[key]`

### 🔍 API Introspection
- `list_methods` - Discover all methods on any object
- `list_fields` - Discover all fields on any object  
- `describe` - Get full object description with type hierarchy

### 📜 Multi-Line Script Execution
- Variable assignments that persist across calls
- Session management for stateful analysis
- Print statements for output capture

### 🔗 MCP Tool Integration
- Call other MCP tools (SQLite, browser, user popups, AI models)
- Store analysis results in databases
- Show interactive HTML popups
- Automate cross-tool workflows

---

## 🎯 What AI Can Do

### Binary Analysis
```java
// Get all functions
functionManager.getFunctions(true)

// Find functions by name pattern
symbolTable.getGlobalSymbols("crypt")

// Read memory bytes
memory.getByte(addr)
memory.getInt(addr)
```

### Decompilation
```java
// Create decompiler and get C code
decomp = new ghidra.app.decompiler.DecompInterface()
decomp.openProgram(currentProgram)
result = decomp.decompileFunction(func, 60, null)
print(result.getDecompiledFunction().getC())
```

### Symbol Analysis
```java
// Find all symbols
symbolTable.getAllSymbols(true)

// Get imports/exports
symbolTable.getExternalSymbols()

// Find cross-references
referenceManager.getReferencesTo(addr)
```

### Data Types
```java
// Access data type manager
dtm = currentProgram.getDataTypeManager()

// Find structures
dtm.getDataType("/MyStruct")

// Create new types
dtm.addDataType(newStruct, null)
```

---

## 📦 Installation

### Prerequisites

1. **Ghidra 12.0+** - Download from https://ghidra-sre.org/

2. **MCP-Link Server** - Download from https://github.com/AuraFriday/mcp-link-server/releases

3. **Java 21+** - Required for building

### Build & Install

```bash
# Clone the repository
git clone https://github.com/AuraFriday/ghidra_mcp.git
cd ghidra_mcp

# Set Ghidra installation path
# Windows PowerShell:
$env:GHIDRA_INSTALL_DIR = "C:\path\to\ghidra_12.0_PUBLIC"
# Linux/Mac:
export GHIDRA_INSTALL_DIR="/path/to/ghidra_12.0_PUBLIC"

# Build the extension
make build
# Or manually:
cd mcp_link_ghidra && ./gradlew buildExtension

# The extension ZIP is created in mcp_link_ghidra/dist/
```

### Install the Extension

1. Open Ghidra
2. Go to **File → Install Extensions**
3. Click the **+** button
4. Select the ZIP file from `mcp_link_ghidra/dist/`
5. Restart Ghidra
6. Open a binary in the CodeBrowser - the plugin auto-connects!

---

## 🎬 Quick Start Examples

### Example 1: Get Program Info
```json
{
  "operation": "eval",
  "expression": "currentProgram.getName()"
}
```
**Result:** `"hello.exe"`

### Example 2: Count Functions
```json
{
  "operation": "eval", 
  "expression": "functionManager.getFunctionCount()"
}
```
**Result:** `42`

### Example 3: Decompile Entry Function
```json
{
  "operation": "script",
  "script": "syms = symbolTable.getGlobalSymbols(\"entry\")\naddr = syms[0].getAddress()\nfunc = listing.getFunctionAt(addr)\ndecomp = new ghidra.app.decompiler.DecompInterface()\ndecomp.openProgram(currentProgram)\nresult = decomp.decompileFunction(func, 60, null)\nprint(result.getDecompiledFunction().getC())",
  "session_id": "default"
}
```
**Result:**
```c
void entry(void)
{
  longlong lVar1;
  undefined4 auStackX_8 [8];
  
  auStackX_8[0] = 0;
  lVar1 = GetStdHandle(0xfffffff5);
  if (lVar1 != -1) {
    WriteFile(lVar1,&DAT_140002020,0xf,auStackX_8,0);
  }
  ExitProcess(0);
  ...
}
```

### Example 4: Discover Available Methods
```json
{
  "operation": "list_methods",
  "target": "currentProgram"
}
```
**Result:** 150+ methods including `getName()`, `getFunctionManager()`, `getMemory()`, `getSymbolTable()`, etc.

### Example 5: Read Memory Bytes
```json
{
  "operation": "script",
  "script": "addr = currentAddress\nb0 = memory.getByte(addr)\nb1 = memory.getByte(addr.add(1))\nb2 = memory.getByte(addr.add(2))\nprint(b0)\nprint(b1)\nprint(b2)",
  "session_id": "hex"
}
```

---

## 🔧 Available Operations

| Operation | Description | Example |
|-----------|-------------|---------|
| `eval` / `execute_java` | Execute single expression | `{"operation": "eval", "expression": "currentProgram.getName()"}` |
| `script` / `execute_script` | Multi-line script with assignments | `{"operation": "script", "script": "x = 1\ny = x + 1\nprint(y)"}` |
| `list_methods` | List all methods on object | `{"operation": "list_methods", "target": "functionManager"}` |
| `list_fields` | List all fields on object | `{"operation": "list_fields", "target": "currentProgram"}` |
| `describe` | Full object description | `{"operation": "describe", "target": "memory"}` |
| `call_tool` | Call other MCP tools | `{"operation": "call_tool", "tool_name": "sqlite", ...}` |

---

## 📋 Built-in Variables

These are automatically available in every expression/script:

| Variable | Type | Description |
|----------|------|-------------|
| `currentProgram` | Program | The currently open program |
| `currentAddress` | Address | Current cursor location |
| `tool` | PluginTool | The Ghidra tool instance |
| `plugin` | MCPLinkGhidraPlugin | This plugin instance |
| `flatApi` | FlatProgramAPI | Simplified API for common operations |
| `functionManager` | FunctionManager | Access to functions |
| `symbolTable` | SymbolTable | Access to symbols and labels |
| `memory` | Memory | Raw memory access |
| `listing` | Listing | Instructions and data |
| `addressFactory` | AddressFactory | Create address objects |

---

## 🛠️ Expression Syntax

### Method Chaining
```java
currentProgram.getFunctionManager().getFunctionCount()
symbolTable.getGlobalSymbols("main")[0].getAddress()
```

### Object Instantiation
```java
new ghidra.app.decompiler.DecompInterface()
new ghidra.program.model.address.GenericAddress(...)
```

### Static Method Calls (@ prefix)
```java
@ghidra.util.Msg.info(plugin, "Hello from AI!")
@java.lang.System.currentTimeMillis()
```

### Class References ($ prefix)
```java
$ghidra.app.decompiler.DecompInterface
$java.util.ArrayList
```

### Literals
```java
"string"           // String
123                // Integer
45.67              // Double
0x1400             // Hex number
true / false       // Boolean
null               // Null
```

### Array/List Access
```java
list[0]            // First element
map["key"]         // Map lookup
iterator[5]        // 6th element (converts to list)
```

---

## 🏗️ Architecture

```
┌─────────────────┐         ┌─────────────────────────┐
│ AI Agent        │         │ MCP-Link Server         │
│ (Cursor/Claude) │◄───────►│ (Running on user's PC)  │
└─────────────────┘  MCP    └─────────────────────────┘
                                       │
                                       ▼
                            ┌──────────────────┐
                            │ Ghidra Extension │
                            │ (Remote Tool)    │
                            └──────────────────┘
                                       │
                    ┌──────────────────┼──────────────────┐
                    │                  │                  │
                    ▼                  ▼                  ▼
            ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
            │ Reflection   │  │ Introspection│  │ MCP Bridge   │
            │ Executor     │  │ (list_*)     │  │ (call_tool)  │
            └──────────────┘  └──────────────┘  └──────────────┘
```

### Components

- **MCPLinkGhidraPlugin.java** - Main plugin, lifecycle management
- **MCPLinkConnection.java** - SSE connection to MCP-Link server
- **MCPLinkExecutor.java** - Routes operations to handlers
- **ReflectionExecutor.java** - Pure Java reflection engine (the magic!)
- **MCPLinkProvider.java** - UI panel for connection status

### How It Works

1. **Extension loads** when you open a program in CodeBrowser
2. **Connects to MCP-Link** via native messaging discovery
3. **Registers as "ghidra" tool** with reflection capabilities
4. **AI sends expressions** → Parsed and executed via reflection
5. **Results returned** with type information and string representation

---

## 🔗 Built-in MCP Tools

When running with MCP-Link server, these tools are available:

| Tool | Description |
|------|-------------|
| 🖥️ **System** | Windows desktop automation - screenshots, UI scanning, clicking, typing, window management |
| 🔌 **Terminal** | Universal transport - Serial, TCP, SSH, Telnet, WebSocket, Bluetooth, BLE, RFC2217, named pipes |
| 🌐 **Chrome Browser** | **Unique:** Execute JS with pristine pre-page-load environment - essential for web malware analysis |
| 🧠 **SQLite** | Store analysis results, semantic search with embeddings |
| 💬 **User** | Show HTML popups, forms, get user input |
| 🐍 **Python** | Local Python execution with MCP tool access |
| 🤖 **OpenRouter** | Access 500+ AI models |
| 📚 **Context7** | Live library documentation lookup |

### 🌐 Chrome Browser: Web Malware Analysis Superpower

**Unlike any other browser automation tool**, our Chrome Browser MCP provides something unique: a **pristine pre-page-load JavaScript environment**.

When you analyze web-based malware, obfuscated JavaScript, or hostile web pages, those scripts often:
- Override `console.log` to hide their activity
- Hook `fetch` and `XMLHttpRequest` to intercept/modify network traffic  
- Modify DOM methods to evade detection
- Pollute the global namespace to break analysis tools

**Our solution:** Before ANY page scripts execute, we inject `originalWindow` - a frozen copy of the pristine browser environment:

```javascript
// In your analysis script (via run_script_in_page):

// Safe logging - works even if page redirected console.log to /dev/null
originalWindow.console.log('Malware did X, Y, Z');

// Bypass fetch hooks - make requests the malware can't intercept
const realData = await originalWindow.fetch('/api/secret');

// Access unmodified DOM - createElement that wasn't tampered with
const cleanDiv = originalWindow.document.createElement('div');

// See what the malware DID while having tools it COULDN'T break
const malwareState = document.body.innerHTML; // See malware's mess
originalWindow.console.log('Captured state:', malwareState); // Log safely
```

**Why this matters for RE:**

You can simultaneously:
1. **See what malicious scripts have done** - access the polluted DOM, hooked functions, modified state
2. **Use unbroken tools to analyze it** - pristine console, fetch, timers, event handlers

Plus: Execute JavaScript in **any debug target** - service workers, web workers, extension backgrounds, iframes. Perfect for analyzing complex web apps and browser extensions.

---

### 🔧 System + Terminal: Essential for Real RE Work

These two tools are **game-changers for reverse engineering workflows**:

**System Tool** - See and interact with the desktop:
- Take screenshots of running applications
- Scan UI elements with 100% accurate text extraction (no OCR needed)
- Click buttons, type text, automate any Windows application
- Perfect for: capturing debugger state, automating IDA/x64dbg, interacting with target programs

**Terminal Tool** - Connect to anything:
- Serial ports for embedded device debugging (ESP32, ARM, microcontrollers)
- TCP/Telnet for network device analysis
- SSH for remote system access
- Bluetooth/BLE for wireless device RE
- WebSocket for browser debugging protocols (Chrome DevTools)
- Named pipes for IPC analysis

**Why this matters for RE:**

When analyzing malware or firmware, you often need to:
1. **Run the target** in a controlled environment
2. **Observe behavior** - watch windows, network traffic, serial output
3. **Interact** - click dialogs, respond to prompts, inject input
4. **Capture state** - screenshots, memory dumps, communication logs

With System + Terminal, the AI can do ALL of this autonomously. It can run a sample, watch what windows appear, take screenshots, capture network traffic, and correlate everything with the static analysis from Ghidra.

**Example: Store analysis in database**
```json
{
  "operation": "call_tool",
  "tool_name": "sqlite",
  "arguments": {
    "input": {
      "sql": "INSERT INTO functions (name, addr) VALUES (?, ?)",
      "params": ["main", "0x140001000"]
    }
  }
}
```

**Example: Take screenshot of debugger**
```json
{
  "operation": "call_tool",
  "tool_name": "system",
  "arguments": {
    "input": {
      "operation": "take_screenshot",
      "hwnd": "0x001234",
      "tool_unlock_token": "..."
    }
  }
}
```

**Example: Monitor embedded device serial output**
```json
{
  "operation": "call_tool",
  "tool_name": "terminal",
  "arguments": {
    "input": {
      "operation": "open_session",
      "endpoint": "COM3",
      "baud_rate": 115200,
      "tool_unlock_token": "..."
    }
  }
}
```

---

## 💡 Use Cases

### 🔍 Malware Analysis
- Automatically find suspicious functions
- Extract strings and IOCs
- Decompile and analyze crypto routines
- Store findings in database

### 🛡️ Vulnerability Research
- Find dangerous API calls
- Trace data flow through functions
- Identify buffer overflow patterns
- Document findings automatically

### 📚 Documentation Generation
- Extract function signatures
- Generate API documentation
- Create call graphs
- Build symbol databases

### 🤖 Automated RE Workflows
- Batch analyze binaries
- Compare function similarities
- Track changes between versions
- Generate reports

---

## 🔧 Technical Details

### Thread Safety
- All Ghidra API calls execute on Swing EDT when needed
- Background SSE thread handles network communication
- Concurrent session management for parallel analysis

### Expression Parser
- Hand-written recursive descent parser
- Handles method chains, nested calls, string escaping
- Type-aware argument conversion
- Full Java primitive support

### Session Persistence
- Variables persist within sessions
- Multiple sessions for parallel work
- Clear sessions programmatically

---

## ⚠️ Limitations

- **No loop constructs** - Use scripts with variable assignments
- **No conditionals** - Ternary expressions work, but no if/else blocks
- **Iterator consumption** - Iterators get consumed when displayed
- **Swing EDT** - Some operations must run on main thread

---

## 🤝 Contributing

**Want to contribute?** PRs welcome!

### Ideas for Contributors
- Add more expression language features (loops, conditionals)
- Create example scripts for common RE tasks
- Improve error messages and debugging
- Build integrations with other tools
- Write tutorials and documentation

---

## 📄 License

Apache 2.0 - See LICENSE file for details

---

## 👤 Author

Created by [AuraFriday](https://github.com/AuraFriday)

---

## 🔗 Links

- **MCP-Link Server**: https://github.com/AuraFriday/mcp-link-server
- **Model Context Protocol**: https://modelcontextprotocol.io
- **Ghidra**: https://ghidra-sre.org
- **Ghidra GitHub**: https://github.com/NationalSecurityAgency/ghidra

---

## 🛡️ Safety and Environment Assumptions

This plugin is designed for **professional reverse-engineering workflows**.

It exposes reflective access to the Ghidra Java API, equivalent in power to writing and executing custom Ghidra scripts.

As with all reverse-engineering tools, it assumes you are operating inside an appropriately isolated environment (for example: virtual machines, snapshots, non-privileged user accounts).

**If your environment is safe for analyzing untrusted binaries in Ghidra, it is safe for using this plugin.**

If it is not, this plugin is not the thing that needs fixing.

---

## ❓ FAQ

**Q: Does this work with Ghidra 12.0?**  
A: Yes! Tested with Ghidra 12.0 and later.

**Q: Do I need Python/Jython?**  
A: No! Pure Java reflection - no Python required.

**Q: Can AI access private methods?**  
A: Yes! `setAccessible(true)` enables access to any member.

**Q: Is this secure?**  
A: The AI has full Ghidra API access. Only use with trusted AI agents.

**Q: Does this work offline?**  
A: Yes! All operations are local. MCP-Link server runs on your machine.

**Q: Can I use with Claude/ChatGPT/Cursor?**  
A: Works with any AI that supports MCP protocol.

**Q: What's the performance impact?**  
A: Minimal - reflection adds microseconds of overhead per call.

---

## 🌟 Star This Project!

If you find this useful, please star the repository!

**Questions?** Open an issue on GitHub.

---

**This is the future of AI-powered reverse engineering.** 🚀
