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 $ripp $rax
set $<reg>=<value>修改寄存器值。关键 Pwn 技术:劫持程序执行流(如修改 $rip)。

3.2 内存与数据 (Memory & Data)

核心命令: x/<count><format><size> <address/expr> (检查内存)

字段描述常用值示例
Count要显示的单元数量。10x/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 的核心指令。

  1. 实战练习 (CSAPP Lab 0): 随便找一个 CSAPP 实验中的 C 文件(比如第一个 lab 的某部分代码),用 -g-fno-omit-frame-pointer 编译。
  2. 启动与调试: 使用 gdb <program> 启动。
  3. 核心任务:
    • 设置断点: b main
    • 运行: r
    • 观察栈: i r 查看 $rsp 的值。然后运行 x/20gx $rsp 观察栈上的数据。
    • 单步执行: 连续使用 si (step instruction) 执行几条指令。观察每执行一条指令后,$rip (指令指针) 和其他寄存器是如何变化的。

理解: 机器的执行过程,无非就是寄存器和内存值的不断改变。GDB 就是你的时间机器,让你暂停并检查这些核心生产资料的状态。