Register and Stack
Understanding CPU registers and stack memory layout is fundamental for binary exploitation in CTF competitions. This guide covers the essential concepts you need to know before diving into buffer overflows, return-oriented programming (ROP), and other binary exploitation techniques.
CPU Registers
Registers are small, fast storage locations directly accessible by the CPU. In x86-64 architecture, there are several types of registers:
General Purpose Registers (x86-64)
- RAX: Accumulator register, often used for return values
- RBX: Base register, general purpose
- RCX: Counter register, often used for loop counters
- RDX: Data register, general purpose
- RSI: Source index, used in string operations
- RDI: Destination index, used in string operations
- RBP: Base pointer, points to the base of the current stack frame
- RSP: Stack pointer, points to the top of the stack
- R8-R15: Additional general purpose registers (x86-64 only)
Special Purpose Registers
- RIP: Instruction pointer, points to the next instruction to execute
- EFLAGS/RFLAGS: Flags register, contains status flags
Register Sizes
Registers can be accessed in different sizes:
- 64-bit: RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP
- 32-bit: EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP
- 16-bit: AX, BX, CX, DX, SI, DI, BP, SP
- 8-bit: AL/AH, BL/BH, CL/CH, DL/DH
The Stack
The stack is a region of memory that grows downward (from higher addresses to lower addresses) and follows the Last-In-First-Out (LIFO) principle.
Stack Operations
- PUSH: Adds data to the top of the stack, decrements RSP
- POP: Removes data from the top of the stack, increments RSP
Stack Frame Structure
When a function is called, a new stack frame is created:
Key Stack Components
- Return Address: Address to return to after function completes
- Saved Base Pointer: Previous frame's RBP value
- Local Variables: Function's local variables
- Function Parameters: Arguments passed to the function
Function Call Convention
x86-64 System V ABI (Linux)
Arguments are passed in registers in this order:
- RDI - First argument
- RSI - Second argument
- RDX - Third argument
- RCX - Fourth argument
- R8 - Fifth argument
- R9 - Sixth argument
- Stack - Additional arguments
Return value is stored in RAX.
Function Prologue and Epilogue
Prologue (function entry):
Epilogue (function exit):
Stack-Based Buffer Overflow
Understanding the stack layout is crucial for buffer overflow attacks:
Vulnerable Code Example
Memory Layout During Overflow
Exploitation Strategy
- Find offset: Determine how many bytes to write before overwriting return address
- Control RIP: Overwrite return address with desired value
- Execute payload: Redirect execution to shellcode or ROP chain
Debugging with GDB
Essential GDB commands for examining registers and stack:
Register Commands
Stack Commands
Memory Examination
Stack Protections
Modern systems implement various stack protections:
Stack Canaries
- Random values placed between buffer and return address
- Program terminates if canary is overwritten
- Can be bypassed by leaking the canary value
ASLR (Address Space Layout Randomization)
- Randomizes memory layout on each execution
- Makes it harder to predict addresses
- Can be bypassed with information leaks
NX Bit (No Execute)
- Marks stack as non-executable
- Prevents direct shellcode execution
- Bypassed using ROP (Return-Oriented Programming)
Common Exploitation Techniques
Buffer Overflow
- Overflow buffer to overwrite return address
- Redirect execution to controlled location
- Execute shellcode or system calls
Return-Oriented Programming (ROP)
- Chain together existing code snippets ("gadgets")
- Each gadget ends with a
retinstruction - Build complex operations without injecting code
Format String Attacks
- Exploit format string functions (
printf,sprintf) - Read from or write to arbitrary memory locations
- Can leak addresses or overwrite function pointers
Practical Tips
- Use pattern generation: Tools like
pwn cyclichelp find offsets - Examine core dumps: Understand crash locations and register states
- Check protections: Use
checksecto identify enabled mitigations - Practice with CTF platforms: PicoCTF, OverTheWire, etc.
- Study assembly: Understanding x86-64 assembly is crucial
Tools and Resources
- GDB with enhancements: pwndbg, GEF, or PEDA
- pwntools: Python library for exploit development
- ROPgadget: Tool for finding ROP gadgets
- checksec: Script to check binary protections
- Ghidra/IDA: Reverse engineering tools
Understanding registers and stack layout forms the foundation for all binary exploitation techniques. Master these concepts before moving on to advanced exploitation methods.