在 GDB 中翻译运行时地址

Posted

技术标签:

【中文标题】在 GDB 中翻译运行时地址【英文标题】:translate runtime addresses in GDB 【发布时间】:2022-01-05 15:01:26 【问题描述】:

当我使用 GDB 运行进程并且进程未运行时,我总是为相同的函数获得相同的地址。但是,当我运行该过程时,每次都会得到不同的地址。 如何比较同一进程的 2 次运行的地址? (二进制不包含调试符号)

【问题讨论】:

在gdb下运行时,默认禁用aslr。当你没有运行时,aslr 被启用。因此,您每次都会得到不同的地址。 【参考方案1】:

当进程运行时,动态内存映射可能会在您每次运行进程时发生变化。 观看它只需使用 gdb 命令: “信息过程映射” 另一种查看内存映射的方法是 bash "pmap" 命令。

每个映射区域都有起始地址和大小,如果从运行时地址减少起始地址,您将得到与 gdb 未运行时相同的地址,始终是相同的地址。

小例子:

映射输出如下所示:

     *Start Addr           End Addr       Size     Offset objfile
  0x563d17d8c000     0x563d17fd2000   0x246000        0x0 /opt/redislabs/bin/dmcproxy
  0x563d181d2000     0x563d181d8000     0x6000   0x246000 /opt/redislabs/bin/dmcproxy
  0x563d181d8000     0x563d181ee000    0x16000   0x24c000 /opt/redislabs/bin/dmcproxy*

您在运行时获得地址 0x0000563d17ed13fa。 为了将它转换为程序地址,你应该减少它的起始地址,起始地址是 0x563d17fd2000 所以结果地址是 0x1453fa

--> 这是你在二进制代码中的地址,如果它是一个函数的地址,你可以使用 objdump 或通过运行 gdb 而不运行程序来查看它。

如果您运行的二进制文件被剥离并且您在不同的机器上具有相同二进制文件的未剥离版本,您现在可以使用计算的地址来查看您通过在未剥离的二进制文件上运行 gdb 找到的地址的详细信息(不运行进程)并使用: “信息符号 0x1453fa” 即使您处于功能的中间,它也会起作用 (请注意,回溯会给您返回地址,而不是通常不同的函数地址)

【讨论】:

以上是关于在 GDB 中翻译运行时地址的主要内容,如果未能解决你的问题,请参考以下文章

gdb调试运行时的程序小技巧

C程序在GDB中运行,在自己运行时崩溃

C程序在GDB中工作,单独运行时崩溃

gdb调试

如何在GDB中调试多线程程序时一次继续一个线程?

如果使用调试信息编译,则通过其名称获取全局变量地址