c - 关于堆栈帧

标签 c gdb stack

我了解了堆栈框架。但如果我是对的,在调用函数之前,该函数的参数会被插入堆栈框架。

例如,

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/

相关文章:

c - 多维字符数组从 C 函数返回错误

c - 如何让 backtrace()/backtrace_symbols() 打印函数名?

c - 如何中断对 gdb 中特定全局变量的访问?

ruby-on-rails - Rails SaaS 应用程序的最佳服务器堆栈/配置是什么

c - 打印堆栈指针与 backtrace() 打印输出

c++ - 使用 C/C++ 访问 OS X 钥匙串(keychain)

c - 在 C 中重新排序对多个 volatile 变量的访问

GDB远程协议(protocol): how to analyse packets?

gdb - 当前上下文中没有符号 "color"。广东发展银行

c++ - 我可以用尽堆栈吗?