MemChanger class builds ROP chains that perform arithmetic and logical operations directly on memory locations. It supports add, xor, or, and operations.
Overview
Accessed through the ROP instance asrop.mem_add(), rop.mem_xor(), rop.mem_or(), and rop.mem_and(), MemChanger automatically:
- Finds gadgets that operate on memory
- Handles different data sizes (1, 2, 4, 8 bytes)
- Verifies operations are correct
- Manages register dependencies
Class Definition
angrop/chain_builder/mem_changer.py
Public Methods
mem_add
int | RopValue
required
Memory address to modify.
int | RopValue
required
Value to add.
int | None
default:"None"
Number of bytes to operate on (1, 2, 4, or 8). Defaults to architecture word size.
RopChain that performs the addition.
mem_xor
int | RopValue
required
Memory address to modify.
int | RopValue
required
Value to XOR with.
int | None
default:"None"
Number of bytes (1, 2, 4, or 8).
RopChain that performs the XOR.
mem_or
int | RopValue
required
Memory address to modify.
int | RopValue
required
Value to OR with.
int | None
default:"None"
Number of bytes (1, 2, 4, or 8).
RopChain that performs the OR.
mem_and
int | RopValue
required
Memory address to modify.
int | RopValue
required
Value to AND with.
int | None
default:"None"
Number of bytes (1, 2, 4, or 8).
RopChain that performs the AND.
verify
str
required
Operation name: ‘add’, ‘xor’, ‘or’, or ‘and’.
RopChain
required
Chain to verify.
RopValue
required
Memory address.
RopValue
required
Operation value.
int
required
Data size in bits (8, 16, 32, or 64).
RopException if verification fails.
ROP Instance Methods
Implementation Details
Memory Change Gadgets
MemChanger requires gadgets with specific properties:- Self-contained: No dependencies on initial state
- Single memory change: Only one read-modify-write operation
- Independent addr/data: Address and data controlled separately
Gadget Examples
Operation Verification
From source code (mem_changer.py:32-71):Usage Examples
Memory Addition
Memory XOR
Memory OR
Memory AND
Complete Memory Operations Example
Incrementing a Counter
Toggling a Flag
Enabling/Disabling Bits in Bitmask
Badbyte Avoidance
MemChanger is crucial for writing data with badbytes:Size Specification
All operations support explicit size:Effect Tuple
MemChanger filters gadgets based on their effect: From source code (mem_changer.py:73-81):Operation-Specific Gadget Lists
MemChanger maintains separate lists: From source code (mem_changer.py:25-30):Error Handling
”Fail to perform _mem_change for operation!”
Raised when no suitable gadgets are found. Solutions:- Use
fast_mode=Falsewhen initializing ROP - Check if binary has memory change gadgets
- Try a different operation (XOR instead of ADD)
” cannot be represented by -byte”
Raised when value is too large for specified size. Solution: Use larger size or split operation:“does not support finding raw chain that bytes”
Raised when size is invalid. Solution: Use valid sizes: 1, 2, 4, or 8 bytes.Gadget Requirements
For memory changes to work:- Read-modify-write: Gadget must read, modify, then write
- Controllable address: Can set address register
- Controllable data: Can set data/operand register
- Independence: Address and data registers are different
- Self-contained: No special initial state required
Deprecated Method
add_to_mem
Performance Considerations
- Gadgets are sorted by data_size (larger first) for efficiency
- Verification adds overhead but ensures correctness
- Multiple operations can be chained efficiently
- Size should match actual data requirements
Architecture Support
Works across all supported architectures:- x86/x86_64: Full support
- ARM/ARM64: Full support
- MIPS: Full support
- PowerPC: Full support
See Also
- MemWriter - Writing data to memory
- Memory Operations Guide - Usage examples
- Badbytes Guide - Handling restricted bytes