PLT and GOT
Dynamic Linking
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.
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).
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
' :
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.
Read tables
Some tools permits to read the PLT and GOT tables :
$ 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
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}
Resources
Last updated