#!/bin/bash # MCGhidra Docker Entrypoint # Starts Ghidra in headless mode with HTTP API server set -e MCGHIDRA_MODE=${MCGHIDRA_MODE:-headless} MCGHIDRA_PORT=${MCGHIDRA_PORT:-8192} MCGHIDRA_MAXMEM=${MCGHIDRA_MAXMEM:-2G} GHIDRA_HOME=${GHIDRA_HOME:-/opt/ghidra} # User scripts directory - Python scripts don't need OSGi bundle registration SCRIPT_DIR=${SCRIPT_DIR:-/home/ghidra/ghidra_scripts} # Project settings PROJECT_DIR=${PROJECT_DIR:-/projects} PROJECT_NAME=${PROJECT_NAME:-MCGhidra} echo "==============================================" echo " MCGhidra Docker Container" echo "==============================================" echo " Mode: ${MCGHIDRA_MODE}" echo " Port: ${MCGHIDRA_PORT}" echo " Memory: ${MCGHIDRA_MAXMEM}" echo " Project: ${PROJECT_DIR}/${PROJECT_NAME}" echo "==============================================" # Ensure directories exist mkdir -p "${PROJECT_DIR}" # Handle different modes case "${MCGHIDRA_MODE}" in headless) # Headless mode: Import a binary and start HTTP server if [ $# -eq 0 ]; then echo "" echo "Usage: docker run mcghidra:latest [binary_path] [options]" echo "" echo "Examples:" echo " # Analyze a binary mounted at /binaries/sample.exe" echo " docker run -p 8192:8192 -v ./samples:/binaries mcghidra /binaries/sample.exe" echo "" echo " # With custom project name" echo " docker run -p 8192:8192 -v ./samples:/binaries -e PROJECT_NAME=malware mcghidra /binaries/sample.exe" echo "" echo "Environment variables:" echo " MCGHIDRA_PORT - HTTP API port (default: 8192)" echo " MCGHIDRA_MAXMEM - Max JVM heap (default: 2G)" echo " PROJECT_NAME - Ghidra project name (default: MCGhidra)" echo " PROJECT_DIR - Project directory (default: /projects)" echo "" echo "Starting in wait mode..." echo "Container will stay running for debugging or manual operation." echo "You can exec into this container to run analyzeHeadless manually." echo "" # Keep container alive for debugging/manual operation tail -f /dev/null else BINARY_PATH="$1" shift if [ ! -f "${BINARY_PATH}" ]; then echo "ERROR: Binary not found: ${BINARY_PATH}" echo "Make sure to mount the binary directory with -v /host/path:/binaries" exit 1 fi BINARY_NAME=$(basename "${BINARY_PATH}") echo "Importing and analyzing: ${BINARY_NAME}" echo "" # Build the analyzeHeadless command ANALYZE_CMD="${GHIDRA_HOME}/support/analyzeHeadless" ANALYZE_ARGS=( "${PROJECT_DIR}" "${PROJECT_NAME}" -import "${BINARY_PATH}" -max-cpu 2 -scriptPath "${SCRIPT_DIR}" -postScript "MCGhidraServer.py" "${MCGHIDRA_PORT}" ) # Add any extra arguments passed ANALYZE_ARGS+=("$@") echo "Running: ${ANALYZE_CMD} ${ANALYZE_ARGS[*]}" echo "" exec "${ANALYZE_CMD}" "${ANALYZE_ARGS[@]}" fi ;; server) # Server mode: Open existing project with HTTP server echo "Starting MCGhidra server on existing project..." if [ $# -eq 0 ]; then echo "Usage: docker run -e MCGHIDRA_MODE=server mcghidra [program_name]" echo "" echo " program_name: Name of program in the project to open" exit 1 fi PROGRAM_NAME="$1" shift exec "${GHIDRA_HOME}/support/analyzeHeadless" \ "${PROJECT_DIR}" "${PROJECT_NAME}" \ -process "${PROGRAM_NAME}" \ -noanalysis \ -scriptPath "${SCRIPT_DIR}" \ -postScript "MCGhidraServer.py" "${MCGHIDRA_PORT}" \ "$@" ;; analyze) # Analyze mode: Import and analyze, then exit (no HTTP server) if [ $# -eq 0 ]; then echo "Usage: docker run -e MCGHIDRA_MODE=analyze mcghidra [binary_path]" exit 1 fi BINARY_PATH="$1" shift echo "Analyzing binary: ${BINARY_PATH}" exec "${GHIDRA_HOME}/support/analyzeHeadless" \ "${PROJECT_DIR}" "${PROJECT_NAME}" \ -import "${BINARY_PATH}" \ -max-cpu 2 \ "$@" ;; shell) # Interactive shell exec /bin/bash ;; *) echo "Unknown mode: ${MCGHIDRA_MODE}" echo "Valid modes: headless, server, analyze, shell" exit 1 ;; esac