Skip to main content

Overview

The GhidraScript class is the foundation for writing custom scripts in Ghidra. It extends FlatProgramAPI and provides access to program analysis, manipulation, and user interaction capabilities.

Creating a Script

All Ghidra scripts must:
  1. Be written in Java
  2. Extend ghidra.app.script.GhidraScript
  3. Implement the run() method
  4. Include a description comment at the top (lines starting with //)

Basic Template

// TODO write a description for this script
// @category Examples

import ghidra.app.script.GhidraScript;

public class MyScript extends GhidraScript {
    @Override
    public void run() throws Exception {
        // Your script code here
    }
}

Script State Variables

Ghidra automatically provides these instance variables when a script runs:
VariableTypeDescription
currentProgramProgramThe active program being analyzed
currentAddressAddressThe current cursor location in the tool
currentLocationProgramLocationThe current program location (may be null)
currentSelectionProgramSelectionThe current selection (may be null)
currentHighlightProgramSelectionThe current highlight (may be null)
monitorTaskMonitorTask monitor for tracking progress

Core Methods

Abstract Methods

protected abstract void run() throws Exception
The main entry point for your script. This is where you implement your script logic.

Output Methods

public void println(String message)
Prints a message to the console and Ghidra’s log.
println("Processing function at: " + currentAddress);
public void print(String message)
Prints a message without a newline.
public void printf(String message, Object... args)
Prints a formatted message using C-style printf formatting.
printf("Found %d functions in range\n", functionCount);
public void printerr(String message)
Prints an error message to stderr and Ghidra’s error log.

User Input Methods

GhidraScript provides numerous ask* methods for user input:
public int askInt(String title, String message)
Prompts the user to enter an integer value.
int count = askInt("Count", "How many iterations?");
public Address askAddress(String title, String message)
Prompts the user to enter an address.
Address start = askAddress("Start Address", "Enter start address:");
public String askString(String title, String message)
public String askString(String title, String message, String defaultValue)
Prompts the user to enter a string.
String name = askString("Function Name", "Enter function name:", "myFunction");
public boolean askYesNo(String title, String message)
Prompts the user with a yes/no question.
boolean proceed = askYesNo("Confirm", "Continue with analysis?");
public <T> T askChoice(String title, String message, List<T> choices, T defaultChoice)
Prompts the user to select from a list of choices.
String dwarf = askChoice("Choice", "Pick one:",
    Arrays.asList("grumpy", "dopey", "sleepy"), "sleepy");
public File askFile(String title, String approveButtonText)
Prompts the user to select a file.
File file = askFile("Input File", "Choose file:");
public File askDirectory(String title, String approveButtonText)
Prompts the user to select a directory.

Running Other Scripts

public void runScript(String scriptName) throws Exception
public void runScript(String scriptName, String[] scriptArguments) throws Exception
Runs another script by name. The called script shares the same GhidraState.
runScript("AnalyzeFunction.java");
runScript("ProcessData.java", new String[]{"arg1", "arg2"});
public GhidraState runScriptPreserveMyState(String scriptName) throws Exception
Runs a script without allowing it to modify this script’s state.

Analysis Control

public AnalysisMode getScriptAnalysisMode()
Returns the analysis mode for this script. Override to control auto-analysis behavior. Analysis Modes:
  • AnalysisMode.ENABLED - Script runs normally with auto-analysis responding to changes
  • AnalysisMode.DISABLED - Auto-analysis is disabled during script execution
  • AnalysisMode.SUSPENDED - Analysis is suspended and will run after script completes
@Override
public AnalysisMode getScriptAnalysisMode() {
    return AnalysisMode.SUSPENDED;
}

Utility Methods

public final boolean isRunningHeadless()
Returns true if the script is running in headless (non-GUI) mode.
if (isRunningHeadless()) {
    println("Running in headless mode");
}
public final String getScriptName()
Returns the name of the current script.
public String[] getScriptArgs()
Returns script-specific arguments passed to the script.
public void setScriptArgs(String[] scriptArgs)
Sets script-specific arguments.

Complete Example

// Demonstrates various GhidraScript capabilities
// @category Examples

import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.*;

public class ExampleScript extends GhidraScript {

    @Override
    public void run() throws Exception {
        // Get user input
        Address start = askAddress("Start Address", "Enter start address:");
        int count = askInt("Count", "How many functions to process?");
        
        // Print information
        println("Processing " + count + " functions from " + start);
        
        // Access current program
        FunctionManager funcMgr = currentProgram.getFunctionManager();
        Function func = funcMgr.getFunctionContaining(start);
        
        if (func != null) {
            printf("Function: %s at %s\n", func.getName(), func.getEntryPoint());
        } else {
            printerr("No function found at " + start);
        }
        
        // Check if running headless
        if (isRunningHeadless()) {
            println("Running in headless mode");
        }
    }
}

Properties Files

Scripts can use .properties files to pre-populate values for ask* methods:
  1. Create a file named MyScript.properties in the same directory as MyScript.java
  2. Add key-value pairs for default values
  3. In GUI mode, these values pre-populate input fields
  4. In headless mode, these values are used automatically
Example: AskScript.properties
FILE=/path/to/default/file
Directory=/path/to/default/directory
integer_1=42
string=default value

Script Arguments

Scripts can accept command-line arguments when run in headless mode:
analyzeHeadless /path/to/project ProjectName -process binary.exe \
    -postScript MyScript.java arg1 arg2 arg3
Access arguments in your script:
String[] args = getScriptArgs();
if (args.length > 0) {
    println("First argument: " + args[0]);
}

Best Practices

  1. Always check for null - State variables like currentProgram may be null
  2. Use monitor.checkCancelled() - Allow users to cancel long-running operations
  3. Handle exceptions - Wrap risky operations in try-catch blocks
  4. Clean up resources - Override cleanup(boolean success) to release resources
  5. Provide meaningful output - Use println() to keep users informed of progress
  6. Use transactions - When modifying the program, changes are automatically wrapped in transactions

See Also

Build docs developers (and LLMs) love