Lukas' Notes

compilers file-formats

Definition

Global Offset Table (GOT)

The Global Offset Table (GOT) is the runtime-populated table inside an ELF binary that records the resolved addresses of shared-library functions the program calls. Entries start out pointing back into the dynamic linker’s resolver; the first call through the PLT resolves the symbol, patches the corresponding GOT slot, and from then on the PLT’s indirect jump reads the resolved address out of the GOT.

Role in Dynamic Linking

Why the GOT exists

Dynamic linking defers address resolution to runtime: at compile time the binary does not know where libc’s system will be loaded, because ASLR randomises that base per execution. The GOT is the per-process table that absorbs the deferred resolution: the PLT computes the indirection through it, the dynamic linker writes the resolved address into it, and the program’s code never needs to be patched. The .got section is the binary’s slot for that table; its contents are populated only after the binary starts running.

Exploiting Writability

GOT overwrite and ret2plt's target

The GOT lives in the binary’s .got section and is writable — the dynamic linker has to patch it at runtime, so the OS marks it writable. That writability is exploitable: an attacker with an arbitrary-write primitive of the right address can overwrite a GOT entry (e.g. puts’s slot) with the address of their chosen function, after which the next puts@plt calls the attacker’s function instead. Conversely, the ret2plt technique reads from the PLT — which uses the GOT — but does not need to write to the GOT, since it lets the dynamic linker do the resolution normally. The GOT is therefore a target both for arbitrary-write primitives (overwrite it) and for ret2plt’s mechanism (read through it).