Address space layout randomization, aka ASLR -- and position independent executables (PIE), are used to improve the security of modern operating systems by making memory addresses less predictable.
Position-independent executables utilize address space layout randomization and have their base entry function shifted at runtime. We can see this by comparing the entry point address
at runtime with the base address seen via readelf
.
$ readelf -h /usr/bin/ls
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Position-Independent Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x6d30
Start of program headers: 64 (bytes into file)
Start of section headers: 140328 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 13
Size of section headers: 64 (bytes)
Number of section headers: 31
Section header string table index: 30
On a system with PIE enabled binaries, the entry point _start
will be modified because it gets computed in addition with another value. Runtime addresses essentially get calculated like:
Runtime Address = Base Address + Entry Point Offset
We can visualize this with a simple C program that prints the address of its main
function. PIE will also shift all of the other functions addresses.
#include <stdio.h>
int main() {
// Print the address of the main function
printf("Address of main: %p\n", main);
return 0;
}
gcc -o entry entry.c
hexagr@vr:~$ ./entry
Address of main: 0x62498320c149
hexagr@vr:~$ ./entry
Address of main: 0x61bcab5a7149
hexagr@vr:~$ ./entry
Address of main: 0x587688ff8149
PIC
If we force the additional use of the fPIC
flag, we can make gcc
to generate position-independent code (assembly) which (if not optimized away) might use the Global Offset Table.
hexagr@vr:~$ gcc -fPIC -S main.c -o main_fpic.s
hexagr@vr:~$ gcc -S main.c -o main_not_fpic.s
hexagr@vr:~$ diff main_fpic.s main_not_fpic.s
18c18
< movq main@GOTPCREL(%rip), %rax
---
> leaq main(%rip), %rax
No comments:
Post a Comment