- Arrays are just memory. A
char buffer[64]is 64 contiguous bytes on the stack. There's nothing stopping code from writing past the end — the language trusts the programmer. - Not all input functions are equal. We learned the difference between
gets(),fgets(),scanf(), andcin, and why some are unsafe by design.gets()was removed from the C standard entirely. - Pointers and memory layout. Building the payload with
memsetandmemcpymade pointer arithmetic concrete — we were placing exact bytes at exact positions. - Binary file I/O. Writing the raw payload to
payload.binwithofstreamin binary mode. - Little-endian byte ordering. Understanding why a 4-byte address gets written into memory backwards.
- The call stack — how functions store their local variables, the saved frame pointer, and the return address, and how overwriting the return address hijacks control flow.
- The exploit anatomy — padding → return-address overwrite → NOP sled → shellcode, and why each piece is needed.
JMP ESPtechnique — using an instruction already present in memory to reliably reach our code, instead of guessing a raw stack address.- NOP sleds — a reliability trick to avoid needing pixel-perfect jump accuracy.
- Position-independent shellcode — how shellcode resolves Windows API functions (like
WinExec) at runtime by walking the PEB.
- Immunity Debugger — attaching to a running process, reading CPU registers (ESP, EIP), inspecting the stack, and searching modules for useful instructions.
- Finding offsets — the crash-and-measure workflow with a unique pattern to pinpoint exactly where EIP gets overwritten.
The exploit only worked because we turned off the protections Windows normally provides — DEP, ASLR, and stack canaries. Doing that by hand, and then watching the exploit succeed, gave us a real understanding of why those mitigations exist and what attack each one is designed to stop.
- Rewrite the vulnerable program safely and prove the overflow no longer triggers.
- Study how attackers bypass modern mitigations (e.g., ROP chains to defeat DEP) — at a conceptual level.
- Explore memory-safe languages (Rust) that prevent this class of bug at compile time.