Let’s consider a simple program like below:
#include <stdio.h>
void iLoveU()
{
// doing nothing
}
int main()
{
printf("%p", &iLoveU);
return 0;
}
Once you will compile and run the above code you will find the below output:
0x5b70f2e42149%
This will really trigger a question in your mind that:
0x5b702f42149%
as the address..text
segment.Also, according to the below image (taken from CS:APP)
The address of the iLoveU
should be near the starting address of .text
segment which is around 0x4000000..
, but this address is stored in the middle somwhere.
Local variables stored on the stack have addresses near 2^48 - 1
.
When GCC is configured with --enable-default-pie
(which is now the default), it generates Position Independent Executables (PIE). This means the actual load address of the program differs from the compile-time linker-specified address (0x400000 for x86_64). This is a security feature to support Address Space Layout Randomization (ASLR). Essentially, GCC uses the -pie
option by default during compilation.
If you compile with -no-pie
(e.g., gcc -no-pie file.c
), you’ll observe the address of functions closer to 0x400000.
On my setup, I get:
$ gcc -no-pie instruction_process_memory_layout.c
$ ./a.out
0x401136%
Expected output will be something like below:
You can confirm the load address using readelf
:
$ readelf -Wl pl.out | grep LOAD
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x000500 0x000500 R 0x1000
LOAD 0x001000 0x0000000000401000 0x0000000000401000 0x00017d 0x00017d R E 0x1000
LOAD 0x002000 0x0000000000402000 0x0000000000402000 0x00010c 0x00010c R 0x1000
LOAD 0x002e10 0x0000000000403e10 0x0000000000403e10 0x000220 0x000228 RW 0x1000
You can check if --enable-default-pie
is enabled by using gcc --verbose
.
You might also see that the address printed by your program changes with each execution due to ASLR. To disable ASLR for testing purposes, you can use:
$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
ASLR
is enabled by default on Linux systems.
References: