Stack corruption is the family of control-flow hijack attacks that exploits a buffer overflow on the stack to overwrite control data in the frame — local variables, function pointers, the saved base pointer, or the saved return address. All four subclasses share the same mechanism: writing past a local buffer walks upward into whatever sits adjacent in the frame; only the target of the overwrite differs.
The Four Subclasses
Four adjacent frame slots, four attacks
Subclass
Overwritten target
Effect
local variable clobbering
a neighbouring local variable
divert the immediate execution flow (e.g. flip a guard into a “Win” value)
function pointer clobbering
a local function pointer
completely control the execution flow at the next indirect call
instruction pointer hijacking
the saved return address
completely control the execution flow when the function returns — see [[Knowledge/Instruction Pointer Hijacking
frame pointer hijacking
the saved base pointer
move the caller’s frame to attacker-controlled memory — see [[Knowledge/Stack Pivot
The boundary between local variable clobbering and function pointer clobbering is just which adjacent slot the overflow reaches; the boundary between the two and the instruction/frame pointer cases is that the latter overwrite control data the CPU resumes through on return, rather than data the function reads.
Example: Local Variable Clobbering
Overflowing guard to reach the Win branch
int main(void) { long guard = 0xcabba6e5; char data[0x10] = {0}; gets(data); if (guard == 0xb000000f) printf("Win \\o/\n"); else printf("N00b :(\n"); return 0;}
the layout
data[0x10] sits at 0xf608, guard at 0xf618, the saved rbp at 0xf620, the saved rip at 0xf628
the intended behaviour
0xb000000f is never written to guard by the program, so “Win \o/” should never print
the overflow
gets does not bound the read; supplying 0x10 bytes of A then 0xb000000f in little-endian walks the write from data into guard
the result
guard is now 0xb000000f, the if fires and “Win \o/” prints — the overflow turned a length bug into a privilege escalation through a single local variable
data at 0xf608, fptr at 0xf618 holding &noob, saved rbp/rip above
the intended behaviour
(*fptr)() calls noob, printing “N00b :(”
the overflow
gets overruns data and overwrites fptr with &win
the result
the indirect call (*fptr)() now dispatches to win — the attacker has full control of where the next call goes, without touching the saved return address
A function pointer gives the attacker complete control at the call site rather than at function return, which is what makes this subclass cleaner than local variable clobbering but harder to stage than instruction pointer hijacking.