mcghidra/BUG_REPORT_HEADLESS_GSON.md
Ryan Malloy 1143489924
Some checks are pending
Build Ghidra Plugin / build (push) Waiting to run
refactor: Rename project from ghydramcp to mcghidra
- Rename src/ghydramcp → src/mcghidra
- Rename GhydraMCPPlugin.java → MCGhidraPlugin.java
- Update all imports, class names, and references
- Update pyproject.toml package name and script entry
- Update Docker image names and container prefixes
- Update environment variables: GHYDRA_* → MCGHIDRA_*
- Update all documentation references
2026-02-07 02:13:53 -07:00

3.3 KiB

Bug Report: Docker Headless Mode Fails - Missing Gson Dependency

Summary

The MCGhidra Docker container fails to start the HTTP API server because MCGhidraServer.java imports Gson, but Gson is not available in Ghidra's headless script classpath.

Environment

  • MCGhidra Docker image: mcghidra:latest
  • Ghidra Version: 11.4.2
  • Build Date: 2025-08-26

Steps to Reproduce

  1. Build the Docker image:

    docker build -t mcghidra:latest -f docker/Dockerfile .
    
  2. Run with a binary:

    docker run -p 8192:8192 -v /path/to/binary:/binaries/test mcghidra:latest /binaries/test
    
  3. Check logs:

    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: MCGhidraServer.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/MCGhidraServer.java (HeadlessAnalyzer)

The health check fails because the HTTP server never starts:

{"healthy":false,"port":8192,"error":"[Errno 111] Connection refused"}

Root Cause Analysis

MCGhidraServer.java (lines 22-24) imports Gson:

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 MCGhidra 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

# Check if Gson is in the built extension
unzip -l target/MCGhidra-*.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

Add Gson JAR to Ghidra's script classpath in 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 MCGhidraServer.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 MCGhidraServer.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 MCGhidra 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)