12

如果我在 gdb 中运行一个 C/C++ 程序(在使用 -g 标志编译之后)并检查某些变量、参数...等的地址,然后我在 gdb 之外运行它(使用./)这些地址将是和我在gdb中看到的一样吗?如果它们不同,它们通常是相似的还是会有很大的不同?

我问这个是因为我有一个在 gdb 中完美运行的缓冲区溢出程序(有和没有断点),但是当我尝试在 gdb 之外运行它时它不起作用。

4

3 回答 3

11

我检查某些变量、参数...等的地址,然后在 gdb 之外运行它(使用 ./)这些地址是否与我在 gdb 中看到的相同

这取决于。

  1. 主可执行文件中定义的全局变量将保持在相同的地址(除非可执行文件是使用标志构建-fpie并链接的。-pie
  2. 由于ASLR的原因,在其他共享库中定义的全局变量可能具有截然不同的地址。
  3. 由于 ASLR,局部变量和参数可能会移动几个 K 字节。
  4. 由于 ASLR,或者如果您的程序是多线程的,堆分配的变量也可能会急剧移动。

请注意,Linux 上的 GDB 默认禁用 ASLR,以使调试更容易。您可以在 GDB 下使用set disable-randomization off. 这可能允许您在 GDB 下重现该问题。

我有缓冲区溢出

另请注意,ValgrindAddress Sanitizer等工具在查找缓冲区溢出方面通常比在 GDB 下运行更有效。Address Sanitizer 尤其出色,因为它可以在全局变量和堆栈中发现缓冲区溢出(Valgrind 没有)。

于 2012-04-08T15:20:39.060 回答
2

您永远不应该假设某个代码或变量将位于固定位置。

过去在大多数操作系统中都是如此,但这是一个安全漏洞。恶意软件使用它来影响程序。操作系统将倾向于打乱地址以提高安全性。

于 2012-04-08T08:38:33.517 回答
0

使用标志编译会-g增加代码大小,因为它会嵌入可执行的额外信息。

至于您的缓冲区问题,在出现问题的地方发布一段代码会有所帮助。

于 2012-04-08T08:34:27.367 回答