PIE

Position Independent Executable

Position Independent Executable (PIE) is a feature that causes the file to be loaded into a different memory address every time it is run.

This means that hardcoding values, such as function addresses and gadget locations, is not possible without first determining their locations.

Add the parameter -no-pie -fno-pie using gcc in order to disable PIE when compiling the binary

How it works ?

PIE executables are based on relative rather than absolute addresses, meaning that while the locations in memory are random the offsets between different parts of the binary remain constant.

If the function main is located 0x42 bytes after the base address of the binary, this offset will always be the same on each runtime.

This means that if the address of the main function is leaked, it's possible to recover the base address of the binary by simply subtracting 0x42.

Double-Checking

Due to the way PIE randomisation works, the base address of a PIE executable will always end in the hexadecimal characters 000. This is because pages are the things being randomised in memory, which have a standard size of 0x1000. Operating Systems keep track of page tables which point to each section of memory and define the permissions for each section, similar to segmentation.

Checking the base address ends in 000 it's a good point to validate the leaked address.

Bypassing PIE

It is possible to bypass PIE, by finding a single address and using it to determine the location of the binary in memory. One way to leak this address is through the stack !

The return pointer is often stored on the stack. By using a technique such as format string exploitation or some other method, it is possible to read the value of the return pointer off the stack.

Since the return pointer is a static offset away from the base address of the binary, it can be used to calculate the location of the binary in memory.

Last updated