# PIE

**P**osition **I**ndependent **E**xecutable (**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.

{% hint style="danger" %}
Add the parameter `-no-pie -fno-pie` using gcc in order to disable PIE when compiling the binary
{% endhint %}

## 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**.

{% hint style="info" %}
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.
{% endhint %}

## 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.

{% hint style="info" %}
Checking the base address ends in `000` it's a good point to validate the leaked address.
{% endhint %}

## 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](/pwn/general-knowledge/operation-of-the-stack.md) !

The return pointer is often stored on the stack. By using a technique such as [format string](/pwn/stack-exploitation/format-string/data-leak.md) 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**.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.ctfrecipes.com/pwn/protections/pie.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
