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

2022-01-20 00:00:00 c hex gdb c++ memory-address

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

If I run a C/C++ program in gdb (after compiling with the -g flag) and I examine the addresses of certain variables, arguments...etc, and then I run it outside of gdb (using ./) will these addresses be the same as the ones I saw in gdb? If they're different are they usually similar or will they be drastically different?

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

I ask this because I have a buffer overflow program that works perfectly in gdb (with and without breakpoints), however when I try to run it outside of gdb it doesn't work.

推荐答案

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

I examine the addresses of certain variables, arguments...etc, and then I run it outside of gdb (using ./) will these addresses be the same as the ones I saw in gdb

视情况而定.

  1. 在主可执行文件中定义的全局变量将保持在同一地址(除非可执行文件是使用 -fpie 构建并与 -pie 标志链接的.
  2. 由于ASLR,在其他共享库中定义的全局变量可能具有截然不同的地址..李>
  3. 由于 ASLR,局部变量和参数可能会移动几个 K 字节.
  4. 由于 ASLR 或您的程序是多线程的,堆分配的变量也可能急剧移动.
  1. Global variables defined in the main executable will stay at the same address (unless the executable is built with -fpie and linked with -pie flags.
  2. Global variables defined in other shared libraries may have drastically different addresses due to ASLR.
  3. Local variables and parameters may move around by several K-bytes due to ASLR.
  4. Heap-allocated variables may also drastically move due to ASLR, or if your program is multi-threaded.

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

Note that GDB on Linux by default disables ASLR, to make debugging easier. You can re-enable ASLR under GDB with set disable-randomization off. That may allow you to reproduce the problem under GDB.

我的缓冲区溢出

另外请注意,像 Valgrind 和 Address Sanitizer 通常比在 GDB 下运行更有效地发现缓冲区溢出.Address Sanitizer 尤其很棒,因为它可以在全局变量和堆栈中发现缓冲区溢出(Valgrind 没有).

Also note, that tools like Valgrind and Address Sanitizer are often significantly more effective for finding buffer overflows than running under GDB. Address Sanitizer in particular is great in that it finds buffer overflows in globals and on stack (Valgrind doesn't).

相关文章