Registers
x86-64x86 Segment Registers (FS / GS and the TEB/PEB)
In 64-bit user mode FS and GS are repurposed as thread-local and process-local base pointers — FS on Linux points to the TLS block, GS on Windows to the TEB.
x86-64 retains six segment registers (CS, DS, ES, SS, FS, GS) but
in 64-bit (Long Mode) the base of CS/DS/ES/SS is forced to zero by the
CPU. Only FS and GS retain programmable bases — set via MSRs
(IA32_FS_BASE / IA32_GS_BASE) or the WRFSBASE/WRGSBASE instructions.
Platform usage
| Platform | Register | Points to |
|---|---|---|
| Linux (userland) | FS | Thread-Local Storage (TLS) block / pthread TCB |
| Windows (userland) | GS | Thread Environment Block (TEB) |
| macOS (userland) | GS | Thread-Local Storage |
| Linux kernel | GS | Per-CPU data; SWAPGS switches on kernel entry |
Windows: GS and the TEB/PEB
On Windows, GS:0 is the start of the TEB (Thread Environment Block).
Key offsets:
| Offset | Field |
|---|---|
GS:[0x00] | ExceptionList (SEH chain head) |
GS:[0x08] | Stack base |
GS:[0x10] | Stack limit |
GS:[0x30] | Pointer to the TEB itself |
GS:[0x60] | Pointer to the PEB (Process Environment Block) |
mov rax, gs:[0x60] ; rax → PEB
mov rax, [rax+0x10] ; rax → PEB.ImageBaseAddressWalking the PEB to find module bases and export tables is a classic shellcode technique for resolving API addresses without importing symbols.
Linux: FS and TLS
mov rax, fs:[0x00] ; pointer to the TCB (pthread_self())
mov rax, fs:[0x28] ; stack canary (stack guard value on Linux/glibc)fs:[0x28] is the stack canary location on Linux — placed in function
prologues as mov rax, fs:[0x28]; mov [rsp+offset], rax and checked in
epilogues.
Reverse-engineering notes
- Any
gs:[...]orfs:[...]access in disassembly immediately signals privileged/system data access or TLS. Check the platform and offset. - The
fs:[0x28]stack canary read/write pair appearing in every function prologue/epilogue is compiler-inserted SSP (Stack Smashing Protector) — safe to treat as boilerplate. - PEB-walking shellcode (
mov rax, gs:[0x60]) is a reliable indicator of position-independent Windows shellcode that does not rely on an IAT.