# PLT and GOT

The **Procedure Linkage Table (PLT)** and **Global Offset Table (GOT)** are sections within an **Executable and Linkable Format** (**ELF**) file that play a significant role in dynamic linking.&#x20;

The purpose of dynamic linking is to reduce the size of binaries by allowing them to rely on system libraries, such as the C standard library (**libc**), to provide the majority of their functionality.

For example, an ELF file **does not include its own version of the '`printf`' function** compiled within it. Instead, it **dynamically links to the '`printf`' function of the system** it is running on. In addition to **smaller binary sizes**, this also means that users can **upgrade their libraries without having to download all the binaries again** each time a new version is released.

## How it works ?

The linking is performed through the cooperation of the **Procedure Linkage Table** (**PLT**) and the **Global Offset Table** (**GOT**).&#x20;

When the '`printf`' function, for example, is called in C and compiled as an ELF executable, it is not included as '`printf`' in the file. Instead, it is compiled as '`printf@plt`' :&#x20;

```wasm
   0x0804925b <+137>:   push   0x804a012
   0x08049260 <+142>:   call   0x8049040 <printf@plt>
   0x08049265 <+147>:   add    esp,0x10
```

The program does not know the actual location of 'printf', so it jumps to the '`printf@plt`' entry instead. When this occurs, '`printf@plt`' performs some specific actions.

* If there isn't a GOT entry, it will resolve it and jump there.
* If there is a GOT entry for `printf`, it jumps to the address stored there.

The GOT is a *massive* table of addresses; these addresses are the actual locations in memory of the `library` functions. `printf@got`, for example, will contain the address of `printf` in memory. When the PLT gets called, it reads the GOT address and redirects execution there. If the address is empty, it coordinates with the `ld.so` (also called the **dynamic linker/loader**) to get the function address and stores it in the GOT.

{% hint style="info" %}

* Calling the PLT address of a function is equivalent to calling the function itself
* The GOT address contains addresses of functions in `libraries`, and the GOT is within the binary.
  {% endhint %}

## Read tables

Some tools permits to read the PLT and GOT tables :&#x20;

```bash
$ readelf -r chall

Relocation section '.rel.dyn' at offset 0x3bc contains 1 entry:
 Offset     Info    Type            Sym.Value  Sym. Name
0804bffc  00000606 R_386_GLOB_DAT    00000000   __gmon_start__

Relocation section '.rel.plt' at offset 0x3c4 contains 9 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0804c00c  00000107 R_386_JUMP_SLOT   00000000   strcmp@GLIBC_2.0
0804c010  00000207 R_386_JUMP_SLOT   00000000   printf@GLIBC_2.0
0804c014  00000307 R_386_JUMP_SLOT   00000000   fclose@GLIBC_2.1
0804c018  00000407 R_386_JUMP_SLOT   00000000   fread@GLIBC_2.0
0804c01c  00000507 R_386_JUMP_SLOT   00000000   puts@GLIBC_2.0
0804c020  00000707 R_386_JUMP_SLOT   00000000   __libc_start_main@GLIBC_2.0
0804c024  00000807 R_386_JUMP_SLOT   00000000   fopen@GLIBC_2.1
0804c028  00000907 R_386_JUMP_SLOT   00000000   putchar@GLIBC_2.0
0804c02c  00000a07 R_386_JUMP_SLOT   00000000   __isoc99_scanf@GLIBC_2.7
```

{% code overflow="wrap" %}

```python
from pwn import *

elf = ELF("./chall")

print(elf.plt)
# {'strcmp': 134516784, 'printf': 134516800, 'fclose': 134516816, 'fread': 134516832, 'puts': 134516848, '__libc_start_main': 134516864, 'fopen': 134516880, 'putchar': 134516896, '__isoc99_scanf': 134516912}

print(elf.got)
# {'__gmon_start__': 134529020, 'strcmp': 134529036, 'printf': 134529040, 'fclose': 134529044, 'fread': 134529048, 'puts': 134529052, '__libc_start_main': 134529056, 'fopen': 134529060, 'putchar': 134529064, '__isoc99_scanf': 134529068}
```

{% endcode %}

## Resources

{% embed url="<https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got>" %}


---

# 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/general-knowledge/plt-and-got.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.
