What stops you, and how exploits get past it
5 min read
Modern binaries fight back, and knowing each defence tells you what a real exploit has to do:
- NX / DEP — the stack is not executable, so you cannot just jump to shellcode you
wrote there. The answer is ROP: chain snippets of the program's own existing code
("gadgets") ending in
retto build your behaviour out of pieces that were already allowed to run. - Stack canary — a random value placed before the return address and checked on return; overwrite it and the program aborts. You either leak it first or avoid overwriting it.
- ASLR — addresses are randomised each run, so you cannot hardcode them. You need an information leak that reveals one real address, then compute the rest relative to it.
- PIE — the binary itself is loaded at a random base too, extending ASLR to the program's own code.
A modern exploit is usually two bugs: one to leak an address and defeat ASLR, one to corrupt control flow and redirect it. Each mitigation you understand turns a "can't" into a "here's the extra step".