On ASLR: you might use the UAF to access memory regions you shouldn’t have access to. By reading the contents, they can potentially leak pointers to a critical library (e.g., libc), allowing them to calculate the offsets to bypass ASLR.
On heap protection: if you spray the heap with predictable data patterns you can improve your chance of landing a useful address, even with ASLR in place
I understand heap sprays in theory. In practice, how do they avoid clobbering something important and crashing the app? It seems like a typical app has a lot of state to clobber.
The writes for a spray are pre exploit, you are going through an allocator to get the space you're writing to. Put another way, its the apps job to write the spray into "free space".
Sprays are pretty crashy but the heap setup is not usually the problem, its that the pointer you want to control "missed" the sprayed area.
On heap protection: if you spray the heap with predictable data patterns you can improve your chance of landing a useful address, even with ASLR in place