Ghidra Framework APIs for Program Analysis: Program, Function, and Instruction Interfaces

The three essential Ghidra framework APIs for program analysis are the Program interface (top-level binary container), Function interface (routine representation), and Instruction interface (disassembled machine code), all accessed through the Listing facade in the ghidra.program.model.listing package.

The National Security Agency's Ghidra binary analysis platform exposes a comprehensive Java API for automated reverse engineering. Understanding the core Program, Function, and Instruction interfaces is essential for developing scripts, analyzers, and plugins that interact with disassembled binaries at the framework level.

Core Ghidra Program Analysis APIs

Ghidra's analysis engine centers on four primary interfaces defined in the SoftwareModeling framework. These abstractions provide read-only views of the program database, with modifications handled through transaction-aware methods.

Program Interface – The Top-Level Container

The Program interface represents a single loaded binary image and serves as the root of the object model. Defined in Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/Program.java (lines 40‑127), this interface provides access to the memory map, symbol table, function manager, and program-wide properties.

Key capabilities include:

  • Retrieving the Listing via program.getListing() to access code units
  • Obtaining the FunctionManager via program.getFunctionManager() to enumerate routines
  • Querying language specifications via program.getLanguage() and image base addresses
  • Accessing the data type manager through program.getDataTypeManager()

Function Interface – Routine Representation

The Function interface models a single entry-point routine within the binary. Located in Function.java (lines 33‑170), it exposes the function body, signature, calling convention, and parameter storage.

Critical methods include:

  • getName() – Returns the function's symbol name
  • getSignature() – Provides the FunctionSignature including return type and parameters
  • getBody() – Returns an AddressSetView defining the function's address ranges
  • updateFunction(...) – Modifies calling convention, return type, or parameters

This interface also manages thunk relationships and stack purge sizes, making it essential for control-flow and data-flow analyses.

Instruction Interface – Disassembled Machine Code

The Instruction interface represents a single disassembled machine instruction. Found in Instruction.java (lines 30‑138), it provides access to raw bytes, operands, control flow, and p-code (intermediate representation).

Key functionality includes:

  • getMnemonicString() – Returns the assembly mnemonic
  • getRegister(int opIndex) – Extracts register operands
  • getPcode(boolean includeOverrides) – Generates p-code operations for semantic analysis
  • getFlowType() and getFallThrough() – Determine control-flow behavior

This interface is the primary touchpoint for instruction-level analysis, including operand decoding, delay slot handling, and cross-reference generation.

Listing Interface – The Unified Facade

The Listing interface acts as the central bridge between Program and individual code units. Defined in Listing.java (lines 88‑236), it unifies instructions, data, undefined bytes, and comments under a single query interface.

Essential methods include:

  • getInstructionAt(Address) – Retrieves an instruction by address
  • getFunctions(boolean forward) – Returns a FunctionIterator for enumerating routines
  • getInstructions(AddressSetView, boolean) – Iterates instructions within an address range
  • createInstruction(...) – Creates new instructions during analysis

Access this facade via program.getListing(); it is the entry point for most analysis scripts.

Practical Implementation Examples

The following Java snippets demonstrate common patterns when scripting against the Ghidra framework APIs. These examples work in the Script Manager or as plugin code, relying solely on the public interfaces.

Enumerating All Functions and Signatures

// Assume 'program' is the current Program instance provided by Ghidra
Listing listing = program.getListing();
FunctionIterator funcIter = listing.getFunctions(true); // forward order

while (funcIter.hasNext()) {
    Function func = funcIter.next();
    String name = func.getName();
    String sig  = func.getSignature().getPrototypeString(false, true);
    println(name + " : " + sig);
}

This pattern uses Program.getListing(), Listing.getFunctions(boolean), and Function.getSignature() to extract prototype strings.

Walking Instructions Within a Function

// Get a function by entry address (example address)
Address entry = program.getAddressFactory().getAddress("0x00401000");
Function f = program.getFunctionManager().getFunctionAt(entry);
if (f == null) {
    println("No function at " + entry);
    return;
}

// Iterate over the function body
AddressSetView body = f.getBody();
InstructionIterator it = listing.getInstructions(body, true);
while (it.hasNext()) {
    Instruction ins = it.next();
    println(ins.getAddress() + "  " + ins.getMnemonicString());

    // Print any pure register operands
    for (int i = 0; i < ins.getNumOperands(); i++) {
        Register reg = ins.getRegister(i);
        if (reg != null) {
            println("   operand " + i + " -> " + reg.getName());
        }
    }
}

Key API calls here include Program.getFunctionManager(), Function.getBody(), and Instruction.getRegister(int).

Generating P-code for Semantic Analysis

// Pick an arbitrary address
Address addr = program.getAddressFactory().getAddress("0x00401120");
Instruction ins = listing.getInstructionAt(addr);
if (ins == null) {
    println("No instruction at " + addr);
    return;
}

// Retrieve p-code (without flow overrides)
PcodeOp[] ops = ins.getPcode(false);
println("P-code for " + ins.getAddress() + ":");
for (PcodeOp op : ops) {
    println("   " + op);
}

This demonstrates Listing.getInstructionAt(Address) and Instruction.getPcode(boolean) for retrieving intermediate representation operations.

Source Code Architecture and Key Files

The following files in the NationalSecurityAgency/ghidra repository define the backbone of the program analysis API:

These interfaces are implemented in the ghidra.program.database package (e.g., ProgramDB), ensuring scripts work against any concrete program representation without modification.

Summary

  • The Program interface is the root container for binary images, providing access to memory, symbols, and the Listing facade via methods like getListing() and getFunctionManager().
  • The Function interface represents individual routines with entry points, bodies (AddressSetView), and signatures, accessible through program.getFunctionManager().getFunctionAt().
  • The Instruction interface exposes disassembled machine code, operands, control flow, and p-code generation through listing.getInstructionAt() and instruction.getPcode().
  • The Listing interface serves as the unified entry point for iterating functions and instructions, creating code units, and managing comments.
  • All APIs are defined as Java interfaces in ghidra.program.model.listing, with concrete database-backed implementations in the ghidra.program.database package.

Frequently Asked Questions

What is the relationship between Program and Listing in Ghidra?

The Listing is a component owned by the Program. Access it via program.getListing() to retrieve code units (instructions and data) and create or delete them. While Program manages the binary-wide context (memory, symbols, functions), Listing provides the granular view of disassembled content at specific addresses.

How do I access function parameters using the Ghidra API?

First obtain a Function object via program.getFunctionManager().getFunctionAt(address) or through the Listing. Then call function.getSignature() to retrieve the FunctionSignature, which exposes parameters through getArguments(). Each parameter provides its name, data type, and storage location (register or stack offset).

Can I modify instructions programmatically using these APIs?

Direct modification of Instruction objects is restricted because the interfaces are read-only. To create or modify instructions, use the Listing interface methods such as createInstruction(Address, InstructionPrototype) or clearCodeUnits(). These methods handle transactions, locking, and undo/redo bookkeeping automatically.

Where are the concrete implementations of these interfaces located?

While the API contracts reside in ghidra.program.model.listing, the concrete database-backed implementations live in ghidra.program.database. For example, ProgramDB implements Program, and FunctionDB implements Function. This separation allows scripts to run against flat programs, database-backed programs, or in-memory test fixtures without code changes.

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 →