npm package: @modular-intelligence/ghidra
Description: MCP server wrapping Ghidra headless analyzer for reverse engineering
Latest version: 1.0.2

# Ghidra MCP Server

An MCP server that provides reverse engineering capabilities through Ghidra's headless analyzer. This server wraps Ghidra functionality to analyze binaries, decompile functions, extract strings, and perform various static analysis tasks.

## Features

- **Binary Analysis**: Extract format, architecture, compiler, entry points, and section information
- **Decompilation**: Convert assembly to readable C-like pseudocode for specific functions
- **Function Listing**: Enumerate all functions with filtering and metadata
- **Cross-References**: Find caller/callee relationships and references
- **String Extraction**: Extract strings with configurable encoding and filtering
- **Import/Export Analysis**: Identify external dependencies and exported APIs
- **Custom Scripts**: Execute allowlisted Ghidra scripts for advanced analysis

## Prerequisites

### 1. Ghidra Installation

Download and install Ghidra from [https://ghidra-sre.org/](https://ghidra-sre.org/)

### 2. Environment Variable

Set the `GHIDRA_HOME` environment variable to point to your Ghidra installation:

```bash
# Linux/macOS
export GHIDRA_HOME=/path/to/ghidra_10.x

# Windows
set GHIDRA_HOME=C:\path\to\ghidra_10.x
```

Add this to your shell profile (`.bashrc`, `.zshrc`, etc.) to make it permanent.

### 3. Java Runtime

Ghidra requires Java 11 or later. Verify your installation:

```bash
java -version
```

## Installation

```bash
cd ghidra
bun install
bun run build
```

## Usage

### Running the Server

```bash
bun run start
```

### Available Tools

#### 1. ghidra_analyze

Analyze a binary to extract basic program information.

**Parameters:**
- `binary_path` (required): Absolute path to binary file to analyze
- `timeout` (optional): Max analysis duration in seconds (default: 300, range: 30-1800)

**Returns:**
```json
{
  "binary": "/path/to/binary",
  "format": "Portable Executable (PE)",
  "architecture": "x86:LE:64:default",
  "compiler": "Visual Studio",
  "entry_point": "0x140001000",
  "sections": [
    {
      "name": ".text",
      "address": "0x140001000",
      "size": 4096
    }
  ],
  "analysis_summary": {
    "function_count": 142,
    "section_count": 6
  }
}
```

#### 2. ghidra_decompile

Decompile a specific function to C-like pseudocode.

**Parameters:**
- `binary_path` (required): Absolute path to binary file to analyze
- `function_name` (optional): Function name to decompile
- `address` (optional): Memory address in hex (e.g., 0x401000)
- `timeout` (optional): Max analysis duration in seconds (default: 300)

Note: Either `function_name` or `address` must be provided.

**Returns:**
```json
{
  "binary": "/path/to/binary",
  "function_name": "main",
  "decompiled_code": "int main(int argc, char **argv) {\n  ...\n}",
  "address": "0x401000",
  "calling_convention": "__cdecl",
  "return_type": "int",
  "parameters": 2
}
```

#### 3. ghidra_list_functions

List all functions in a binary with optional filtering.

**Parameters:**
- `binary_path` (required): Absolute path to binary file to analyze
- `filter` (optional): Filter function names by pattern
- `limit` (optional): Max functions to return (default: 100, range: 1-1000)
- `timeout` (optional): Max analysis duration in seconds (default: 300)

**Returns:**
```json
{
  "binary": "/path/to/binary",
  "functions": [
    {
      "name": "main",
      "address": "0x401000",
      "size": 256,
      "calling_convention": "__cdecl",
      "return_type": "int",
      "parameter_count": 2
    }
  ],
  "total": 142
}
```

#### 4. ghidra_xrefs

Find cross-references to or from a function or address.

**Parameters:**
- `binary_path` (required): Absolute path to binary file to analyze
- `function_name` (optional): Function name to focus on
- `address` (optional): Memory address in hex (e.g., 0x401000)
- `direction` (optional): Cross-reference direction - "to", "from", or "both" (default: "both")
- `timeout` (optional): Max analysis duration in seconds (default: 300)

**Returns:**
```json
{
  "target": "main",
  "direction": "both",
  "xrefs": [
    {
      "from_address": "0x401234",
      "from_function": "start",
      "to_address": "0x401000",
      "to_function": "main",
      "type": "UNCONDITIONAL_CALL"
    }
  ],
  "total": 5
}
```

#### 5. ghidra_strings

Extract strings from a binary.

**Parameters:**
- `binary_path` (required): Absolute path to binary file to analyze
- `min_length` (optional): Minimum string length (default: 4, range: 3-100)
- `encoding` (optional): String encoding - "ascii", "utf8", or "utf16" (default: "ascii")
- `limit` (optional): Max strings to return (default: 500, range: 1-5000)
- `timeout` (optional): Max analysis duration in seconds (default: 300)

**Returns:**
```json
{
  "binary": "/path/to/binary",
  "strings": [
    {
      "value": "Hello, World!",
      "address": "0x402000",
      "section": ".rdata",
      "encoding": "ascii"
    }
  ],
  "total": 324
}
```

#### 6. ghidra_imports_exports

List imported and exported functions.

**Parameters:**
- `binary_path` (required): Absolute path to binary file to analyze
- `type` (optional): Show "imports", "exports", or "both" (default: "both")
- `timeout` (optional): Max analysis duration in seconds (default: 300)

**Returns:**
```json
{
  "binary": "/path/to/binary",
  "imports": [
    {
      "name": "printf",
      "library": "msvcrt.dll",
      "address": "0x403000",
      "ordinal": 0
    }
  ],
  "exports": [
    {
      "name": "MyExportedFunction",
      "address": "0x401500",
      "ordinal": 0
    }
  ]
}
```

#### 7. ghidra_script

Execute an allowlisted Ghidra script on a binary.

**Parameters:**
- `binary_path` (required): Absolute path to binary file to analyze
- `script_name` (required): Allowed Ghidra script to run
  - `ExportFunctions.java`
  - `ExportDecompiled.java`
  - `ListStrings.java`
  - `ListImports.java`
  - `ListExports.java`
  - `FindXrefs.java`
  - `AnalyzeProgram.java`
- `script_args` (optional): Arguments to pass to the script
- `timeout` (optional): Max analysis duration in seconds (default: 300)

**Returns:**
```json
{
  "binary": "/path/to/binary",
  "script": "ExportFunctions.java",
  "output": "script output here...",
  "stderr": "",
  "exit_code": 0
}
```

## Security Features

This server implements multiple security layers to prevent abuse:

### Path Validation
- Only absolute paths are accepted
- Path traversal attempts are blocked
- Null byte injection is prevented
- System paths (`/proc`, `/sys`, `/dev`, `/etc/shadow`, `/etc/passwd`) are blocked
- Files must exist and be under 500MB

### Script Allowlisting
Only pre-approved Ghidra scripts can be executed:
- ExportFunctions.java
- ExportDecompiled.java
- ListStrings.java
- ListImports.java
- ListExports.java
- FindXrefs.java
- AnalyzeProgram.java

### Input Validation
- Function names: Must match `[a-zA-Z_][a-zA-Z0-9_]*` and be under 256 characters
- Addresses: Must be in hex format (e.g., `0x401000`)
- Timeouts: Enforced between 30-1800 seconds with process kill on timeout

### Resource Limits
- Maximum file size: 500MB
- Maximum output buffer: 50MB
- Configurable per-tool limits on result counts
- Automatic cleanup of temporary project directories

## Architecture

```
ghidra/
├── package.json              # Package configuration
├── tsconfig.json            # TypeScript configuration
├── README.md                # This file
└── src/
    ├── index.ts             # MCP server implementation
    ├── schemas.ts           # Zod schemas for validation
    ├── security.ts          # Security validation functions
    ├── cli-executor.ts      # Ghidra headless execution wrapper
    └── tools/
        ├── ghidra-analyze.ts           # Binary analysis
        ├── ghidra-decompile.ts         # Function decompilation
        ├── ghidra-list-functions.ts    # Function enumeration
        ├── ghidra-xrefs.ts             # Cross-reference analysis
        ├── ghidra-strings.ts           # String extraction
        ├── ghidra-imports-exports.ts   # Import/export listing
        └── ghidra-script.ts            # Custom script execution
```

## How It Works

1. **Temporary Projects**: Each analysis creates a temporary Ghidra project directory
2. **Headless Analysis**: Ghidra's `analyzeHeadless` tool runs in non-interactive mode
3. **Script Execution**: Custom Java scripts extract specific information from the analyzed binary
4. **Output Parsing**: Structured output is parsed and returned as JSON
5. **Cleanup**: Temporary projects are automatically deleted after analysis

## Error Handling

The server provides detailed error messages for:
- Missing GHIDRA_HOME environment variable
- Invalid or inaccessible binary paths
- Timeout exceeded during analysis
- Decompilation failures
- Script execution errors
- Invalid input parameters

## Performance Considerations

- First analysis of a binary is slower due to initial import and analysis
- Decompilation time scales with function complexity
- Large binaries (>100MB) may require increased timeout values
- Temporary directories can consume significant disk space during analysis

## License

This MCP server is provided as-is for reverse engineering and security research purposes. Ensure you have permission to analyze any binaries you process.

## Troubleshooting

### "GHIDRA_HOME environment variable is required"
Ensure GHIDRA_HOME is set and points to a valid Ghidra installation directory.

### "File size exceeds maximum allowed size"
The binary is larger than 500MB. This limit can be adjusted in `src/security.ts` if needed.

### Timeouts
Increase the `timeout` parameter for large or complex binaries. Maximum is 1800 seconds (30 minutes).

### Script Not Found
Verify the script name exactly matches one of the allowlisted scripts. Script names are case-sensitive.