Skip to content

Registers

x86-64

x86 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

PlatformRegisterPoints to
Linux (userland)FSThread-Local Storage (TLS) block / pthread TCB
Windows (userland)GSThread Environment Block (TEB)
macOS (userland)GSThread-Local Storage
Linux kernelGSPer-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:

OffsetField
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)
asm
mov rax, gs:[0x60]    ; rax → PEB
mov rax, [rax+0x10]   ; rax → PEB.ImageBaseAddress

Walking 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

asm
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:[...] or fs:[...] 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.