How to Use Ghidra Headless Mode for Open-Source Binary Analysis: A Complete Workflow

Ghidra headless mode for open-source binary analysis lets you run static analysis, disassembly, and decompilation entirely from the command line without launching the GUI, making it ideal for batch processing and CI pipelines.

Ghidra is the free, open-source reverse-engineering platform developed by the NSA, and driving it headlessly turns it into a programmable static-analysis engine. The zhaoxuya520/reverse-skill repository provides a complete workflow for this, including tool-index management, Jython post-scripts, and optional MCP bridge integration.

Understanding the Headless Architecture

The headless pipeline in the reverse-skill repository consists of three distinct stages, documented across skills/reverse-engineering/tools.md and skills/ghidra-reverse/SKILL.md.

  • Ghidra Core: Performs the underlying static analysis, disassembly, and decompilation. The repository references this in the Ghidra section of skills/reverse-engineering/tools.md.
  • analyzeHeadless: The command-line driver that creates a temporary project, imports a binary, runs the default analysis pipeline, and optionally executes a post-processing script. The canonical syntax is shown in skills/reverse-engineering/tools.md at lines 27-34.
  • Ghidra MCP (Message-Channel-Protocol): Exposes Ghidra functionality over a TCP port, enabling remote agents to request decompilation or cross-references without the UI. This is described in skills/ghidra-reverse/SKILL.md at lines 56-63.
  • Headless Scripts: Custom Jython scripts, such as ExportDecomp.py, that run after import via the -postScript hook to export artifacts.

Setting Up the Environment

Before running headless jobs, you must tell the reverse-skill framework where Ghidra is installed.

  1. Install Ghidra from the official NSA release page or use the repository's bootstrap script.
  2. Generate the tool index so automation scripts can resolve the Ghidra path:

# Linux/macOS

bash skills/scripts/refresh-tool-index.sh

# Windows

powershell -NoProfile -ExecutionPolicy Bypass -File skills/scripts/refresh-tool-index.ps1

This populates skills/tool-index.md with the absolute path to the Ghidra executable, which the ghidra-reverse skill reads at startup, as noted in skills/ghidra-reverse/SKILL.md at lines 12-13.

  1. (Optional) Start the Ghidra MCP server if downstream tools need remote access:
ghidra-mcp --port 8765 &

The default port and available commands are documented in the MCP command table in skills/ghidra-reverse/SKILL.md at lines 57-62.

Running a One-Off Headless Analysis

The analyzeHeadless utility is the entry point for all headless work. A minimal invocation creates a transient project, imports the target, runs the default analyzers, and executes a post-script.

analyzeHeadless /tmp/ghidra_proj myproj \
  -import sample.bin \
  -postScript ExportDecomp.py
  • -import sample.bin specifies the target binary.
  • -postScript ExportDecomp.py hooks a Jython script that runs after automatic analysis completes.

This exact command pattern is illustrated in skills/reverse-engineering/tools.md at lines 27-34.

Automating Decompilation with Jython Post-Scripts

The real power of Ghidra headless mode for open-source binary analysis comes from post-processing scripts that extract structured data. The reverse-skill workflow expects scripts like ExportDecomp.py to dump decompiled artifacts for downstream diffing or AI ingestion.


# ExportDecomp.py – Jython script for Ghidra headless

from ghidra.app.script import GhidraScript
import json, 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)

When analyzeHeadless completes, you will have one .c file per function in /tmp/decomp_output, ready for patching, auditing, or further analysis.

Integrating the Ghidra MCP Bridge

For interactive workflows that follow an initial headless pass, the repository supports the Ghidra MCP bridge. After a binary is imported and analyzed, a background MCP server can field requests for cross-references, renames, and additional decompilations without re-running the full pipeline.

According to skills/ghidra-reverse/SKILL.md at lines 57-62, agents connect to the exposed TCP port and issue MCP commands while the project remains open. This separates long-running batch analysis from lightweight, on-the-fly queries.

CI/CD Integration for Batch Binary Analysis

Because headless mode is entirely non-interactive, you can embed it directly into a GitHub Actions workflow.


# .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" >> $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 configuration demonstrates how the repository's tool-index and headless sections are designed for seamless continuous integration.

Advanced Headless Workflows

The reverse-skill repository documents several advanced patterns:

  • Bulk decompilation: Loop over directories of binaries in a shell script, reusing or recreating the temporary project for each file. The analyzeHeadless syntax in skills/reverse-engineering/tools.md at lines 27-34 supports this.
  • Selective function export: Filter inside the post-script by func.getName() or func.getEntryPoint() before writing files.
  • P-Code and deobfuscation: Invoke built-in Jython utilities for intermediate representation analysis, referenced in the repository's advanced tools documentation.

Summary

  • Ghidra headless mode drives the entire analysis pipeline from the command line via analyzeHeadless.
  • The zhaoxuya520/reverse-skill repository uses a tool-index (skills/tool-index.md) to manage cross-platform Ghidra paths.
  • A -postScript hook runs Jython scripts like ExportDecomp.py to extract decompiled C, function signatures, or JSON after import.
  • The optional Ghidra MCP bridge exposes the analyzed project over TCP for remote querying without UI overhead.
  • The workflow is fully automatable in CI/CD pipelines such as GitHub Actions.

Frequently Asked Questions

What is the analyzeHeadless command used for in Ghidra?

analyzeHeadless is the official command-line driver shipped with Ghidra. It creates a temporary project, imports a binary, runs the default analysis pipeline, and optionally executes a user-provided Jython script via -postScript, all without opening the GUI.

How does the reverse-skill repository locate my Ghidra installation?

The repository provides skills/scripts/refresh-tool-index.sh (and a PowerShell variant) to generate skills/tool-index.md. This manifest records the absolute path to Ghidra for the current host, which skills like ghidra-reverse read at runtime, as documented in skills/ghidra-reverse/SKILL.md at lines 12-13.

Can I export decompiled code automatically in headless mode?

Yes. You supply a Jython script such as ExportDecomp.py to the -postScript argument. After Ghidra finishes its automatic analysis, the script iterates over the program's functions and writes each decompiled body to disk.

Is it possible to query Ghidra remotely after a headless import?

Yes. By starting the Ghidra MCP server (ghidra-mcp --port 8765), you can keep the project open and request cross-references, renames, or additional decompilations from remote agents via TCP, as documented in skills/ghidra-reverse/SKILL.md at lines 57-62.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →