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?
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.
The registers FS and GS are segment registers. They have no processor-defined purpose, but instead are given purpose by the OS's running them. In Windows 64-bit the GS register is used to point to operating system defined structures. FS and GS are commonly used by OS kernels to access thread-specific memory.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With