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
Listingviaprogram.getListing()to access code units - Obtaining the
FunctionManagerviaprogram.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 namegetSignature()– Provides theFunctionSignatureincluding return type and parametersgetBody()– Returns anAddressSetViewdefining the function's address rangesupdateFunction(...)– 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 mnemonicgetRegister(int opIndex)– Extracts register operandsgetPcode(boolean includeOverrides)– Generates p-code operations for semantic analysisgetFlowType()andgetFallThrough()– 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 addressgetFunctions(boolean forward)– Returns aFunctionIteratorfor enumerating routinesgetInstructions(AddressSetView, boolean)– Iterates instructions within an address rangecreateInstruction(...)– 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:
-
Program.java–Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/Program.javadefines the top-level program model with accessors for memory, symbols, and the listing. -
Function.java–Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/Function.javaspecifies routine representation, signature handling, and parameter APIs. -
Instruction.java–Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/Instruction.javadeclares operand access, flow types, and p-code generation methods. -
Listing.java–Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/Listing.javaprovides the façade for creating and querying code units. -
FunctionManager.java– Interface definition for the global function map, with concrete implementation inghidra/program/database/function/FunctionManagerDB. -
ProgramBasedDataTypeManager.java–Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/ProgramBasedDataTypeManager.javamanages data types tied to specific program instances.
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
Programinterface is the root container for binary images, providing access to memory, symbols, and theListingfacade via methods likegetListing()andgetFunctionManager(). - The
Functioninterface represents individual routines with entry points, bodies (AddressSetView), and signatures, accessible throughprogram.getFunctionManager().getFunctionAt(). - The
Instructioninterface exposes disassembled machine code, operands, control flow, and p-code generation throughlisting.getInstructionAt()andinstruction.getPcode(). - The
Listinginterface 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 theghidra.program.databasepackage.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →