我了解了堆栈框架。但如果我是对的,在调用函数之前,该函数的参数会被插入堆栈框架。
例如,
int main(void)
{
printf("hi everyone %d \n", 3);
return 0;
}
在这种情况下,在主堆栈框架中,“Hi everyner %d\n”的地址和 3 应该被压入,然后必须调用 printf,如果我是对的。
但是我使用gdb时没有这样的指令。
我正在研究字符串格式漏洞。但我上面写的并没有发生。我这是怎么了?
最佳答案
对于您的简单程序:
#include <stdio.h>
int main(void)
{
printf("hi everyone %d \n", 3);
return 0;
}
编译为gcc -g -ansi -pedantic -Wall test.c -o test
(在使用gcc版本4.8.4的Ubuntu 14.04系统上),似乎printf的参数
正在寄存器中传递。在 printf
命令上设置断点并反汇编会产生以下结果:
Dump of assembler code for function main:
0x000000000040052d <+0>: push rbp
0x000000000040052e <+1>: mov rbp,rsp
=> 0x0000000000400531 <+4>: mov esi,0x3
0x0000000000400536 <+9>: mov edi,0x4005d4
0x000000000040053b <+14>: mov eax,0x0
0x0000000000400540 <+19>: call 0x400410 <printf@plt>
0x0000000000400545 <+24>: mov eax,0x0
0x000000000040054a <+29>: pop rbp
0x000000000040054b <+30>: ret
End of assembler dump.
我们可以看到值 3(在本例中作为文字编码到指令中)开始移动到 %esi
寄存器中,并且字符串的地址被移动到 >%edi
注册。您可以通过查看内存来验证这一点:
(gdb) x/16cb 0x4005d4
0x4005d4: 104 'h' 105 'i' 32 ' ' 101 'e' 118 'v' 101 'e' 114 'r' 121 'y'
0x4005dc: 111 'o' 110 'n' 101 'e' 32 ' ' 37 '%' 100 'd' 32 ' ' 10 '\n
此外,您可以检查堆栈和基指针,您会注意到在这个简单的程序中没有使用堆栈:
(gdb) print $rbp
$4 = (void *) 0x7fffffffe460
(gdb) print $rsp
$5 = (void *) 0x7fffffffe460
as $rpb
和 $rsp
具有相同的值。
希望这有帮助。 -T。
关于c - 关于堆栈帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34638541/