GhydraMCPServer.java imports Gson but headless scripts run in a separate OSGi classloader that can't access extension lib JARs. Fix: Download gson-2.13.1.jar to Framework/Generic/lib/ where it's available to all scripts regardless of execution mode. Closes issue documented in BUG_REPORT_HEADLESS_GSON.md
116 lines
3.3 KiB
Markdown
116 lines
3.3 KiB
Markdown
# Bug Report: Docker Headless Mode Fails - Missing Gson Dependency
|
|
|
|
## Summary
|
|
|
|
The GhydraMCP Docker container fails to start the HTTP API server because `GhydraMCPServer.java` imports Gson, but Gson is not available in Ghidra's headless script classpath.
|
|
|
|
## Environment
|
|
|
|
- GhydraMCP Docker image: `ghydramcp:latest`
|
|
- Ghidra Version: 11.4.2
|
|
- Build Date: 2025-08-26
|
|
|
|
## Steps to Reproduce
|
|
|
|
1. Build the Docker image:
|
|
```bash
|
|
docker build -t ghydramcp:latest -f docker/Dockerfile .
|
|
```
|
|
|
|
2. Run with a binary:
|
|
```bash
|
|
docker run -p 8192:8192 -v /path/to/binary:/binaries/test ghydramcp:latest /binaries/test
|
|
```
|
|
|
|
3. Check logs:
|
|
```bash
|
|
docker logs <container_id>
|
|
```
|
|
|
|
## Expected Behavior
|
|
|
|
Container should start and expose HTTP API on port 8192.
|
|
|
|
## Actual Behavior
|
|
|
|
Analysis completes but the script fails to load:
|
|
|
|
```
|
|
INFO REPORT: Analysis succeeded for file: file:///binaries/cardv (HeadlessAnalyzer)
|
|
ERROR REPORT SCRIPT ERROR: GhydraMCPServer.java : The class could not be found.
|
|
It must be the public class of the .java file: Failed to get OSGi bundle containing script:
|
|
/opt/ghidra/scripts/GhydraMCPServer.java (HeadlessAnalyzer)
|
|
```
|
|
|
|
The health check fails because the HTTP server never starts:
|
|
|
|
```json
|
|
{"healthy":false,"port":8192,"error":"[Errno 111] Connection refused"}
|
|
```
|
|
|
|
## Root Cause Analysis
|
|
|
|
`GhydraMCPServer.java` (lines 22-24) imports Gson:
|
|
|
|
```java
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.GsonBuilder;
|
|
import com.google.gson.JsonObject;
|
|
import com.google.gson.JsonParser;
|
|
```
|
|
|
|
However:
|
|
1. Gson is **not** bundled with Ghidra
|
|
2. The GhydraMCP extension JAR includes Gson, but headless scripts run in a **separate OSGi classloader** without access to extension lib dependencies
|
|
3. The Dockerfile doesn't copy Gson to Ghidra's script classpath
|
|
|
|
## Verification
|
|
|
|
```bash
|
|
# Check if Gson is in the built extension
|
|
unzip -l target/GhydraMCP-*.zip | grep -i gson
|
|
# Result: No matches
|
|
|
|
# Check Ghidra's lib directories
|
|
ls /opt/ghidra/Ghidra/Framework/*/lib/ | grep -i gson
|
|
# Result: No matches
|
|
```
|
|
|
|
## Proposed Solutions
|
|
|
|
### Option 1: Bundle Gson JAR with Scripts (Recommended)
|
|
|
|
Add Gson JAR to Ghidra's script classpath in Dockerfile:
|
|
|
|
```dockerfile
|
|
# Download Gson and add to Ghidra lib
|
|
RUN curl -fsSL "https://repo1.maven.org/maven2/com/google/gson/gson/2.10.1/gson-2.10.1.jar" \
|
|
-o /opt/ghidra/Ghidra/Framework/Generic/lib/gson-2.10.1.jar
|
|
```
|
|
|
|
### Option 2: Use Built-in JSON (No External Dependencies)
|
|
|
|
Rewrite `GhydraMCPServer.java` to use only JDK classes:
|
|
- Replace Gson with `javax.json` or manual JSON string building
|
|
- This ensures the script works without any external dependencies
|
|
|
|
### Option 3: Pre-compiled Script JAR
|
|
|
|
Compile `GhydraMCPServer.java` with Gson into a JAR and place it in the extension, then reference it differently in headless mode.
|
|
|
|
## Impact
|
|
|
|
- **Severity**: High - Docker deployment is completely broken
|
|
- **Affected**: All users attempting to use Docker/headless mode
|
|
- **Workaround**: None currently (must use GUI mode)
|
|
|
|
## Additional Context
|
|
|
|
The main GhydraMCP plugin works fine in GUI mode because the extension's lib dependencies are loaded. This only affects the headless Docker workflow where scripts are loaded separately from the extension.
|
|
|
|
---
|
|
|
|
**Reported by**: Firmware analysis session
|
|
**Date**: 2026-01-26
|
|
**Binary being analyzed**: WOLFBOX G850 dashcam `cardv` (ARM 32-bit)
|