GCC 堆栈金丝雀的位置

Position of GCC stack canaries

除非我误解了什么,金丝雀值的位置似乎可以在ebp之前或之后,因此在第二种情况下,攻击者可以在不接触金丝雀的情况下覆盖帧指针。

例如,在此代码段中,金丝雀位于比 ebp 更低的地址 (ebp-0xc),因此保护它(攻击者必须覆盖金丝雀才能覆盖 ebp) :

0x080484e0 <+52>: mov eax,DWORD PTR [ebp-0xc]
0x080484e3 <+55>: xor eax,DWORD PTR gs:0x14
0x080484ea <+62>: je 0x80484f1 <func+69>
0x080484ec <+64>: call 0x8048360 <__stack_chk_fail@plt>

但是看看金丝雀在 rbp+8:

之后的其他代码

我该如何解读?这取决于 GCC 版本还是其他?

金丝雀始终位于帧指针下方,我尝试过的每个版本的 gcc 都是如此。您可以在您链接的博客 post 中的 IDA 反汇编正下方的 gdb 反汇编中看到确认,其中有 mov rax, QWORD PTR [rbp-0x8].

我认为这只是 IDA 反汇编程序的神器。它不是显示 rbp 相对地址的数字偏移量,而是为每个堆栈槽分配一个名称,并显示该名称;基本上假设每个 rbp 相对访问都是对局部变量或参数的访问。看起来它总是显示带有 + 的名称,无论偏移量是正数还是负数。请注意 buffd 也会得到一个 + 符号,即使它们是明显低于帧指针的局部变量。

在此示例中,它已将金丝雀命名为 var_8,就好像它是一个局部变量一样。所以我想正确翻译这个,你必须认为 var_8 具有值 -8.