# How to Use Ghidra Headless Mode for Automated Batch Processing

> Automate your binary analysis with Ghidra headless mode. Learn to import, analyze, and script binaries using this powerful command-line tool from the NSA.

- Repository: [National Security Agency/ghidra](https://github.com/NationalSecurityAgency/ghidra)
- Tags: how-to-guide
- Published: 2026-03-04

---

**Ghidra headless mode is a command-line interface that runs the full analysis engine without the GUI, enabling automated binary import, analysis, and scripting via the `analyzeHeadless` script located in `Ghidra/RuntimeScripts/Common/support/`.**

The National Security Agency's Ghidra framework provides a powerful headless capability for reverse engineering automation. This mode allows security researchers and DevSecOps pipelines to process binaries at scale without launching the graphical interface. By leveraging the `AnalyzeHeadless` class and specific command-line flags, you can create projects, execute scripts, and generate reports entirely from the terminal.

## Core Architecture Components

The headless implementation relies on three primary components that disable GUI functionality while preserving the full analysis engine.

**`analyzeHeadless` Shell Script**: Located at `Ghidra/RuntimeScripts/Common/support/analyzeHeadless`, this entry point builds the Java classpath, sets the `SystemUtilities.isHeadless` system property to `true`, and launches the `ghidra.app.util.headless.AnalyzeHeadless` class.

**`AnalyzeHeadless` Java Class**: Found in [`Ghidra/Features/Base/src/main/java/ghidra/app/util/headless/AnalyzeHeadless.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Features/Base/src/main/java/ghidra/app/util/headless/AnalyzeHeadless.java), this class parses command-line arguments, manages project creation, handles file imports via the `-import` flag, and orchestrates pre- and post-processing script execution.

**System Utilities Flag**: The `SystemUtilities.isHeadless` property, defined in [`Ghidra/Framework/Utility/src/main/java/ghidra/util/SystemUtilities.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Framework/Utility/src/main/java/ghidra/util/SystemUtilities.java), acts as a global boolean consulted throughout the codebase. When true, it prevents UI components and Swing utilities from loading, ensuring compatibility with servers, CI pipelines, and Docker containers.

## Essential Command-Line Flags

The `analyzeHeadless` script accepts specific flags to control the batch processing pipeline:

- **`-import <path>`**: Specifies a single file, directory, or wildcard pattern to import into the project.
- **`-recursive`**: Enables recursive directory traversal when importing multiple binaries.
- **`-preScript <script> [args...]`**: Executes a script before analysis begins, passing optional arguments.
- **`-postScript <script> [args...]`**: Executes a script after analysis completes.
- **`-noanalysis`**: Skips the built-in auto-analysis phase entirely.
- **`-log <file>`**: Writes Ghidra's console output to a specified file.
- **`-scriptlog <file>`**: Captures output specifically from script execution.
- **`-librarySearchPaths <paths>`**: Defines additional directories for resolving shared library dependencies.
- **`-max-cpu <n>`**: Limits CPU usage to *n* cores during the analysis phase.

## Six-Step Batch Processing Workflow

A typical headless session follows this automated sequence:

1. **Project Initialization**: Create or open a Ghidra project at the specified directory path.
2. **Binary Import**: Load target files using `-import` with optional `-recursive` scanning for bulk operations.
3. **Pre-Processing**: Execute `-preScript` scripts to prepare binaries, rename sections, or configure loaders.
4. **Analysis Phase**: Run the default analyzer suite unless `-noanalysis` is specified.
5. **Post-Processing**: Execute `-postScript` scripts to extract data, export symbols, or delete temporary files.
6. **Logging**: Capture all system and script output via `-log` and `-scriptlog` for audit trails and debugging.

## Practical Automation Examples

### Example 1: Simple Import with Automatic Analysis

```bash
<GHIDRA_INSTALL>/support/analyzeHeadless \
    /tmp/ghidra_projects myProject \
    -import /opt/binaries/*.exe \
    -log /tmp/ghidra_log.txt

```

This command creates `myProject` under `/tmp/ghidra_projects`, imports all `.exe` files from `/opt/binaries`, runs the default analyzers, and writes operational logs to [`/tmp/ghidra_log.txt`](https://github.com/NationalSecurityAgency/ghidra/blob/main//tmp/ghidra_log.txt).

### Example 2: Scripted Pipeline with Analysis Disabled

```bash
<GHIDRA_INSTALL>/support/analyzeHeadless \
    /tmp/ghidra_projects myProject \
    -import /opt/binaries/myapp.bin \
    -preScript MyPrepScript.java arg1 \
    -noanalysis \
    -postScript ExportSymbols.py \
    -scriptlog /tmp/post_script.log \
    -log /tmp/run.log

```

Here, [`MyPrepScript.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/MyPrepScript.java) prepares the binary before processing. Analysis is skipped via `-noanalysis`, and [`ExportSymbols.py`](https://github.com/NationalSecurityAgency/ghidra/blob/main/ExportSymbols.py) extracts symbols afterward. Separate log files capture script output and runtime events according to the NSA Ghidra source code implementation.

### Example 3: Recursive Batch Processing with Resource Limits

```bash
<GHIDRA_INSTALL>/support/analyzeHeadless \
    /tmp/ghidra_projects myProject \
    -import /opt/binaries -recursive \
    -librarySearchPaths /opt/shared_libs \
    -max-cpu 4 \
    -log /tmp/recursive_import.log

```

This recursively processes all files under `/opt/binaries`, searches `/opt/shared_libs` for dependencies, constrains processing to four CPU cores, and logs the entire session to `/tmp/recursive_import.log`.

## Scripting Considerations for Headless Execution

When writing scripts for headless mode, note that **GhidraScript API** methods requiring user interaction behave differently. According to the implementation in [`AnalyzeHeadless.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/AnalyzeHeadless.java), methods like `askString()` or `askFile()` either become no-operations or throw `ImproperUseException` when `SystemUtilities.isInHeadlessMode()` returns true. Scripts must handle data programmatically rather than interactively.

Both Java and Jython (Python 2.7) scripts are supported. Place custom scripts in Ghidra's script directories or specify absolute paths when invoking via `-preScript` or `-postScript`.

## Summary

- **Ghidra headless mode** enables full binary analysis without the GUI using the `analyzeHeadless` script in `Ghidra/RuntimeScripts/Common/support/`.
- The entry point class [`AnalyzeHeadless.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/AnalyzeHeadless.java) manages project creation, import, and script execution while the `SystemUtilities.isHeadless` flag prevents UI initialization.
- Use **`-import`** for file ingestion, **`-preScript`** and **`-postScript`** for automation, and **`-noanalysis`** to skip auto-analysis when needed.
- Output control via **`-log`** and **`-scriptlog`** ensures capture of both Ghidra system messages and script-specific output.
- Recursive processing, library resolution paths, and CPU throttling support enterprise-scale batch operations.

## Frequently Asked Questions

### Can I run Ghidra headless mode inside a Docker container?

Yes. The `analyzeHeadless` script automatically sets `SystemUtilities.isHeadless=true`, which disables all Swing and AWT dependencies. Since the mode never attempts to initialize a graphical display, it runs natively in containerized environments without requiring X11 forwarding or virtual displays.

### What happens if my script calls a GUI dialog in headless mode?

According to the Ghidra source code, calling interactive methods like `askString()` or `askFile()` from the `GhidraScript` API during headless execution results in either a no-operation or an `ImproperUseException`. Scripts intended for batch processing must use non-interactive alternatives or pre-configure all parameters before execution.

### How do I process thousands of binaries efficiently?

Use the **`-recursive`** flag combined with **`-max-cpu`** to limit resource consumption. For massive-scale operations, invoke multiple `analyzeHeadless` instances in parallel across different project directories, ensuring each instance writes to dedicated `-log` files to prevent I/O conflicts.

### Where is the headless mode documentation located?

The authoritative documentation resides in [`Ghidra/RuntimeScripts/Common/support/analyzeHeadlessREADME.md`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/RuntimeScripts/Common/support/analyzeHeadlessREADME.md) within the NSA Ghidra repository. This file contains the complete flag reference, environment variable requirements, and advanced usage patterns for the `AnalyzeHeadless` class.