MemWriter class builds ROP chains that write arbitrary data to memory addresses. It handles badbytes, chunk optimization, and uses memory arithmetic operations when needed.
Overview
Accessed through the ROP instance asrop.write_to_mem(), MemWriter automatically:
- Finds optimal memory write gadgets
- Handles data with badbytes using arithmetic transformations
- Writes data in efficient chunks (1, 2, 4, or 8 bytes)
- Manages address and data register dependencies
Class Definition
angrop/chain_builder/mem_writer.py
Public Method
write_to_mem
int | RopValue
required
Target memory address where data will be written.
bytes
required
Data to write (must be a bytes object).
set | None
default:"None"
Set of register names that must not be modified.
bytes
default:"b'\\xff'"
Single byte used to pad data if necessary. Must not be a badbyte.
RopChain that writes the data to memory.
Raises:
RopExceptionif data cannot be writtenRopExceptionif fill_byte is a badbyteRopExceptionif addr is symbolic
ROP Instance Method
When you callrop.write_to_mem(), it invokes MemWriter.write_to_mem() internally:
Implementation Details
Memory Write Gadgets
MemWriter requires gadgets with specific properties:- Self-contained: No dependencies on initial state
- Single memory write: Only one symbolic write operation
- Independent addr/data: Address and data controlled by different registers
Gadget Examples
Badbyte Handling
When data contains badbytes, MemWriter uses multiple strategies:1. Chunk Transforms
Transforms safe bytes into target bytes using arithmetic: From source code (mem_writer.py:213-250):2. Per-Byte Operations
Handles each byte with different operations:3. Write Plans
From source code (mem_writer.py:607-629):MemWriteChain Caching
MemWriter caches chain templates for efficiency: From source code (mem_writer.py:18-132):Usage Examples
Basic Memory Write
Writing Binary Data
Writing with Register Preservation
Building Execve Chain
Writing File Paths
Writing with Badbytes
Building Data Structures
Writing Pointer Arrays
Write Size Optimization
MemWriter automatically chooses optimal chunk sizes:Error Handling
”Fail to write data to memory :(”
Raised when no suitable gadgets are found. Solutions:- Use
fast_mode=Falsewhen initializing ROP - Check if binary has memory write gadgets
- Try alternative addresses or data
”fill_byte is a bad byte!”
Raised when fill_byte contains a badbyte. Solution: Choose a different fill_byte that’s not in badbytes.”cannot write to a symbolic address”
Raised when addr parameter is symbolic. Solution: Use a concrete address value.”data is not a byte string”
Raised when data is not bytes type. Solution: Convert to bytes:data.encode() or bytes([...])
Gadget Requirements
For memory writes to work:- Controllable address: Can set address register to any value
- Controllable data: Can set data register to any value
- Independence: Address and data registers are different
- Self-contained: Gadget doesn’t require special initial state
Performance Considerations
- Writing large data may generate long chains
- Badbyte handling adds overhead (arithmetic operations)
- Caching reduces overhead for repeated writes
- Chunk size optimization minimizes total gadgets used
See Also
- MemChanger - Arithmetic operations on memory
- Memory Operations Guide - Usage examples
- Badbytes Guide - Handling restricted bytes