Some checks are pending
Build Ghidra Plugin / build (push) Waiting to run
- Add ghydramcp Python package with FastMCP server implementation - Add docker-compose.yml for easy container management - Add Makefile with build/run targets - Add QUICKSTART.md for getting started - Add uv.lock for reproducible dependencies
329 lines
7.8 KiB
Markdown
329 lines
7.8 KiB
Markdown
# GhydraMCP Quick Start Guide
|
|
|
|
## What is GhydraMCP?
|
|
|
|
GhydraMCP is a complete reverse engineering platform that combines:
|
|
- **Ghidra** - NSA's powerful binary analysis tool
|
|
- **Docker** - Containerized, reproducible analysis environment
|
|
- **HTTP REST API** - HATEOAS-compliant REST interface
|
|
- **MCP Server** - FastMCP-based Model Context Protocol integration
|
|
- **ARM Firmware Support** - Tools for analyzing raw embedded firmware
|
|
|
|
## 5-Minute Quick Start
|
|
|
|
### 1. Analyze a Standard Binary (ELF/PE/Mach-O)
|
|
|
|
```bash
|
|
cd /home/rpm/claude/ghydramcp/GhydraMCP
|
|
|
|
# Build the Docker image (one time)
|
|
docker build -t ghydramcp:latest -f docker/Dockerfile .
|
|
|
|
# Analyze any standard binary
|
|
docker run -d --name my-analysis \
|
|
-p 8192:8192 \
|
|
-v $(pwd)/binaries:/binaries \
|
|
ghydramcp:latest \
|
|
/binaries/your-binary
|
|
|
|
# Wait ~20 seconds for analysis, then access HTTP API
|
|
curl http://localhost:8192/
|
|
curl http://localhost:8192/functions | jq '.functions[] | {name, address}'
|
|
curl http://localhost:8192/functions/<address>/decompile
|
|
```
|
|
|
|
### 2. Analyze ARM Firmware (Raw Binary)
|
|
|
|
```bash
|
|
# Step 1: Create ELF wrapper
|
|
python3 docker/arm_firmware_prep.py \
|
|
your-firmware.bin \
|
|
binaries/your-firmware.elf \
|
|
0x00000000
|
|
|
|
# Step 2: Analyze normally
|
|
docker run -d --name arm-firmware \
|
|
-p 8192:8192 \
|
|
-v $(pwd)/binaries:/binaries \
|
|
ghydramcp:latest \
|
|
/binaries/your-firmware.elf
|
|
```
|
|
|
|
### 3. Use the MCP Server
|
|
|
|
```bash
|
|
# The MCP server is located at:
|
|
cd /home/rpm/claude/ghydramcp/GhydraMCP
|
|
./launch.sh
|
|
|
|
# Or with uv:
|
|
cd GhydraMCP && uv run ghydramcp
|
|
```
|
|
|
|
## HTTP API Overview
|
|
|
|
Once analysis completes, the API is available at `http://localhost:8192/`:
|
|
|
|
### Core Endpoints
|
|
|
|
```bash
|
|
# Program information
|
|
GET /program
|
|
|
|
# Functions
|
|
GET /functions # List all functions
|
|
GET /functions/<address> # Function details
|
|
GET /functions/<address>/decompile # Decompiled C code
|
|
GET /functions/<address>/disassembly # Assembly listing
|
|
GET /functions/<address>/variables # Local variables
|
|
|
|
# Analysis
|
|
GET /analysis/callgraph?name=main&max_depth=3
|
|
GET /analysis/dataflow?address=<addr>&direction=forward
|
|
|
|
# Memory
|
|
GET /memory/<address>?length=256&format=hex
|
|
POST /memory/<address> # Write bytes
|
|
|
|
# Data & Structures
|
|
GET /data/strings
|
|
GET /structs
|
|
GET /xrefs?to_addr=<addr>
|
|
```
|
|
|
|
### Response Format (HATEOAS)
|
|
|
|
All responses include navigation links:
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"result": {
|
|
"name": "main",
|
|
"address": "00101380",
|
|
"signature": "int main(void)"
|
|
},
|
|
"_links": {
|
|
"self": "/functions/00101380",
|
|
"decompile": "/functions/00101380/decompile",
|
|
"disassembly": "/functions/00101380/disassembly"
|
|
}
|
|
}
|
|
```
|
|
|
|
## MCP Tools Overview
|
|
|
|
Use with Claude Code or any MCP client:
|
|
|
|
```python
|
|
# Functions
|
|
functions_list(port=8192, page_size=50)
|
|
functions_decompile(address="00101380", port=8192)
|
|
functions_get(name="main", port=8192)
|
|
|
|
# Analysis
|
|
analysis_get_callgraph(name="main", max_depth=3, port=8192)
|
|
analysis_get_dataflow(address="00101380", direction="forward", port=8192)
|
|
|
|
# Data
|
|
data_list_strings(port=8192, grep="password")
|
|
structs_list(port=8192)
|
|
|
|
# Docker Management
|
|
docker_status()
|
|
docker_start(binary_path="/path/to/binary", port=8192)
|
|
docker_stop(name_or_id="container-name")
|
|
docker_logs(name_or_id="container-name", tail=100)
|
|
```
|
|
|
|
## Common Workflows
|
|
|
|
### Find Interesting Functions
|
|
|
|
```bash
|
|
# List all functions
|
|
curl http://localhost:8192/functions | jq '.functions[].name'
|
|
|
|
# Search for crypto-related functions
|
|
curl http://localhost:8192/functions | jq '.functions[] | select(.name | test("crypt|hash|encrypt"; "i"))'
|
|
|
|
# Get call graph from main
|
|
curl 'http://localhost:8192/analysis/callgraph?name=main&max_depth=2' | jq .
|
|
```
|
|
|
|
### Analyze Strings
|
|
|
|
```bash
|
|
# List all strings
|
|
curl http://localhost:8192/data/strings | jq '.strings[] | {address, value}'
|
|
|
|
# Find passwords/keys
|
|
curl http://localhost:8192/data/strings | jq '.strings[] | select(.value | test("password|key|secret"; "i"))'
|
|
```
|
|
|
|
### Decompile Entry Point
|
|
|
|
```bash
|
|
# Get program entry point
|
|
ENTRY=$(curl -s http://localhost:8192/program | jq -r '.program.entryPoint')
|
|
|
|
# Decompile it
|
|
curl "http://localhost:8192/functions/$ENTRY/decompile" | jq -r '.result'
|
|
```
|
|
|
|
## Docker Management
|
|
|
|
### List Running Containers
|
|
|
|
```bash
|
|
docker ps | grep ghydramcp
|
|
```
|
|
|
|
### View Logs
|
|
|
|
```bash
|
|
docker logs -f my-analysis
|
|
```
|
|
|
|
### Stop Analysis
|
|
|
|
```bash
|
|
docker stop my-analysis
|
|
docker rm my-analysis
|
|
```
|
|
|
|
### Persistent Projects
|
|
|
|
```bash
|
|
# Mount project directory for persistence
|
|
docker run -d --name persistent \
|
|
-p 8192:8192 \
|
|
-v $(pwd)/projects:/projects \
|
|
-v $(pwd)/binaries:/binaries \
|
|
-e PROJECT_NAME=MyProject \
|
|
ghydramcp:latest \
|
|
/binaries/my-binary
|
|
|
|
# Projects are saved in ./projects/MyProject/
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Import Failed
|
|
|
|
```bash
|
|
# Check logs
|
|
docker logs my-analysis 2>&1 | grep ERROR
|
|
|
|
# Common issues:
|
|
# 1. Binary not found → Check volume mount path
|
|
# 2. AutoImporter failed → Use arm_firmware_prep.py for raw binaries
|
|
# 3. Unsupported format → Check file type with `file binary`
|
|
```
|
|
|
|
### Script Errors
|
|
|
|
```bash
|
|
# If you see "Failed to get OSGi bundle" errors
|
|
# Fix script permissions in running container:
|
|
docker exec my-analysis sh -c 'chmod 644 /opt/ghidra/scripts/*.java'
|
|
|
|
# Then restart the analysis
|
|
```
|
|
|
|
### Port Already in Use
|
|
|
|
```bash
|
|
# Use different port
|
|
docker run -d --name analysis2 \
|
|
-p 8193:8192 \
|
|
-v $(pwd)/binaries:/binaries \
|
|
ghydramcp:latest \
|
|
/binaries/binary
|
|
|
|
# Access at http://localhost:8193/
|
|
```
|
|
|
|
## Examples
|
|
|
|
### Example 1: Analyze Test Binary
|
|
|
|
```bash
|
|
# Create simple test binary
|
|
cat > test.c << 'EOF'
|
|
#include <stdio.h>
|
|
int secret_value = 0x42;
|
|
void hidden() { printf("Hidden: %d\n", secret_value); }
|
|
int main() { printf("Hello!\n"); return 0; }
|
|
EOF
|
|
|
|
gcc -o binaries/test test.c
|
|
|
|
# Analyze
|
|
docker run -d --name test-analysis \
|
|
-p 8192:8192 \
|
|
-v $(pwd)/binaries:/binaries \
|
|
ghydramcp:latest \
|
|
/binaries/test
|
|
|
|
# Find hidden function
|
|
sleep 15
|
|
curl http://localhost:8192/functions | jq '.functions[] | select(.name == "hidden")'
|
|
```
|
|
|
|
### Example 2: Cisco Phone Firmware
|
|
|
|
```bash
|
|
# Prepare firmware
|
|
python3 docker/arm_firmware_prep.py \
|
|
cisco-firmware/P003-8-12-00.bin \
|
|
binaries/cisco.elf \
|
|
0x00000000
|
|
|
|
# Analyze
|
|
docker run -d --name cisco \
|
|
-p 8192:8192 \
|
|
-v $(pwd)/binaries:/binaries \
|
|
ghydramcp:latest \
|
|
/binaries/cisco.elf
|
|
|
|
# Explore
|
|
sleep 30
|
|
curl http://localhost:8192/functions | jq '.functions | length' # Function count
|
|
curl http://localhost:8192/data/strings | jq '.strings[] | select(.value | test("SIP|RTP"))'
|
|
```
|
|
|
|
## Next Steps
|
|
|
|
- **Read ARM_FIRMWARE_SUCCESS.md** for ARM firmware details
|
|
- **Check docker/README_ARM_SOLUTION.md** for advanced ARM workflows
|
|
- **Explore MCP integration** with Claude Code
|
|
- **Build automations** using the HTTP API
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
GhydraMCP/
|
|
├── docker/
|
|
│ ├── Dockerfile # Main Docker image
|
|
│ ├── entrypoint.sh # Container entry point
|
|
│ ├── GhydraMCPServer.java # HTTP API server (1724 lines)
|
|
│ ├── ImportRawARM.java # Raw binary import script
|
|
│ ├── arm_firmware_prep.py # ELF wrapper tool ⭐
|
|
│ └── README*.md # Documentation
|
|
├── src/ghydramcp/ # MCP server implementation
|
|
│ ├── __init__.py
|
|
│ ├── server.py # FastMCP server
|
|
│ └── mixins/ # Modular functionality
|
|
│ ├── docker.py # Docker management
|
|
│ ├── instances.py # Instance registry
|
|
│ ├── functions.py # Function operations
|
|
│ ├── analysis.py # Analysis tools
|
|
│ └── ...
|
|
├── binaries/ # Binary files for analysis
|
|
├── projects/ # Ghidra project persistence
|
|
└── launch.sh # MCP server launcher
|
|
```
|
|
|
|
Happy reverse engineering! 🔍
|