Process Memory · ASLR Off vs On

The same program, the same regions, the same order — but with ASLR every base address is re-rolled at every exec(). High-level user-space view of a 64-bit Linux process.

LINUX · x86-64 · USER-SPACE VIEW

1 The two pictures high addresses on top

higher addresses ↑ ASLR OFF identical picture on every single run kernel space stack argv · env · frames grows ↓ shared libraries libc.so.6 · ld-linux.so vdso · other mmap()s unused gap (huge) heap malloc / brk grows ↑ .data / .bss .text code (non-PIE ELF image) unmapped NULL page lives here 0x7ffffffff000 0x7ffff7c00000 0x405000 0x400000 0x0 heap starts right after .bss, no gap kernel has its own switch: KASLR same regions, same order — only the base addresses move = base re-rolled at every exec() ASLR ON (PIE binary) — re-shuffled at every exec() kernel space stack argv · env · frames shared libraries libc.so.6 · ld-linux.so vdso · other mmap()s unused gap (random size) heap malloc / brk .data / .bss .text code (PIE image) unmapped — PIE lifted the image far above the old 0x400000 0x7ffd3f8e1000 0x7ffce62a9000 two different runs 0x7f2c1a400000 0x7f96e3200000 random brk gap 0x55e8d2a41000 0x5643197f2000 0x0
Left: classic non-PIE binary with randomize_va_space=0 — you can hardcode any of these addresses in an exploit and they work every time. Right: PIE + full ASLR — white/pink address pairs show the same region on two different runs.
The relative layout inside a module never changes — .text, .data, and every function keep their offsets from the module base. Leak one pointer and you know where the whole module is. That is why info leaks defeat ASLR.

2 What actually moves and by how much

RegionASLR offASLR on · typical x86-64 entropy
ELF image (non-PIE)0x400000, fixedstill 0x400000 — image only moves if it is PIE
ELF image (PIE)0x555555554000 (the famous gdb address)0x55…/0x56…, ~28 bits
Heap (brk)starts right after .bss, no gapimage end + random gap, ~13 bits
Shared libs / mmapfixed 0x7ffff7…0x7f…, ~28 bits (/proc/sys/vm/mmap_rnd_bits)
Stacktop at 0x7ffffffff0000x7ffc…–0x7fff…, ~22 bits
vdsofixedrandomized along with the mmap region
Kernelseparate mechanism (KASLR), decided once at boot, not per-process

The switch: /proc/sys/kernel/randomize_va_space

ValueMeaning
0ASLR off — the left picture
1stack, mmap/libs, vdso, PIE base randomized — but heap (brk) is not
2everything in 1 plus the heap — the right picture (default)
ASLR ≠ PIE. ASLR is the kernel rolling dice; PIE is the binary being built relocatable so its image can join the game. Full ASLR + non-PIE binary = stack/heap/libs move but .text/.data sit at 0x400000 forever (this is what checksec’s PIE column is about).

3 See it on your machine two minutes

$ cat /proc/sys/kernel/randomize_va_space      # 2 = full ASLR (default)

$ for i in 1 2; do grep -E 'heap|stack|libc' /proc/self/maps; echo; done
# every address differs between the two runs

$ setarch $(uname -m) -R grep -E 'heap|stack|libc' /proc/self/maps
$ setarch $(uname -m) -R grep -E 'heap|stack|libc' /proc/self/maps
# -R = ADDR_NO_RANDOMIZE for this one process: now identical runs
gdb disables ASLR by default — that’s why you always see 0x555555554000 for the image and 0x7ffff7… for libc while debugging. Turn it back on with set disable-randomization off.