1. 启动与准备
1.1 编译时准备
- 核心要求: 必须使用
-g编译选项生成调试信息。gcc -g main.c -o my_program - 推荐: 对于 Pwn/逆向,使用
-O0(无优化) 和-fno-omit-frame-pointer(保留栈帧) 编译,以最大化代码与汇编的对应关系。
1.2 启动 GDB
| 命令 | 描述 | 备注 |
|---|---|---|
gdb <program> | 启动 GDB 并加载程序。 | |
file <program> | 在 GDB 内部加载新的可执行文件。 | 适用于中途需要切换分析对象。 |
run / r | 启动程序执行。 | 此时程序开始运行,直到遇到断点、结束或崩溃。 |
run <args> | 启动程序并传入命令行参数。 | 例如 r AAAA BAAA。 |
attach <pid> | 附着到正在运行的进程。 | 动态分析 Web 服务器或恶意进程时非常关键。 |
2. 断点与流程控制 (Breakpoints & Control)
这是 GDB 最常用的功能,用于暂停“历史”并进行介入。
2.1 设置断点
| 命令 | 描述 | 战略意义 |
|---|---|---|
break <func> / b | 在函数入口设置断点。 | 最常用的方式,例如 b main。 |
break <file>:<line> | 在源代码的特定行设置断点。 | |
break *<address> | 在内存的绝对地址设置断点。 | 汇编级调试和 Pwn 攻防的核心。例如 b *0x401122。 |
tbreak | 设置临时断点。 | 触发一次后自动删除。 |
watch <var> | 设置硬件监视点 (Watchpoint)。 | 当变量的值发生变化时暂停。用于追踪数据流污染。 |
2.2 流程控制
| 命令 | 描述 | 区别 |
|---|---|---|
continue / c | 继续执行,直到下一个断点或结束。 | |
next / n | 单步跳过函数调用。 | 在源码级别,将函数调用视为一条指令执行。 |
step / s | 单步进入函数调用。 | 深入函数内部(如 printf),适用于要追踪函数实现。 |
nexti / ni | 单步跳过一条汇编指令。 | 汇编级别。 |
stepi / si | 单步执行一条汇编指令。 | Pwn 攻防必备。用于精确定位指令执行流。 |
finish | 执行完当前函数,返回到调用者。 |
3. 检查状态 (Examination)
在程序暂停时,核心操作是检查寄存器、内存和栈。
3.1 寄存器 (Registers)
| 命令 | 描述 | |
|---|---|---|
info registers / i r | 显示所有寄存器的值。 | |
print $<reg> / p $<reg> | 显示特定寄存器。 | 例如 p $rip 或 p $rax。 |
set $<reg>=<value> | 修改寄存器值。 | 关键 Pwn 技术:劫持程序执行流(如修改 $rip)。 |
3.2 内存与数据 (Memory & Data)
核心命令: x/<count><format><size> <address/expr> (检查内存)
| 字段 | 描述 | 常用值 | 示例 |
|---|---|---|---|
| Count | 要显示的单元数量。 | 10 | x/10i $rip |
| Format | 显示格式。 | x (十六进制), d (十进制), s (字符串), i (指令) | |
| Size | 单元大小。 | b (字节), h (半字/2字节), w (字/4字节), g (双字/8字节) |
示例命令:
x/10gx $rsp: 以 64 位(g)十六进制(x)格式显示栈顶(rsp)开始的 10 个数据。x/20s 0x401000: 从地址开始显示 20 个字节的字符串(追踪字符串数据)。x/10i $rip: 从当前指令指针(rip)开始反汇编 10 条指令。
3.3 栈帧与回溯
| 命令 | 描述 | |
|---|---|---|
backtrace / bt | 显示完整的函数调用栈。 | 崩溃分析必备。找到错误的根源。 |
info frame / i f | 显示当前栈帧的详细信息。 | |
frame <n> | 切换到栈帧 <n>。 |
4. 增强工具:TUI 与 PEDA/GEF
GDB 默认界面难以阅读,强烈推荐使用增强插件:
4.1 TUI 模式
tui enable: 开启终端用户界面。layout asm: 显示汇编代码窗口。layout src: 显示源代码窗口。
4.2 GDB 增强插件 (GEF/PEDA)
- GEF (GDB Enhanced Features) 或 PEDA (Python Exploit Development Assistance) 是安全人员的标配。
- 安装 (GEF 推荐):
# 找一个方便的位置克隆
wget -qO- [https://gef.blah.cat/sh](https://gef.blah.cat/sh) | sh- 功能: 自动显示寄存器、栈、堆和代码流,极大地提高了效率和可读性。
5. 挑战系统的行动项 (Action Item)
现在,你已经掌握了 GDB 的核心指令。
- 实战练习 (CSAPP Lab 0): 随便找一个 CSAPP 实验中的 C 文件(比如第一个 lab 的某部分代码),用
-g和-fno-omit-frame-pointer编译。 - 启动与调试: 使用
gdb <program>启动。 - 核心任务:
- 设置断点:
b main - 运行:
r - 观察栈:
i r查看$rsp的值。然后运行x/20gx $rsp观察栈上的数据。 - 单步执行: 连续使用
si(step instruction) 执行几条指令。观察每执行一条指令后,$rip(指令指针) 和其他寄存器是如何变化的。
- 设置断点:
理解: 机器的执行过程,无非就是寄存器和内存值的不断改变。GDB 就是你的时间机器,让你暂停并检查这些核心生产资料的状态。