查找在 gdb 中调试的程序的基址和内存大小

逆向工程 调试 数据库 调试器 小精灵
2021-06-26 07:18:19

我想找出gdb中正在调试的程序的基地址和图像大小。就像在内存中加载它的地方一样。对于共享库,我可以执行“info sharedlibrary”,并且得到非常好的输出,如下所示:

0x00007ffff7dd5f10  0x00007ffff7df4b20  Yes         /lib64/ld-linux-x86-64.so.2

我如何获得我正在调试的主程序的输出?

我知道 gdb 禁用了 ASLR,我可以自己检查 ELF 文件以找出答案,但也必须有一种通过 gdb 的方法。

(背景:我正在使用gdb的mi,我可以通过解析sharedlibrary-load消息来保持对事物所在位置的基本概述。但它从未向主程序发送这样的消息,这是最重要的。)

谢谢!

2个回答

info file 显示当前进程的内存映射:

Local exec file:
        `/bin/less', file type elf64-x86-64.
        Entry point: 0x402080
        0x0000000000400238 - 0x0000000000400254 is .interp
        0x0000000000400254 - 0x0000000000400274 is .note.ABI-tag
        0x0000000000400274 - 0x0000000000400298 is .note.gnu.build-id
        0x0000000000400298 - 0x00000000004002e0 is .gnu.hash
        0x00000000004002e0 - 0x0000000000400b20 is .dynsym
        0x0000000000400b20 - 0x0000000000400e7d is .dynstr
        0x0000000000400e7e - 0x0000000000400f2e is .gnu.version
        0x0000000000400f30 - 0x0000000000400fa0 is .gnu.version_r
        0x0000000000400fa0 - 0x0000000000401000 is .rela.dyn
        0x0000000000401000 - 0x0000000000401708 is .rela.plt
        0x0000000000401708 - 0x0000000000401722 is .init
        0x0000000000401730 - 0x0000000000401bf0 is .plt
        0x0000000000401bf0 - 0x0000000000415824 is .text
        0x0000000000415824 - 0x000000000041582d is .fini
        0x0000000000415840 - 0x000000000041bd67 is .rodata
        0x000000000041bd68 - 0x000000000041c90c is .eh_frame_hdr
        0x000000000041c910 - 0x00000000004208e4 is .eh_frame
        0x0000000000620e00 - 0x0000000000620e08 is .init_array
        0x0000000000620e08 - 0x0000000000620e10 is .fini_array
        0x0000000000620e10 - 0x0000000000620e18 is .jcr
        0x0000000000620e18 - 0x0000000000620ff8 is .dynamic
        0x0000000000620ff8 - 0x0000000000621000 is .got
        0x0000000000621000 - 0x0000000000621270 is .got.plt
        0x0000000000621280 - 0x000000000062500c is .data
        0x00007fffff4001c8 - 0x00007fffff4001ec is .note.gnu.build-id in /lib64/ld-linux-x86-64.so.2
        0x00007fffff4001f0 - 0x00007fffff4002ac is .hash in /lib64/ld-linux-x86-64.so.2
        0x00007fffff4002b0 - 0x00007fffff40038c is .gnu.hash in /lib64/ld-linux-x86-64.so.2
        0x00007fffff400390 - 0x00007fffff400630 is .dynsym in /lib64/ld-linux-x86-64.so.2

末尾没有文件名的行是主可执行文件的行。

您可以执行以下操作:

  • info inferior或者print getpid()给你一个进程ID
  • shell pmap -x {the process id} 为您提供进程的内存映射(它不是 gdb 的功能,pmap 是其他 shell 命令,但它比分析 ELF 好一点)
  • 您也可以使用shell cat /proc/{pid}/mapsfile (据我所知 pmap 只是解析并打印其内容)

您会看到类似这样的内容(这是我刚刚调试的名为 opt 的进程的结果):

6648:   /home/ubuntu/llvm-5.0.1.src/build/bin/opt
Address           Kbytes     RSS   Dirty Mode  Mapping
0000000000400000  100524   36380       8 r-x-- opt
0000000000400000       0       0       0 r-x-- opt
000000000682a000    4176     356     296 r---- opt
000000000682a000       0       0       0 r---- opt
0000000006c3e000     628      76      76 rw--- opt
0000000006c3e000       0       0       0 rw--- opt
0000000006cdb000     684     480     480 rw---   [ anon ]
0000000006cdb000       0       0       0 rw---   [ anon ]
00007ffff6908000    1792    1056       8 r-x-- libc-2.23.so
00007ffff6908000       0       0       0 r-x-- libc-2.23.so
00007ffff6ac8000    2048       0       0 ----- libc-2.23.so
00007ffff6ac8000       0       0       0 ----- libc-2.23.so
00007ffff6cc8000      16      16      16 r---- libc-2.23.so
00007ffff6cc8000       0       0       0 r---- libc-2.23.so
00007ffff6ccc000       8       8       8 rw--- libc-2.23.so
00007ffff6ccc000       0       0       0 rw--- libc-2.23.so
00007ffff6cce000      16      12      12 rw---   [ anon ]
00007ffff6cce000       0       0       0 rw---   [ anon ]
...
...

如果我正确理解你的问题,那行

  0000000000400000  100524   36380       8 r-x-- opt

是你所需要的。