I debug a program with gdb for fun, with stack guard so it writes the canary to the stack from fs:28h. Out of curiosity, I trying to find the memory address that fs:28h points to. I encounter two problems. first, gdb cannot show me the value in gdtr/ldtr because it doesn't run in ring zero. second, When reading fs with gdb it contains 0, how does it make sense? I know that gdt/ldt contain 0 in the first index to return invalid address and the RPL is off so what am I missing here? If anyone knows how to find the address that segment register fs points to I would like to know.
file: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked
You appear to be using
x86_64-linux-gnu, i.e. all three of x86-64 CPU, Linux kernel, and the GNU C Library. With this combination of hardware and system software, the FS segment is set such that the memory operand%fs:0refers to the beginning of the thread control block for the currently executing thread. (A thread control block is an internal C library data structure that describes a running thread. You can think of it as the object referred to by apthread_tthread handle.)Precisely because x86 has historically not made it easy for unprivileged code to look up the "actual" address (more precisely "linear virtual address") referred to by a
%fs:xxxor%gs:xxxmemory operand, the first field of the thread control block onx86_64-linux-gnuis a pointer to the thread control block itself. Thus,will return the address you want. Keep in mind that this is only guaranteed to be true on
x86_64-linux-gnu. If you switch to a different Unix kernel (e.g. FreeBSD) or a different C library (e.g. musl libc), there's a good chance that the FS segment will still point to the thread control block, but the data in that space is likely to be rather different.