带符号调试-gdb脚本实现自动化加载
问题由来
在对于堆的_IO_FILE
利用的学习过程中,我们通常需要伪造一个fake_IO_FILE,并且附带源码调试,以方便清除是否进入了目标函数,是否一些条件判断通过。但是有时候却在pwndbg加载时找不到对应的glibc的symbol
file文件,这就导致我们无法进行源码级别调试,而且看结构体只能自己一个一个字段带进去看,十分麻烦。所以这里介绍一下如何方便地进行带符号调试。


符号文件
Build ID
Build ID
是 ELF
文件(可执行文件和共享库)中一个独特的标识符,用于标识文件的内容。它是一个不可变的标志,通常用来快速匹配文件与其调试符号或源代码。
主要用途
- 唯一标识 ELF 文件:
- 即使文件名或路径改变,
Build ID
仍然可以唯一标识文件。 - 不同编译选项或源代码的修改会导致新的
Build ID
。
- 即使文件名或路径改变,
- 关联调试符号和源代码:
- 调试符号文件(如
.debug
文件)通常使用Build ID
来匹配对应的 ELF 文件。
- 调试符号文件(如
- 软件包管理和安全检查:
- 用于确保文件未被篡改,或用于匹配特定版本的依赖项。
生成方式
Build ID
是通过对 ELF
文件的内容(如代码段和数据段)进行哈希计算生成的,具体方式取决于工具链。它通常由
编译器 或 链接器 自动生成,存储在 ELF
文件的 .note.gnu.build-id
段中。
查看 ELF 文件的 Build ID
1 | 1.readelf -n /path/to/file | grep 'Build ID' |
.debug
通常symbol file
会在一个.debug/.build-id/xx/
的目录下,这里在build-id
中会有一堆2位16进制数构成的目录名,实际在.debug文件检索时,会先根据build-id
的第一个字节(最高位)来进入对应前缀的文件夹,然后在该目录下找对应的.debug文件。比如我们的build-id
为89c3cb85f9e55046776471fed05ec441581d1969
,那么我们目标的.debug文件就在.debug/.build-id/89/c3cb85f9e55046776471fed05ec441581d1969.debug
这个位置。

手动加载符号文件
一般来说,我们用glibc-all-in-one
下载到的glibc都是连带着.debug
一起下的,但我们pwndbg会找不到目标的符号文件。我们可以直接在gdb中用add-symbol-file /path/to/.debug
来读取符号信息。

或者也可以在~/.gdbinit
中加一个set debug-file-directory /path/to/glibc-all-in-one/libs/2.35-0ubuntu3_amd64/.debug/
,然后进入gdb时就会自动检索到.debug
文件,附加调试符号信息。
自动化进行附加符号文件
既然我们已经知道了手动附加的原理,这里我们就可以尝试使用脚本进行自动化附加。这里我们选择用gdb中的info proc mappings
命令来获取libc的基址以及路径,后续.debug文件路径的判断也是基于此。所以我们想要附加生效,就要链接到glibc-all-in-one中的libc。
在gdbinit中加入如下命令,这里使用了gdb.events.stop.connect
来使gdb在停下来的时候调用函数进行加载symbol file
,这是因为gdb.attach(p)时,.gdbinit
是先加载后再把gdb附加到进程的,如果直接调用会报错。
1 | python |
然后就能愉快地调试了,好耶。

一般换库步骤
1 | strings ./libc.so.6 | grep 'GNU' #看给的libc版本 |
- 标题: 带符号调试-gdb脚本实现自动化加载
- 作者: collectcrop
- 创建于 : 2024-11-23 19:31:26
- 更新于 : 2024-11-23 19:44:52
- 链接: https://collectcrop.github.io/2024/11/23/带符号调试-gdb脚本实现自动化加载/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。