Skip to content

olivercase/ghidra_headless

Ghidra Headless Automation Suite

License: MIT Ghidra Java Platform

A collection of scripts for automating Ghidra's headless analyser — batch-decompile binaries, export filtered C code and Markdown reports, and extract constants from memory, all without touching the GUI.


Contents


Features

  • Automatic Ghidra discoveryrun_ghidra_headless.sh searches common macOS and Linux install paths so you rarely need to set GHIDRA_HOME manually.
  • Regex-filtered decompilationExportDecompFiltered.java matches functions by name pattern and exports clean C source alongside Markdown metadata (call trees, entry points, signatures).
  • Constant extractionExtractConstants.java reads hardcoded doubles or floats from specific memory addresses and prints them to the console or a file.
  • Extensible script base — the included Java examples are intentionally minimal; drop in new GhidraScript subclasses and pass them straight to --post-script.

Requirements

  • Ghidra 10.x or 11.x installed locally
  • JDK 17 or later (JDK 21 recommended for Ghidra 11.x)
  • Bash 4+ (macOS ships Bash 3 — install a newer version via Homebrew if needed)

Installation

git clone https://github.com/olivercase/ghidra_headless.git
cd ghidra_headless
chmod +x run_ghidra_headless.sh

No build step is required. Ghidra compiles the .java scripts at runtime.

If your Ghidra installation is in a non-standard location, export the environment variable before running:

export GHIDRA_HOME=/path/to/ghidra_11.x_PUBLIC

Usage

Basic import and decompile

./run_ghidra_headless.sh \
  --import /path/to/target_binary \
  --post-script ExportDecompFiltered.java /path/to/output_dir "^FUN_.*"

Specify a project directory and name

./run_ghidra_headless.sh \
  --ghidra-home /Applications/ghidra_11.0.1_PUBLIC \
  --project-dir ~/ghidra_projects \
  --project-name my_analysis \
  --import /path/to/target_binary \
  --post-script ExportDecompFiltered.java ./out "^sub_"

Extract constants from known addresses

./run_ghidra_headless.sh \
  --import /path/to/target_binary \
  --post-script ExtractConstants.java

Pass additional analyzeHeadless flags

Use -- to forward arguments directly to Ghidra:

./run_ghidra_headless.sh \
  --import /path/to/target_binary \
  -- -noanalysis -readOnly

Run ./run_ghidra_headless.sh --help for the full option reference.


Scripts

run_ghidra_headless.sh

Thin Bash wrapper around Ghidra's analyzeHeadless launcher.

Flag Default Description
--ghidra-home PATH auto-detected Path to Ghidra installation root
--project-dir PATH ./ghidra_projects Directory for Ghidra project files
--project-name NAME tfm_analysis Ghidra project name
--import FILE Binary to import and analyse
--post-script SCRIPT [args…] Script to run after analysis, with optional arguments
-- Forward remaining arguments to analyzeHeadless

Ghidra home is resolved in this order: --ghidra-home$GHIDRA_HOME → automatic path search.


ExportDecompFiltered.java

Decompiles every function whose name matches a regex and writes two files per function into the output directory.

Arguments (passed after the script name):

ExportDecompFiltered.java <output_dir> <regex>

Output per matched function:

File Content
<name>-<address>.c Decompiled C source
<name>-<address>.md Metadata: entry point, signature, call tree, callers

A decomp_summary.txt is also written summarising exported, failed, and skipped counts.


ExtractConstants.java

Reads double values from three hardcoded memory addresses and prints them via println. Edit the address literals in the script to target your binary.


ExtractFloat.java

Reads a single float from a hardcoded address and writes it to sampling_freq.txt in the working directory. A minimal example for adapting to other data types.


Example output

Running ExportDecompFiltered.java against a binary with the pattern ^FUN_ produces:

FUN_007baf30-007baf30.md

# FUN_007baf30

- Entry: 007baf30
- Signature: `undefined FUN_007baf30(void)`

## Calls
- FUN_007c9850 @ 007c9850
- FUN_006ea100 @ 006ea100
- FUN_006e9ec0 @ 006e9ec0

## Called By
- FUN_00801240 @ 00801240

FUN_007baf30-007baf30.c

void FUN_007baf30(int param_1)
{
    uint uVar1;
    uVar1 = (uint)*(ushort *)(param_1 + 0x802);
    if (uVar1 < 0x1202) {
        /* ... */
    }
}

decomp_summary.txt

Program: target_binary
Regex: ^FUN_.*

OK: FUN_007baf30 @ 007baf30
OK: FUN_007c9850 @ 007c9850
...

Exported: 142
Failed:   3
Skipped (regex mismatch): 891

Contributing

Contributions are welcome. To propose a change:

  1. Fork the repository and create a feature branch.
  2. Follow the style of existing scripts — keep Java scripts self-contained GhidraScript subclasses.
  3. Open a pull request with a clear description of what the script does and why it is useful.

Please open an issue before starting significant new work so the direction can be agreed on first.


Licence

Distributed under the MIT Licence. See LICENSE for details.


Maintained by Oliver Case.

About

Automated Ghidra headless scripts for batch decompilation, metadata extraction, and programmatic memory constant retrieval.

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors