Most memory-corruption exploitation is really allocator manipulation. The bug gives you a write; grooming decides what’s next to it.
The general shape:
- Learn the allocator. glibc’s tcache/fastbins, Windows’ LFH/segment heap, macOS’s magazine malloc, and every browser’s custom one behave completely differently. Generic advice is useless here — you need the specific one.
- Find a spray primitive. Something attacker-controlled that allocates a chosen size on demand. ArrayBuffers, strings, and DOM nodes are the classic browser ones.
- Defragment. Fill the holes so subsequent allocations are predictable and contiguous.
- Place the victim. Allocate the target object so it lands adjacent to your overflowable buffer, or in the hole left by your UAF.
- Trigger, then re-check. Grooming is probabilistic. Build in verification so the exploit can bail rather than crash.
The step people skip is 5. A groom that works 70% of the time and crashes otherwise is worse than one that works 40% of the time and retries cleanly.
Modern allocators actively fight this — randomized placement, type-isolated pools, guard pages, delayed free. Which target’s allocator has given you the most trouble?