Supported Architectures
From the README, angrop supports multiple processor architectures:- x86 (32-bit Intel/AMD)
- x64 (AMD64, 64-bit Intel/AMD)
- MIPS (32-bit and 64-bit)
- ARM (32-bit, including Thumb mode)
- AArch64 (ARM 64-bit)
- RISC-V (64-bit)
Architecture-Agnostic Design
From the README:“Its design is architecture-agnostic so it supports multiple architectures.”angrop achieves architecture independence through abstraction layers:
The ROPArch Class
Fromarch.py:5-39, the base architecture class:
Register Management
Fromarch.py:24-39:
- x86:
eax, ebx, ecx, edx, esi, edi, ebp - x64:
rax, rbx, rcx, rdx, rsi, rdi, r8-r15, rbp - ARM:
r0-r12, lr - AArch64:
x0-x30 - MIPS:
$v0-$v1, $a0-$a3, $t0-$t9, $s0-$s8
x86 (32-bit)
Fromarch.py:44-86:
- Uses
int 0x80for system calls - Multiple return instruction variants (
ret,ret imm16,retf, etc.) - Segment registers not used in ROP (filtered out)
- Smaller maximum gadget size (20 instructions)
x64 (AMD64)
Fromarch.py:87-96:
- Uses
syscallinstruction instead ofint 0x80 - Different syscall numbers (Linux x64 ABI)
- 64-bit registers (
raxvseax) - Different calling convention (registers vs stack)
ARM (32-bit)
Fromarch.py:100-128:
- Return via
pop {pc}orbx lr - Conditional execution on every instruction
- Thumb mode for 16-bit instruction encoding
Thumb Mode
Fromrop.py:36-37:
- 16-bit instruction encoding (vs 32-bit ARM)
- 2-byte instruction alignment
- Smaller code size
- Most ARM instructions available in Thumb
- Cannot mix ARM and Thumb in same ROP chain
is_thumb=True, gadgets are searched at 2-byte aligned addresses with Thumb decoding.
AArch64 (ARM 64-bit)
Fromarch.py:130-143:
- 64-bit registers:
x0-x30(vs ARM’sr0-r12) - Fixed 4-byte instruction size (no Thumb)
- Return via
retinstruction - PAC (Pointer Authentication Codes) filtered - incompatible with ROP
MIPS
Fromarch.py:145-152:
- Delay slots after branches (branch executes, then next instruction, then jump)
- Different syscall number encoding
- Both big-endian and little-endian variants supported
RISC-V (64-bit)
Fromarch.py:154-160:
- Clean RISC architecture
- Compressed instruction set (16-bit and 32-bit)
- Return via
ret(pseudo-instruction forjalr x0, x1, 0)
Architecture Detection
Fromarch.py:162-178:
Kernel Mode
All architectures support kernel mode for finding gadgets in kernel code:- Uses kernel syscall numbers
- Allows segment register operations (x86/x64)
- Searches in
.textsection of kernel images - Different constraints on memory accesses
Adding New Architectures
From the README:“It should be relatively easy to support other architectures that are supported by angr. If you’d like to use angrop on other architectures, please create an issue and we will look into it :)”To add a new architecture:
- Create a new class inheriting from
ROPArch:
-
Implement
block_make_sense()to filter invalid instruction sequences -
Add to
get_arch()function:
Cross-Architecture Exploitation
The same angrop API works across all architectures:- Register name differences
- Calling convention differences
- Instruction encoding differences
- Endianness differences
- Alignment requirements