47

我已经编写了一段 C 代码,并对其进行了反汇编并读取了寄存器以了解程序在汇编中是如何工作的。

int test(char *this){
    char sum_buf[6];
    strncpy(sum_buf,this,32);
    return 0;
}

我一直在检查的代码是测试功能。当我反汇编输出我的测试功能时,我得到...

   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 

我想知道的mov %fs:0x28,%rax是真正在做什么?

4

3 回答 3

78

FS和寄存器都GS可以用作基指针地址,以便访问特殊的操作系统数据结构。因此,您所看到的是加载的值与寄存器中保存的值的偏移量FS,而不是对FS寄存器内容的位操作。

具体来说,FS:0x28Linux 上正在存储一个特殊的哨兵堆栈保护值,并且代码正在执行堆栈保护检查。例如,如果您进一步查看代码,您会发现 at 的值FS:0x28存储在堆栈中,然后调用堆栈的内容并XOR使用原始值 at 执行an FS:0x28。如果两个值相等,这意味着已经设置了零位,因为XOR'ing 两个相同的值会导致零值,然后我们跳转到test例程,否则我们跳转到一个特殊函数,该函数指示堆栈以某种方式损坏,并且存储在堆栈中的标记值已更改。

如果使用 GCC,可以使用以下命令禁用

-fno-stack-protector
于 2012-04-26T01:03:02.440 回答
0
glibc:
  uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
# ifdef THREAD_SET_STACK_GUARD
  THREAD_SET_STACK_GUARD (stack_chk_guard); 

the _dl_random from kernel.
于 2019-07-08T04:56:15.550 回答
-3

查看http://www.imada.sdu.dk/Courses/DM18/Litteratur/IntelnATT.htm,我认为%fs:28实际上是从%fs. 所以我认为它将一个完整的寄存器大小从位置加载%fs + 28到%rax。

于 2012-04-26T00:43:17.170 回答