gdb地址和“真实”地址之间的区别?

时间:2012-04-08 08:29:30

标签: c++ c gdb hex memory-address

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

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

3 个答案:

答案 0 :(得分:9)

  

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

取决于。

  1. 主可执行文件中定义的全局变量将保留在同一地址(除非可执行文件使用-fpie构建并与-pie标记链接。
  2. 由于ASLR,其他共享库中定义的全局变量可能具有截然不同的地址。
  3. 由于ASLR,局部变量和参数可能会移动几个K字节。
  4. 由于ASLR,或者程序是多线程的,堆分配的变量也可能会大幅移动。
  5. 请注意,Linux上的GDB默认禁用ASLR,以便更轻松地进行调试。您可以使用set disable-randomization off在GDB下重新启用ASLR。这可能允许您在GDB下重现问题。

      

    我有缓冲区溢出

    另请注意,ValgrindAddress Sanitizer等工具在查找缓冲区溢出方面通常比在GDB下运行更有效。地址Sanitizer特别是很好,因为它在全局和堆栈中找到缓冲区溢出(Valgrind没有)。

答案 1 :(得分:2)

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

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

答案 2 :(得分:0)

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

关于你的缓冲区问题,在事情出错的情况下发布一段代码会有所帮助。