How to Integrate Ghidra for Headless Binary Analysis: Automation and CI Workflows
Ghidra's analyzeHeadless driver enables fully automated static analysis without the GUI, allowing you to batch-process binaries in CI pipelines by combining Jython post-scripts with the tool-index manifest from the reverse-skill repository.
The reverse-skill repository provides a complete framework for integrating Ghidra into automated security workflows. By leveraging headless mode, you can decompile binaries, extract cross-references, and generate analysis artifacts programmatically without launching the graphical interface. This guide covers the exact file paths, command syntax, and script patterns used in the zhaoxuya520/reverse-skill codebase.
Architecture of Headless Ghidra Integration
Headless binary analysis in Ghidra relies on a modular pipeline designed for automation. According to the implementation details in skills/reverse-engineering/tools.md, the workflow separates project management, analysis execution, and result extraction into distinct stages.
Core Components
The headless architecture consists of four primary elements documented in the repository:
analyzeHeadless— The command-line driver located in Ghidra's installation directory that creates temporary projects, imports binaries, and executes analysis pipelines without initializing the Swing GUI.- Ghidra MCP (Message-Channel-Protocol) — A TCP server that exposes Ghidra functionality over port 8765, enabling remote agents to request decompilation and cross-references without re-running full analysis cycles. Configuration details appear in
skills/ghidra-reverse/SKILL.mdlines 56-63. - Post-Processing Scripts — Custom Jython scripts (e.g.,
ExportDecomp.py) executed via the-postScriptparameter to extract specific artifacts like decompiled C code or function signatures. - Tool-Index Manifest — The
skills/tool-index.mdfile generated byskills/scripts/refresh-tool-index.shthat records absolute installation paths, ensuring scripts reference the correctanalyzeHeadlessbinary across different environments.
The Three-Stage Pipeline
As implemented in the reverse-skill framework, headless analysis follows this sequence:
- Project Creation and Import —
analyzeHeadlessinitializes a transient Ghidra project, imports the target binary, and runs the default analyzer suite. - Export and Post-Processing — A Jython script processes the analyzed program, exporting decompiled functions, string tables, or JSON metadata to the filesystem.
- MCP Interaction (Optional) — For interactive automation, the Ghidra MCP server allows downstream tools to query the analyzed project for on-the-fly cross-references and renames without restarting the analysis.
Setting Up the Environment
Before running automated analysis, you must index your Ghidra installation so that scripts can locate the analyzeHeadless binary.
Generating the Tool-Index
The repository uses shell scripts to populate skills/tool-index.md with absolute paths. Run the appropriate script for your platform:
# Linux/macOS
bash skills/scripts/refresh-tool-index.sh
# Windows PowerShell
powershell -NoProfile -ExecutionPolicy Bypass -File skills/scripts/refresh-tool-index.ps1
This updates the tool-index manifest referenced in skills/ghidra-reverse/SKILL.md lines 12-13, allowing automation scripts to resolve Ghidra's location dynamically.
Starting the Ghidra MCP Server (Optional)
If your workflow requires remote querying capabilities, start the MCP server before running headless jobs:
ghidra-mcp --port 8765 &
The default port 8765 and command syntax are documented in skills/ghidra-reverse/SKILL.md lines 58-62. This server enables AI assistants and other agents to request decompilation results via TCP while the headless analysis runs in the background.
Running Headless Analysis
Basic analyzeHeadless Command
The canonical syntax for one-off analysis appears in skills/reverse-engineering/tools.md lines 27-34:
analyzeHeadless /tmp/ghidra_proj myproj \
-import sample.bin \
-postScript ExportDecomp.py
Parameter breakdown:
/tmp/ghidra_proj— Temporary project directory (created if absent)myproj— Project name-import sample.bin— Target binary path-postScript ExportDecomp.py— Jython script executed after automatic analysis completes
Writing Export Scripts
Create Jython scripts that extend GhidraScript to extract specific data. The following pattern exports each function as a separate C file:
# ExportDecomp.py - Jython script for headless execution
from ghidra.app.script import GhidraScript
import os
class ExportDecomp(GhidraScript):
def run(self):
out_dir = "/tmp/decomp_output"
os.makedirs(out_dir, exist_ok=True)
for func in currentProgram.getFunctionManager().getFunctions(True):
decomp = self.decompileFunction(func, 30)
if decomp.decompileCompleted():
src = decomp.getDecompiledFunction().getC()
fname = os.path.join(out_dir, func.getName() + ".c")
with open(fname, "w") as f:
f.write(src)
ExportDecomp().run()
The decompileFunction(func, 30) method invokes Ghidra's decompiler with a 30-second timeout per function. This script runs within the headless JVM environment, giving you full access to the Ghidra API without GUI dependencies.
CI/CD Integration
Because analyzeHeadless requires no user interaction, you can embed it directly into CI pipelines. The following GitHub Actions workflow demonstrates batch analysis using the reverse-skill tool-index pattern:
# .github/workflows/ghidra-headless.yml
name: Ghidra Headless Scan
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Ghidra
run: |
wget https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_10.4_build/ghidra_10.4_PUBLIC_20230802.zip
unzip ghidra_10.4_PUBLIC_20230802.zip -d $HOME
echo "$HOME/ghidra_10.4_PUBLIC/support" >> $GITHUB_PATH
- name: Refresh tool-index
run: bash skills/scripts/refresh-tool-index.sh
- name: Run headless analysis
run: |
analyzeHeadless $HOME/ghidra_proj ghidra_job \
-import path/to/binary \
-postScript ExportDecomp.py
- name: Upload results
uses: actions/upload-artifact@v3
with:
name: decomp
path: /tmp/decomp_output/
This workflow downloads Ghidra, generates the tool-index, processes the binary, and uploads decompiled artifacts—demonstrating how the repository's tool-index system enables portable automation across different runner environments.
Advanced Automation Patterns
Bulk Processing Multiple Binaries
For analyzing dozens of samples, loop over files while reusing the same temporary project or creating fresh ones per binary. The analyzeHeadless syntax documented in skills/reverse-engineering/tools.md supports wildcard imports and script parameters:
for bin in samples/*.bin; do
analyzeHeadless /tmp/ghidra_proj batch_job \
-import "$bin" \
-postScript ExportDecomp.py \
-scriptPath $(pwd)/scripts
done
Selective Function Export
Modify ExportDecomp.py to filter functions by name or entry point before writing files, reducing noise in automated reports:
# Filter example within ExportDecomp.py
if func.getName().startswith("sub_") or "crypto" in func.getName().lower():
# Process only matching functions
continue
Combining with MCP for Interactive Queries
After the headless run completes, keep the project available via the Ghidra MCP server for on-the-fly cross-reference requests. This hybrid approach—batch analysis for heavy lifting, MCP for lightweight queries—optimizes performance in automated reverse engineering pipelines as described in skills/ghidra-reverse/SKILL.md.
Summary
- Headless mode transforms Ghidra into a programmable static-analysis engine via the
analyzeHeadlesscommand-line driver, eliminating GUI overhead. - The tool-index system (
skills/tool-index.md) generated byskills/scripts/refresh-tool-index.shensures scripts locate the correct Ghidra installation across diverse environments. - Jython post-scripts (extending
GhidraScript) execute after automatic analysis to export decompiled C code, function signatures, or custom JSON artifacts. - Ghidra MCP provides a TCP bridge (default port 8765) for remote agents to query analysis results without re-running the full pipeline.
- Full CI/CD integration is achievable because the headless workflow requires no user interaction, supporting automated binary scanning on every commit.
Frequently Asked Questions
What is the difference between Ghidra headless mode and the GUI?
Headless mode runs Ghidra's analysis engine without initializing the Swing graphical interface, using the analyzeHeadless script instead of the ghidraRun launcher. According to the reverse-skill documentation in skills/reverse-engineering/tools.md, headless mode is designed for batch processing and CI environments where no display server is available, while providing identical decompilation and disassembly capabilities.
How do I locate the analyzeHeadless binary in automated environments?
The reverse-skill repository solves this through the tool-index pattern. Run skills/scripts/refresh-tool-index.sh (or .ps1 on Windows) to generate skills/tool-index.md, which records the absolute path to Ghidra's installation directory. Automation scripts then reference this manifest to construct the full path to support/analyzeHeadless, ensuring portability across different machines and container environments.
Can I use Python 3 instead of Jython for Ghidra scripts?
Standard Ghidra headless mode executes scripts within the embedded Jython 2.7 interpreter. While PyGhidra enables Python 3 bindings for certain use cases, the -postScript parameter in analyzeHeadless specifically requires Jython-compatible scripts that extend ghidra.app.script.GhidraScript. For pure Python 3 automation, consider using the Ghidra MCP bridge documented in skills/ghidra-reverse/SKILL.md to query analysis results via TCP from external Python processes.
How does the Ghidra MCP bridge improve automation workflows?
The MCP (Message-Channel-Protocol) bridge exposes Ghidra's API over TCP port 8765, allowing external agents to request specific operations—such as retrieving cross-references (getReferencesTo) or renaming functions—without restarting the analysis. As detailed in skills/ghidra-reverse/SKILL.md, this enables a hybrid workflow where analyzeHeadless performs the heavy initial analysis, while MCP handles lightweight, interactive queries from AI assistants or automation scripts during subsequent processing stages.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →