Un programme compilé avec PIE peut être mappé en mémoire à une adresse variable, à la manière des bibliothèques partagées. Il s’agit d’une protection très efficace contre le Return Oriented Programming, étant donné qu’il devient compliqué de prédire l’adresse d’une portion de code.
Voici deux exécutions d’un programme PIE :
$ gcc test.c -fpie -pie ./a.out && cat /proc/`pidof a.out`/maps)
b75df000-b75e0000 rw-p 00000000 00:00 0
b75e0000-b7788000 r-xp 00000000 08:03 1313428 /usr/lib/libc-2.18.so
b7788000-b7789000 ---p 001a8000 08:03 1313428 /usr/lib/libc-2.18.so
b7789000-b778b000 r--p 001a8000 08:03 1313428 /usr/lib/libc-2.18.so
b778b000-b778c000 rw-p 001aa000 08:03 1313428 /usr/lib/libc-2.18.so
b778c000-b778f000 rw-p 00000000 00:00 0
b77ae000-b77af000 rw-p 00000000 00:00 0
b77af000-b77b0000 r-xp 00000000 00:00 0 [vdso]
b77b0000-b77d0000 r-xp 00000000 08:03 1313416 /usr/lib/ld-2.18.so
b77d0000-b77d1000 r--p 0001f000 08:03 1313416 /usr/lib/ld-2.18.so
b77d1000-b77d2000 rw-p 00020000 08:03 1313416 /usr/lib/ld-2.18.so
b77d2000-b77d3000 r-xp 00000000 08:04 261743 /home/tosh/Test/a.out
b77d3000-b77d4000 rw-p 00000000 08:04 261743 /home/tosh/Test/a.out
bf9ae000-bf9cf000 rw-p 00000000 00:00 0 [stack]
$ gcc test.c -fpie -pie && cat /proc/`pidof a.out`/maps)
b7528000-b7529000 rw-p 00000000 00:00 0
b7529000-b76d1000 r-xp 00000000 08:03 1313428 /usr/lib/libc-2.18.so
b76d1000-b76d2000 ---p 001a8000 08:03 1313428 /usr/lib/libc-2.18.so
b76d2000-b76d4000 r--p 001a8000 08:03 1313428 /usr/lib/libc-2.18.so
b76d4000-b76d5000 rw-p 001aa000 08:03 1313428 /usr/lib/libc-2.18.so
b76d5000-b76d8000 rw-p 00000000 00:00 0
b76f7000-b76f8000 rw-p 00000000 00:00 0
b76f8000-b76f9000 r-xp 00000000 00:00 0 [vdso]
b76f9000-b7719000 r-xp 00000000 08:03 1313416 /usr/lib/ld-2.18.so
b7719000-b771a000 r--p 0001f000 08:03 1313416 /usr/lib/ld-2.18.so
b771a000-b771b000 rw-p 00020000 08:03 1313416 /usr/lib/ld-2.18.so
b771b000-b771c000 r-xp 00000000 08:04 261743 /home/tosh/Test/a.out
b771c000-b771d000 rw-p 00000000 08:04 261743 /home/tosh/Test/a.out
bfd49000-bfd6a000 rw-p 00000000 00:00 0 [stack]
On voit que cette fois, il n’y a pas une seule plage mémoire qui n’est pas aléatoire !