Stack Frame Layout
- •
What it is
- •
The arrangement of local variables, saved registers, and return information on the stack. Deriving their offsets shows exactly where an overflow lands.
- •
- •
How it works
- •
With a conventional frame-pointer prologue (
push rbp; mov rbp, rsp), savedrbpis at[rbp]and the return address at[rbp+8]. Optimized or unusual frames may differ. - •
High addresses [ return addr ] ← rbp + 0x8 [ saved rbp ] ← rbp + 0x0 [ ... ] [ local buffer ] ← rbp - offset (offset read directly off disassembly) Low addresses (rsp) - •
To get the distance from a buffer to the return address: take the buffer's
rbp-relative offset (magnitude) and add0x8(past the saved rbp slot).
- •
- •
When to use it
- •
Any time you have (or can get) a disassembly and need an exact overflow offset rather than guessing or brute-forcing with a cyclic pattern — look for the
lea/movthat establishes the buffer pointer relative torbp. - •
For two locations relative to the same frame pointer, subtract their offsets; an absolute address is unnecessary.
- •
- •
- •
pwntools
- •
pattern = cyclic(200) offset = cyclic_find(0x6161616b) # Use a value observed in the crash.
- •
- •
Debugging
- •
disas challenge info frame x/2gx $rbp
- •
- •
Related
- •
Cards
- •
Given a buffer at
rbp-0x50, how many bytes reach the saved return address?- •
0x50 + 0x8 = 0x58(88 decimal) bytes.
- •
- •
What's always true about
[rbp+0x0]and[rbp+0x8]in a standard (non-optimized) stack frame?- •
With the conventional
push rbp; mov rbp, rspframe,[rbp]holds savedrbpand[rbp+8]the return address. Do not assume this for omitted-frame-pointer code.
- •
- •