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
7.8 KiB
7.8 KiB
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)
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)
# 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
# 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
# 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:
{
"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:
# 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
# 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
# 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
# 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
docker ps | grep ghydramcp
View Logs
docker logs -f my-analysis
Stop Analysis
docker stop my-analysis
docker rm my-analysis
Persistent Projects
# 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
# 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
# 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
# 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
# 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
# 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! 🔍