Why does this memory address %fs:0x28 ( fs[0x28] ) have a random value?
buffer-overflow, c, disassembly, gcc, x86-64
Solution
Both the `FS` and `GS` registers can be used as base-pointer addresses in order to access special operating system data-structures. So what you're seeing is a value loaded at an offset from the value held in the `FS` register, and not bit manipulation of the contents of the `FS` register.
Specifically what's taking place, is that `FS:0x28` on Linux is storing a special sentinel stack-guard value, and the code is performing a stack-guard check. For instance, if you look further in your code, you'll see that the value at `FS:0x28` is stored on the stack, and then the contents of the stack are recalled and an `XOR` is performed with the original value at `FS:0x28`. If the two values are equal, which means that the zero-bit has been set because `XOR`'ing two of the same values results in a zero-value, then we jump to the `test` routine, otherwise we jump to a special function that indicates that the stack was somehow corrupted, and the sentinel value stored on the stack was changed.
If using GCC, this can be disabled with:
-fno-stack-protector
Problem
I've written a piece of C code and I've disassembled it as well as read the registers to understand how the program works in assembly. ``` int test(char *this){ char sum_buf[6]; strncpy(sum_buf,this,32); return 0; } ``` The piece of my code that I've been examining is the test function. When I disassemble the output my test function I get ... ``` 0x00000000004005c0 <+12>: mov %fs:0x28,%rax => 0x00000000004005c9 <+21>: mov %rax,-0x8(%rbp) ... stuff .. 0x00000000004005f0 <+60>: xor %fs:0x28,%rdx 0x00000000004005f9 <+69>: je 0x400600 <test+76> 0x00000000004005fb <+71>: callq 0x4004a0 <__stack_chk_fail@plt> 0x0000000000400600 <+76>: leaveq 0x0000000000400601 <+77>: retq ``` What I would like to know is what `mov %fs:0x28,%rax` is really doing?