SigreturnBuilder class builds SROP (Sigreturn-Oriented Programming) chains that use the sigreturn syscall to set all registers and control execution flow with a single syscall.
Overview
Sigreturn is a powerful technique that allows setting arbitrary register values including PC and SP in one operation. Accessed throughrop.sigreturn(), SigreturnBuilder automatically:
- Creates properly formatted sigreturn frames
- Invokes the sigreturn syscall
- Handles stack pointer calculations
- Supports chaining after sigreturn
- Provides execve convenience method
Class Definition
angrop/chain_builder/sigreturn.py
Public Methods
sigreturn
Keyword arguments mapping register names to values. All registers can be set including:
- General purpose: rax, rbx, rcx, etc.
- Stack pointer: rsp
- Instruction pointer: rip
- Flags: rflags (on x64)
RopChain containing sigreturn syscall and frame.
Raises: RopException if sigreturn is not supported or cannot be built.
sigreturn_syscall
int
required
Syscall number to invoke after sigreturn.
list
required
Arguments for the syscall (mapped to registers per syscall convention).
int | None
default:"None"
New stack pointer value. If provided, allows chaining after the syscall.
RopChain that performs sigreturn then invokes the syscall.
sigreturn_execve
int | None
required
Address containing the path string (e.g., “/bin/sh”).
RopChain that spawns a shell via SROP.
Raises: RopException if path_addr is None.
ROP Instance Methods
Implementation Details
Sigreturn Frame Structure
Sigreturn uses a frame structure defined by the OS kernel: From the sigreturn module:Stack Pointer Calculation
SigreturnBuilder calculates where the frame should be placed: From source code (sigreturn.py:18-31):Frame Placement
From source code (sigreturn.py:132-154):Usage Examples
Basic Sigreturn
Sigreturn Execve
Sigreturn to Syscall
Complete SROP Chain
Chaining After Sigreturn
Setting Flags
Architecture Support
x86_64 Linux
x86 (32-bit) Linux
ARM Linux
Sigreturn vs Regular ROP
Advantages of SROP
- Single operation: Set all registers at once
- Minimal gadgets: Only need syscall gadget
- Full control: Can set PC, SP, and flags
- Badbyte friendly: Frame data can be manipulated
Disadvantages
- Frame size: Requires significant stack space (~248 bytes on x64)
- Platform specific: Frame layout varies by OS/arch
- Limited scenarios: Need control of stack and syscall gadget
Error Handling
”sigreturn is not supported on this architecture”
Raised when architecture doesn’t support sigreturn. Solution: Only Linux on x86/x64/ARM supports sigreturn.” is not supported!”
Raised when OS is not Linux. Solution: SROP only works on Linux.”target does not contain syscall gadget!”
Raised when no syscall gadgets exist. Solution: Binary must havesyscall; ret or similar.
”Fail to execute sigreturn chain until syscall”
Raised when chain execution fails. Solution: Check gadgets and frame setup.”path_addr is required for sigreturn_execve”
Raised when path_addr is None. Solution: Provide address with command string.Frame Pretty Printing
Sigreturn frames are pretty-printed in chain output: From source code (sigreturn.py:153-154):chain.pp(), the frame is displayed:
Best Practices
- Check support: Verify
arch.sigreturn_numis not None - Plan stack: Ensure sufficient stack space for frame
- Set PC correctly: Point to syscall gadget or next ROP
- Use for complex setups: When many registers need setting
- Verify frame size: Different architectures have different sizes
Performance Considerations
- Frame creation is lightweight
- Stack space requirement is significant
- Single syscall is very efficient
- No need for many gadgets
Advanced Techniques
Stack Pivoting with SROP
Kernel SROP
See Also
- SysCaller - Regular syscall invocation
- Syscalls Guide - Syscall examples
- RegSetter - Alternative register setting method