Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/NationalSecurityAgency/ghidra/llms.txt

Use this file to discover all available pages before exploring further.

Program Model

The Program interface is the central abstraction for representing executable binaries in Ghidra. It extends DomainObject and provides access to all aspects of a program’s structure.
// From ghidra/program/model/listing/Program.java:40-53
public interface Program extends DataTypeManagerDomainObject, ProgramArchitecture {
    Listing getListing();
    Memory getMemory();
    SymbolTable getSymbolTable();
    FunctionManager getFunctionManager();
    ReferenceManager getReferenceManager();
    BookmarkManager getBookmarkManager();
    EquateTable getEquateTable();
    ExternalManager getExternalManager();
    RelocationTable getRelocationTable();
    ProgramBasedDataTypeManager getDataTypeManager();
}

Program Components

A program is divided into several major subsystems, each managed by a dedicated interface.

Memory

The memory subsystem manages the program’s address space and byte storage.
// From ghidra/program/model/mem/Memory.java:30-79
public interface Memory extends AddressSetView {
    Program getProgram();
    
    // Address set queries
    AddressSetView getLoadedAndInitializedAddressSet();
    AddressSetView getAllInitializedAddressSet();
    AddressSetView getExecuteSet();
    
    // Block management
    MemoryBlock[] getBlocks();
    MemoryBlock getBlock(Address addr);
    MemoryBlock getBlock(String blockName);
    
    // Byte access
    byte getByte(Address addr);
    void setByte(Address addr, byte value);
    int getBytes(Address addr, byte[] dest);
    void setBytes(Address addr, byte[] source);
}

Memory Blocks

Memory is organized into contiguous blocks:
public interface MemoryBlock extends Comparable<MemoryBlock> {
    String getName();
    Address getStart();
    Address getEnd();
    long getSize();
    
    boolean isRead();
    boolean isWrite();
    boolean isExecute();
    boolean isVolatile();
    
    boolean isInitialized();
    boolean isMapped();
    boolean isLoaded();
    boolean isOverlay();
}
Block Types:

Initialized

Contains specific data loaded from the binary file

Uninitialized

Defines a region but content is unknown (e.g., BSS)

Byte-Mapped

Maps to another region with byte-level mapping

Bit-Mapped

Maps to bits in another region (1 byte = 1 bit)
From ghidra/program/model/mem/Memory.java:43-56

Creating Memory Blocks

// Initialized block from byte array
MemoryBlock block = memory.createInitializedBlock(
    ".text",              // Block name
    addr(0x401000),       // Start address
    bytes,                // Initial data
    false                 // Overlay?
);

// Uninitialized block
MemoryBlock bss = memory.createUninitializedBlock(
    ".bss",
    addr(0x500000),
    0x1000,               // Size
    false
);

// Byte-mapped block (mirror another region)
MemoryBlock mapped = memory.createByteMappedBlock(
    "mirror",
    addr(0x600000),
    addr(0x401000),       // Maps to .text
    0x1000
);
All block operations require exclusive access and should be performed within a transaction.

Overlay Blocks

Overlay address spaces provide alternate contexts for memory:
// Create overlay space
MemoryBlock overlay = memory.createInitializedBlock(
    "overlay_1",
    addr("overlay_1::0x401000"),  // Note address space prefix
    bytes,
    true                           // Overlay = true
);
Use Cases:
  • Multiple executable contexts (RTOS tasks)
  • Paged memory architectures
  • Bank-switched memory
  • Alternate code paths
Overlays have limitations during analysis. References between overlay and base memory may not be discovered automatically.

Address Spaces

Ghidra supports multiple address spaces within a single program.

Address Interface

// From ghidra/program/model/address/Address.java:23-30
public interface Address extends Comparable<Address> {
    AddressSpace getAddressSpace();
    long getOffset();
    
    Address add(long displacement);
    Address subtract(long displacement);
    long subtract(Address addr);
    
    boolean isMemoryAddress();
    boolean isExternalAddress();
}

AddressSpace Types

From ghidra/program/model/address/AddressSpace.java:28-89
public interface AddressSpace extends Comparable<AddressSpace> {
    // Physical memory (loaded into RAM)
    public static final int TYPE_RAM = 1;
    
    // Processor registers
    public static final int TYPE_REGISTER = 4;
    
    // Stack-relative (signed offsets)
    public static final int TYPE_STACK = 5;
    
    // Non-loaded data (file headers, debug sections)
    public static final int TYPE_OTHER = 7;
    
    // External library references
    public static final int TYPE_EXTERNAL = 10;
    
    String getName();
    int getSpaceID();
    int getSize();                    // Address width in bits
    int getAddressableUnitSize();     // Bytes per address unit
}
Common Address Spaces:
SpaceTypeDescription
ramRAMPhysical memory
registerREGISTERCPU registers
stackSTACKStack-relative addressing
EXTERNALEXTERNALExternal symbols
OTHEROTHERNon-loaded data
constCONSTANTAnalysis constants
uniqueUNIQUETemporary values

Address Arithmetic

Address addr = program.getAddressFactory().getAddress("ram:0x401000");

// Add offset
Address next = addr.add(4);           // ram:0x401004

// Subtract addresses
long diff = next.subtract(addr);      // 4

// Address comparison
if (addr.compareTo(next) < 0) {
    // addr comes before next
}
Use AddressSet and AddressRange for efficient representation of address collections:
AddressSet set = new AddressSet();
set.add(new AddressRangeImpl(start, end));
set.add(anotherAddress);

if (set.contains(addr)) {
    // Address is in set
}

Listing

The listing provides access to code units, instructions, and data:
public interface Listing {
    CodeUnit getCodeUnitAt(Address addr);
    CodeUnit getCodeUnitContaining(Address addr);
    CodeUnit getCodeUnitAfter(Address addr);
    CodeUnit getCodeUnitBefore(Address addr);
    
    Instruction getInstructionAt(Address addr);
    Instruction getInstructionContaining(Address addr);
    
    Data getDataAt(Address addr);
    Data getDefinedDataAt(Address addr);
    Data createData(Address addr, DataType dataType);
}

Code Units

Code units are the atomic elements of the listing:
public interface CodeUnit {
    Address getAddress();
    Address getMinAddress();
    Address getMaxAddress();
    int getLength();
    byte[] getBytes();
    
    String getLabel();
    String getComment(int commentType);
    void setComment(int commentType, String comment);
}
Code Unit Types:
  • Instruction - Disassembled processor instruction
  • Data - Defined data with a specific type
  • Undefined - Unanalyzed bytes

Instructions

public interface Instruction extends CodeUnit {
    String getMnemonicString();
    int getNumOperands();
    Object[] getOpObjects(int opIndex);
    Address[] getReferencesFrom();
    FlowType getFlowType();
    boolean isFallthrough();
    Address getFallThrough();
}

Data

public interface Data extends CodeUnit {
    DataType getDataType();
    boolean isDefined();
    int getNumComponents();
    Data getComponent(int index);
    Object getValue();
}

Symbol Table

The symbol table manages labels, functions, and namespaces:
public interface SymbolTable {
    Symbol getPrimarySymbol(Address addr);
    Symbol[] getSymbols(Address addr);
    Symbol getSymbol(String name, Namespace namespace);
    
    Symbol createLabel(Address addr, String name, Namespace namespace, 
                      SourceType source);
    
    SymbolIterator getSymbols(String name);
    SymbolIterator getSymbols(Namespace namespace);
    SymbolIterator getAllSymbols(boolean includeDynamicSymbols);
}

Symbols

public interface Symbol {
    String getName();
    Address getAddress();
    Namespace getParentNamespace();
    SymbolType getSymbolType();
    SourceType getSource();
    boolean isPrimary();
    boolean isDynamic();
    boolean isExternal();
}
Symbol Types:
  • FUNCTION - Function entry point
  • LABEL - Address label
  • NAMESPACE - Namespace container
  • CLASS - Class namespace
  • PARAMETER - Function parameter
  • LOCAL_VAR - Local variable
  • GLOBAL_VAR - Global variable

Namespaces

public interface Namespace {
    String getName();
    String getName(boolean includeNamespacePath);
    Namespace getParentNamespace();
    Symbol getSymbol();
}
Namespaces organize symbols hierarchically:
Global
  └─ MyClass
      ├─ method1
      └─ method2
  └─ AnotherClass
      └─ function

Function Manager

Manages functions and their properties:
public interface FunctionManager {
    Function getFunctionAt(Address entryPoint);
    Function getFunctionContaining(Address addr);
    
    Function createFunction(String name, Address entryPoint, 
                           AddressSetView body, SourceType source);
    
    FunctionIterator getFunctions(boolean forward);
    FunctionIterator getFunctions(AddressSetView asv, boolean forward);
    int getFunctionCount();
}

Functions

public interface Function extends Namespace {
    Address getEntryPoint();
    AddressSetView getBody();
    
    Parameter[] getParameters();
    Parameter getReturn();
    Variable[] getLocalVariables();
    
    String getPrototypeString(boolean includeName, boolean includeReturn);
    void setCustomVariableStorage(boolean hasCustomVariableStorage);
}

Reference Manager

Tracks all memory references and cross-references:
public interface ReferenceManager {
    Reference addMemoryReference(Address fromAddr, Address toAddr, 
                                RefType type, SourceType sourceType, 
                                int opIndex);
    
    Reference[] getReferencesFrom(Address addr);
    Reference[] getReferencesTo(Address addr);
    ReferenceIterator getReferencesTo(Address addr);
    
    void delete(Reference ref);
}
Reference Types:
  • READ - Data read
  • WRITE - Data write
  • UNCONDITIONAL_JUMP - Direct jump
  • CONDITIONAL_JUMP - Conditional branch
  • UNCONDITIONAL_CALL - Function call
  • FALL_THROUGH - Sequential flow
  • EXTERNAL_REF - Reference to external symbol

Data Types

Programs have an associated data type manager:
public interface ProgramBasedDataTypeManager extends DataTypeManager {
    DataType resolve(DataType dataType, DataTypeConflictHandler handler);
    Category getCategory(CategoryPath path);
    DataType getDataType(String dataTypePath);
    void addDataTypeManagerListener(DataTypeManagerChangeListener listener);
}

Built-in Data Types

  • Primitives: byte, word, dword, qword
  • Signed: sbyte, short, int, long
  • Floating: float, double
  • Text: string, unicode
  • Pointers: pointer, pointer32, pointer64

Custom Data Types

// Structure
Structure struct = new StructureDataType("MyStruct", 0);
struct.add(IntegerDataType.dataType, "field1", null);
struct.add(PointerDataType.dataType, "field2", null);

// Array
Array arr = new ArrayDataType(IntegerDataType.dataType, 10, 4);

// Typedef
Typedef td = new TypedefDataType("DWORD", IntegerDataType.dataType);

Program Properties

Programs store metadata in property lists:
Options options = program.getOptions(Program.PROGRAM_INFO);
options.setString("Compiler", "gcc");
options.setString("Executable Format", "ELF");

boolean analyzed = options.getBoolean(Program.ANALYZED_OPTION_NAME, false);
From ghidra/program/model/listing/Program.java:54-64

Language and Architecture

public interface Program extends ProgramArchitecture {
    Language getLanguage();
    CompilerSpec getCompilerSpec();
    int getDefaultPointerSize();
    String getCompiler();
    void setCompiler(String compiler);
}

Language Definition

  • Processor instruction set
  • Register definitions
  • P-code semantics
  • Calling conventions
  • Memory model

Transaction Model

All program modifications must occur within transactions:
// Explicit transaction
int txId = program.startTransaction("Make changes");
try {
    // Modify program
    memory.setByte(addr, (byte)0x90);
    program.endTransaction(txId, true);
} catch (Exception e) {
    program.endTransaction(txId, false);  // Rollback
}

// Try-with-resources
try (Transaction tx = program.openTransaction("Make changes")) {
    memory.setByte(addr, (byte)0x90);
    // Automatically commits on success
}
Forgetting to start a transaction will result in an exception when attempting to modify the program.

Program Events

Programs generate events for changes:
program.addListener(new DomainObjectListener() {
    @Override
    public void domainObjectChanged(DomainObjectChangedEvent ev) {
        for (DomainObjectChangeRecord rec : ev) {
            EventType type = rec.getEventType();
            if (type == ProgramEvent.MEMORY_BLOCK_ADDED) {
                Address start = (Address) rec.getObject();
                // Handle new memory block
            }
        }
    }
});
Common Program Events:
  • MEMORY_BLOCK_ADDED / REMOVED
  • CODE_ADDED / REMOVED
  • FUNCTION_ADDED / REMOVED
  • SYMBOL_ADDED / RENAMED / REMOVED
  • DATA_TYPE_ADDED / CHANGED

Best Practices

  • Create memory blocks before analysis
  • Use meaningful block names
  • Set proper permissions (R/W/X)
  • Consider using overlays for alternate contexts
  • Use descriptive symbol names
  • Organize with namespaces
  • Mark important symbols as primary
  • Document symbol sources
  • Define structures for complex data
  • Share data types via archives
  • Apply types consistently
  • Use categories to organize types
  • Keep transactions focused and small
  • Use descriptive transaction names
  • Always commit or rollback explicitly
  • Avoid long-running transactions

Next Steps

Analysis

Learn about program analysis

Projects

Understand project organization

Architecture

Explore framework architecture

Overview

Return to framework overview