The Memory interface provides the ability to inspect and manage the memory model for a Program. It supports conventional memory blocks, byte-mapped blocks, bit-mapped blocks, and overlay blocks.
Overview
Memory operations in Ghidra include:
- Reading and writing bytes - Access program memory
- Creating memory blocks - Define initialized, uninitialized, and mapped blocks
- Memory block management - Move, split, join, and remove blocks
- Overlay support - Create alternate memory contexts
- File bytes - Store and manage original file data
All memory block manipulations require exclusive access and should generally be completed prior to analysis.
Block Types
Initialized Blocks
Memory blocks with specific data, initialized from FileBytes, InputStream, or set to zeros.
Uninitialized Blocks
Memory blocks whose data is unknown.
Byte-Mapped Blocks
Memory blocks whose bytes map to another memory region using 1:1 or custom mapping.
Bit-Mapped Blocks
Memory blocks where each byte corresponds to a single bit in another region.
Overlay Blocks
Alternate content for a physical memory region, useful for different execution contexts.
Memory Size Limits
Maximum size of all memory blocks: 16 GB
Maximum size of a single memory block: 16 GB
Creating Memory Blocks
Create Initialized Block
createInitializedBlock(String name, Address start, InputStream is, long length, TaskMonitor monitor, boolean overlay)
Creates an initialized memory block from an InputStream.FileInputStream fis = new FileInputStream("data.bin");
MemoryBlock block = memory.createInitializedBlock(
".text",
addr("00400000"),
fis,
0x1000,
monitor,
false
);
fis.close();
createInitializedBlock(String name, Address start, long size, byte initialValue, TaskMonitor monitor, boolean overlay)
Creates an initialized block with all bytes set to the specified value.// Create 4KB block initialized to zeros
MemoryBlock block = memory.createInitializedBlock(
".bss",
addr("00404000"),
0x1000,
(byte) 0,
monitor,
false
);
Use zero as the initial value for reduced storage.
createInitializedBlock(String name, Address start, FileBytes fileBytes, long offset, long size, boolean overlay)
Creates an initialized block using bytes from a FileBytes object.FileBytes fileBytes = memory.getAllFileBytes().get(0);
MemoryBlock block = memory.createInitializedBlock(
".data",
addr("00405000"),
fileBytes,
0x1000, // offset in file
0x800, // size
false
);
Create Uninitialized Block
createUninitializedBlock(String name, Address start, long size, boolean overlay)
Creates an uninitialized memory block.MemoryBlock block = memory.createUninitializedBlock(
"EXTERNAL",
addr("01000000"),
0x10000,
false
);
Create Mapped Blocks
createByteMappedBlock(String name, Address start, Address mappedAddress, long length, boolean overlay)
Creates a byte-mapped block with 1:1 byte mapping.// Mirror memory region
MemoryBlock block = memory.createByteMappedBlock(
"mirror",
addr("10000000"),
addr("00400000"), // source address
0x1000,
false
);
createBitMappedBlock(String name, Address start, Address mappedAddress, long length, boolean overlay)
Creates a bit-mapped block where each byte corresponds to a single bit.MemoryBlock block = memory.createBitMappedBlock(
"bitfield",
addr("20000000"),
addr("00404000"),
256, // 256 bytes = 2048 bits
false
);
Reading Memory
Read Bytes
Reads a single byte from memory.try {
byte b = memory.getByte(addr);
println("Byte at " + addr + ": 0x" + Integer.toHexString(b & 0xFF));
} catch (MemoryAccessException e) {
println("Cannot read memory at " + addr);
}
getBytes(Address addr, byte[] dest)
Reads bytes into the destination array.byte[] bytes = new byte[16];
int numRead = memory.getBytes(addr, bytes);
println("Read " + numRead + " bytes");
getBytes(Address addr, byte[] dest, int destIndex, int size)
Reads a specified number of bytes into the destination array at the given offset.byte[] buffer = new byte[256];
int numRead = memory.getBytes(addr, buffer, 0, 32);
Read Integers
Reads a short (2 bytes) using default endianness.short value = memory.getShort(addr);
getShort(Address addr, boolean bigEndian)
Reads a short with specified endianness.
Reads an int (4 bytes) using default endianness.int value = memory.getInt(addr);
println("Int at " + addr + ": 0x" + Integer.toHexString(value));
getInt(Address addr, boolean bigEndian)
Reads an int with specified endianness.
Reads a long (8 bytes) using default endianness.long value = memory.getLong(addr);
getLong(Address addr, boolean bigEndian)
Reads a long with specified endianness.
Read Arrays
getShorts(Address addr, short[] dest)
Reads multiple shorts into an array.
getInts(Address addr, int[] dest)
Reads multiple ints into an array.
getLongs(Address addr, long[] dest)
Reads multiple longs into an array.
Writing Memory
Write Bytes
setByte(Address addr, byte value)
Writes a single byte to memory.memory.setByte(addr, (byte) 0x90); // Write NOP instruction
setBytes(Address addr, byte[] source)
Writes an array of bytes to memory.byte[] bytes = {(byte) 0x90, (byte) 0x90, (byte) 0x90};
memory.setBytes(addr, bytes); // Write 3 NOPs
setBytes(Address addr, byte[] source, int sIndex, int size)
Writes a portion of a byte array to memory.byte[] buffer = new byte[256];
// ... fill buffer ...
memory.setBytes(addr, buffer, 10, 32); // Write 32 bytes starting at buffer[10]
Write Integers
setShort(Address addr, short value)
Writes a short using default endianness.
setShort(Address addr, short value, boolean bigEndian)
Writes a short with specified endianness.
setInt(Address addr, int value)
Writes an int using default endianness.memory.setInt(addr, 0x12345678);
setInt(Address addr, int value, boolean bigEndian)
Writes an int with specified endianness.
setLong(Address addr, long value)
Writes a long using default endianness.
setLong(Address addr, long value, boolean bigEndian)
Writes a long with specified endianness.
Memory Block Operations
Get Blocks
Returns all memory blocks.MemoryBlock[] blocks = memory.getBlocks();
for (MemoryBlock block : blocks) {
println(block.getName() + ": " + block.getStart() + " - " + block.getEnd());
println(" Size: " + block.getSize());
println(" Initialized: " + block.isInitialized());
println(" Executable: " + block.isExecute());
}
Returns the block containing the specified address.MemoryBlock block = memory.getBlock(addr);
if (block != null) {
println("Address " + addr + " is in block: " + block.getName());
}
getBlock(String blockName)
Returns the block with the specified name.
Modify Blocks
moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor)
Moves a memory block to a new start address.MemoryBlock block = memory.getBlock(".text");
memory.moveBlock(block, addr("00500000"), monitor);
split(MemoryBlock block, Address addr)
Splits a block at the given address.MemoryBlock block = memory.getBlock(addr("00400000"));
memory.split(block, addr("00401000")); // Split into two blocks
join(MemoryBlock blockOne, MemoryBlock blockTwo)
Joins two contiguous blocks into a single block.MemoryBlock block1 = memory.getBlock(".text");
MemoryBlock block2 = memory.getBlock(".text2");
MemoryBlock joined = memory.join(block1, block2);
After joining, both input blocks should no longer be used.
removeBlock(MemoryBlock block, TaskMonitor monitor)
Removes a memory block.MemoryBlock block = memory.getBlock("EXTERNAL");
memory.removeBlock(block, monitor);
Convert Blocks
convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue)
Converts an uninitialized block to initialized.MemoryBlock block = memory.getBlock(".bss");
MemoryBlock initialized = memory.convertToInitialized(block, (byte) 0);
convertToUninitialized(MemoryBlock initializedBlock)
Converts an initialized block to uninitialized, discarding all bytes.
Memory Properties
Returns the program that this memory belongs to.
Returns the total memory size in bytes.long totalSize = memory.getSize();
println("Total memory: " + totalSize + " bytes");
Returns true if memory is big-endian.boolean isBigEndian = memory.isBigEndian();
Address Sets
getLoadedAndInitializedAddressSet()
Returns addresses of all loaded memory blocks with initialized data.AddressSetView loadedSet = memory.getLoadedAndInitializedAddressSet();
getAllInitializedAddressSet()
Returns addresses of all memory blocks with initialized data, including non-loaded blocks like debug sections.
Returns addresses corresponding to executable memory.AddressSetView execSet = memory.getExecuteSet();
File Bytes Management
createFileBytes(String filename, long offset, long size, InputStream is, TaskMonitor monitor)
Stores original file bytes for later use in memory blocks.FileInputStream fis = new FileInputStream("program.exe");
FileBytes fileBytes = memory.createFileBytes(
"program.exe",
0,
fileSize,
fis,
monitor
);
fis.close();
Returns all stored file bytes objects.List<FileBytes> allFileBytes = memory.getAllFileBytes();
for (FileBytes fb : allFileBytes) {
println("File: " + fb.getFilename());
println("Size: " + fb.getSize());
}
deleteFileBytes(FileBytes fileBytes)
Deletes stored file bytes if no memory blocks reference them.
Searching Memory
findBytes(Address addr, byte[] bytes, byte[] masks, boolean forward, TaskMonitor monitor)
Finds a sequence of bytes in memory starting from the specified address.// Search for "MZ" signature
byte[] pattern = {0x4D, 0x5A};
Address found = memory.findBytes(
addr("00400000"),
pattern,
null, // no mask
true, // forward
monitor
);
if (found != null) {
println("Found at " + found);
}
findBytes(Address startAddr, Address endAddr, byte[] bytes, byte[] masks, boolean forward, TaskMonitor monitor)
Finds bytes within a specified address range.// Search with mask for specific bits
byte[] pattern = {(byte) 0xFF, 0x15};
byte[] mask = {(byte) 0xFF, (byte) 0xFF};
Address found = memory.findBytes(
startAddr,
endAddr,
pattern,
mask,
true,
monitor
);
Example Usage
Creating Memory Layout
public void createMemoryLayout(Program program) throws Exception {
Memory memory = program.getMemory();
TaskMonitor monitor = TaskMonitor.DUMMY;
// Create .text section (executable code)
MemoryBlock textBlock = memory.createInitializedBlock(
".text",
addr("00400000"),
0x1000,
(byte) 0,
monitor,
false
);
textBlock.setExecute(true);
textBlock.setRead(true);
// Create .data section
MemoryBlock dataBlock = memory.createInitializedBlock(
".data",
addr("00401000"),
0x800,
(byte) 0,
monitor,
false
);
dataBlock.setRead(true);
dataBlock.setWrite(true);
// Create .bss section (uninitialized)
MemoryBlock bssBlock = memory.createUninitializedBlock(
".bss",
addr("00402000"),
0x400,
false
);
bssBlock.setRead(true);
bssBlock.setWrite(true);
}
Reading and Analyzing Memory
public void analyzeMemory(Program program, Address start, int length) {
Memory memory = program.getMemory();
try {
byte[] bytes = new byte[length];
int numRead = memory.getBytes(start, bytes);
// Analyze bytes
println("Read " + numRead + " bytes from " + start);
// Check for common signatures
if (bytes.length >= 2 && bytes[0] == 0x4D && bytes[1] == 0x5A) {
println("Found MZ signature (DOS header)");
}
// Read as integers
for (int i = 0; i < Math.min(4, numRead / 4); i++) {
Address addr = start.add(i * 4);
int value = memory.getInt(addr);
println(String.format(" [%s] = 0x%08X", addr, value));
}
} catch (MemoryAccessException e) {
println("Error reading memory: " + e.getMessage());
}
}
Package Location
ghidra.program.model.mem.Memory