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

> Master Ghidra headless mode for open-source binary analysis. Automate static analysis, disassembly, and decompilation from the command line. Perfect for batch processing and CI pipelines.

- Repository: [ZhaoXu/reverse-skill](https://github.com/zhaoxuya520/reverse-skill)
- Tags: tutorial
- Published: 2026-08-07

---

**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`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/reverse-engineering/tools.md) and [`skills/ghidra-reverse/SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/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`](https://github.com/zhaoxuya520/reverse-skill/blob/main/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`](https://github.com/zhaoxuya520/reverse-skill/blob/main/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`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/ghidra-reverse/SKILL.md) at lines 56-63.
- **Headless Scripts**: Custom Jython scripts, such as [`ExportDecomp.py`](https://github.com/zhaoxuya520/reverse-skill/blob/main/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:

```bash

# Linux/macOS

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

```

```powershell

# Windows

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

```

This populates [`skills/tool-index.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/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`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/ghidra-reverse/SKILL.md) at lines 12-13.

3. (Optional) Start the Ghidra MCP server if downstream tools need remote access:

```bash
ghidra-mcp --port 8765 &

```

The default port and available commands are documented in the MCP command table in [`skills/ghidra-reverse/SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/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.

```bash
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`](https://github.com/zhaoxuya520/reverse-skill/blob/main/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`](https://github.com/zhaoxuya520/reverse-skill/blob/main/ExportDecomp.py) to dump decompiled artifacts for downstream diffing or AI ingestion.

```python

# 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`](https://github.com/zhaoxuya520/reverse-skill/blob/main/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.

```yaml

# .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`](https://github.com/zhaoxuya520/reverse-skill/blob/main/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`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/tool-index.md)) to manage cross-platform Ghidra paths.
- A **`-postScript`** hook runs Jython scripts like [`ExportDecomp.py`](https://github.com/zhaoxuya520/reverse-skill/blob/main/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`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/scripts/refresh-tool-index.sh) (and a PowerShell variant) to generate [`skills/tool-index.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/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`](https://github.com/zhaoxuya520/reverse-skill/blob/main/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`](https://github.com/zhaoxuya520/reverse-skill/blob/main/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`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/ghidra-reverse/SKILL.md) at lines 57-62.