Heap grooming: making the allocator do what you want

Most memory-corruption exploitation is really allocator manipulation. The bug gives you a write; grooming decides what’s next to it.

The general shape:

  1. 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.
  2. Find a spray primitive. Something attacker-controlled that allocates a chosen size on demand. ArrayBuffers, strings, and DOM nodes are the classic browser ones.
  3. Defragment. Fill the holes so subsequent allocations are predictable and contiguous.
  4. Place the victim. Allocate the target object so it lands adjacent to your overflowable buffer, or in the hole left by your UAF.
  5. 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?