【问题标题】:Disassembling C code and inspecting stack反汇编 C 代码并检查堆栈
【发布时间】:2019-04-18 12:35:05
【问题描述】:

所以我有一些简单的 C 代码来创建大小为 512 字节的缓冲区:

 #include <sys/types.h>
 #include <netinet/in.h>

 #include <stdio.h>
 #include <ctype.h>

 main(argc, argv)
      char *argv[];
 {
    char line[512];
    gets(line);
 }

这是否意味着恰好为该缓冲区分配了 512 个字节?在 GDB 中有没有办法我们可以反汇编编译后的二进制文件,我们可以看到类似的东西

  • 栈到返回地址的距离
  • 什么参数被传递给'gets()'函数..比如地址?

我尝试使用 GDB 逐步执行此操作,但找不到检查此类内容的方法

【问题讨论】:

  • 我不确定我是否完全理解你在问“堆栈和返回地址之间的距离” - 你可以让 gdb 打印一个函数的反汇编,例如 (gdb) disas /s main 见@ 987654321@
  • 我认为这里不需要 gdb。查看 objdump --disassemble 并查看 linux.die.net/man/1/objdump 。你可以在那里看到指令的汇编代码,你会看到堆栈将减少大约 512 字节的大小 - 如果不需要对齐。
  • C 中没有gets 函数。请扔掉任何教它的书。
  • @n.m 它似乎工作,所以也许坚持那些书
  • 1970 年代打电话,他们想要回他们的 pre-ANSI C 代码。

标签: c memory gdb


【解决方案1】:

您可以查看“strace”命令行工具。它将列出所有内部系统调用和相应的参数。它还会让您了解分配了多少内存。

请注意,您应该谨慎使用gets,因为它不会检查缓冲区溢出。

来自手册页:

gets() 从标准输入读取一行到 s 指向的缓冲区,直到一个终止换行符或 EOF,它 替换为“\0”。不检查缓冲区溢出(请参阅下面的错误)。

【讨论】:

    【解决方案2】:

    如果需要,可以使用 printf 显示内存地址,例如:

    #include <stdio.h>
    int main() {
      char line1[512];
      char line2[512];
      char line3[512];
      printf("line1 ptr: %p\n", line1);
      printf("line2 ptr: %p\n", line2);
      printf("line3 ptr: %p\n", line3);
      long int diff = line3 - line1;
      printf("diff between line3 and line1 : %ld\n", diff);
      return 0;
    }
    

    如果你运行它,你可能会看到 line1、line2 和 line1 的内存位置之间正好有 512 个字节,如果编译器选择以这种方式在内存中布局的话。

    【讨论】:

    • 您不能从line3 中减去line1,因为它会产生未定义的行为。
    猜你喜欢
    • 2014-05-29
    • 2015-12-23
    • 2011-12-05
    • 1970-01-01
    • 2017-11-18
    • 2019-10-01
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    相关资源
    最近更新 更多