GDB + pwndbg
2026/5/29工具工具逆向工程GDBpwndbg大约 7 分钟
GDB + pwndbg
链接
是什么
GDB(GNU Debugger)是 GNU 项目开发的标准调试器,用于调试 C/C++ 等编译型语言程序。pwndbg 是一个专为逆向工程和漏洞利用开发的 GDB 插件,提供了丰富的增强功能,使得调试更加直观和高效。
GDB 核心功能:
- 设置断点和单步执行
- 查看和修改内存/寄存器
- 分析程序崩溃原因
- 跟踪程序执行流程
- 动态修改程序行为
pwndbg 增强功能:
- 彩色化的堆分析命令
- 自动化的 ROP gadget 搜索
- 增强的内存映射显示
- 堆可视化和分析
- 漏洞利用辅助命令
- 与 pwntools 集成
在 CTF Pwn 类题目中,GDB + pwndbg 是最重要的调试组合,用于分析程序漏洞和调试利用代码。
安装与配置
安装 GDB
# Ubuntu/Debian
sudo apt update && sudo apt install gdb
# CentOS/RHEL
sudo yum install gdb
# Arch Linux
sudo pacman -S gdb
# 验证安装
gdb --version安装 pwndbg
# 方法一:从 GitHub 安装(推荐)
git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh
# 方法二:使用 pip
pip install pwndbg
# 方法三:Kali Linux(预装)
pwndbg --version配置 pwndbg
pwndbg 安装后会自动配置 GDB。配置文件位于:
~/.gdbinit:GDB 启动配置- pwndbg 会自动在
.gdbinit中添加加载命令
# 查看配置
cat ~/.gdbinit
# 应包含类似内容:
# source /path/to/pwndbg/gdbinit.py安装辅助工具
# 安装 GEF(另一个流行的 GDB 插件,可选)
# bash -c "$(curl -fsSL https://gef.blah.cat/sh)"
# 安装 pwntools(Python Pwn 工具库)
pip install pwntools
# 安装 ROPgadget
pip install ROPgadget基本用法
启动 GDB
# 调试可执行文件
gdb ./program
# 调试正在运行的进程
gdb -p <pid>
# 调试核心转储文件
gdb ./program core
# 调试时传递参数
gdb --args ./program arg1 arg2
# 附加到进程
gdb attach <pid>基本命令
# 运行程序
(gdb) run
(gdb) r
# 带参数运行
(gdb) r arg1 arg2
# 继续执行
(gdb) continue
(gdb) c
# 单步执行(进入函数)
(gdb) step
(gdb) s
# 单步执行(不进入函数)
(gdb) next
(gdb) n
# 单步执行一条指令
(gdb) stepi
(gdb) si
# 单步执行一条指令(不进入函数)
(gdb) nexti
(gdb) ni
# 退出 GDB
(gdb) quit
(gdb) q断点操作
# 在函数处设置断点
(gdb) break main
(gdb) b main
# 在地址处设置断点
(gdb) b *0x401234
(gdb) b *main+100
# 条件断点
(gdb) b main if $rax == 0
(gdb) b *0x401234 if *(int*)($rbp-4) == 0x42
# 硬件断点(用于只读内存)
(gdb) hbreak *0x401234
# 监视点(当变量值改变时中断)
(gdb) watch *(int*)0x601000
# 读监视点(当变量被读取时中断)
(gdb) rwatch *(int*)0x601000
# 访问监视点(当变量被读或写时中断)
(gdb) awatch *(int*)0x601000
# 查看所有断点
(gdb) info breakpoints
(gdb) i b
# 删除断点
(gdb) delete 1 # 删除断点 1
(gdb) delete # 删除所有断点
# 禁用/启用断点
(gdb) disable 1
(gdb) enable 1
# 忽略断点 N 次
(gdb) ignore 1 10 # 忽略断点 1 的前 10 次触发寄存器操作
# 查看所有寄存器
(gdb) info registers
(gdb) i r
# 查看特定寄存器
(gdb) print $rax
(gdb) p $rax
# 修改寄存器
(gdb) set $rax = 0x42
(gdb) set $pc = 0x401234
# pwndbg 增强命令
pwndbg> regs # 彩色显示所有寄存器
pwndbg> context reg # 在上下文中显示寄存器内存操作
# 查看内存(十六进制)
(gdb) x/10x $rsp # 查看栈顶 10 个 QWORD
(gdb) x/20x $rbp-0x20 # 查看栈帧
(gdb) x/10x 0x601000 # 查看指定地址
# 查看内存(字符串)
(gdb) x/s 0x401000
# 查看内存(指令)
(gdb) x/10i $rip
(gdb) x/10i main
# 格式说明:
# x/NFU addr
# N: 数量
# F: 格式(x=十六进制, d=十进制, s=字符串, i=指令, c=字符)
# U: 单位(b=字节, h=半字, w=字, g=双字)
# 修改内存
(gdb) set {int}0x601000 = 0x42
(gdb) set {char}0x601000 = 'A'
# pwndbg 增强命令
pwndbg> hexdump $rsp 20 # 彩色十六进制转储
pwndbg> telescope $rsp 20 # 带引用追踪的栈显示
pwndbg> db $rsp 20 # 显示字节
pwndbg> dw $rsp 20 # 显示 WORD
pwndbg> dd $rsp 20 # 显示 DWORD
pwndbg> dq $rsp 20 # 显示 QWORD栈和帧操作
# 查看调用栈
(gdb) backtrace
(gdb) bt
# 切换栈帧
(gdb) frame 0
(gdb) f 0
(gdb) frame 2
# 查看当前帧信息
(gdb) info frame
(gdb) i frame
# 查看函数参数
(gdb) info args
(gdb) i args
# 查看局部变量
(gdb) info locals
(gdb) i locals
# pwndbg 增强命令
pwndbg> stack 20 # 显示栈内容
pwndbg> context stack # 在上下文中显示栈反汇编
# 反汇编当前函数
(gdb) disassemble
(gdb) disas
# 反汇编指定函数
(gdb) disassemble main
(gdb) disas main
# 反汇编指定地址范围
(gdb) disassemble 0x401000, 0x401200
# pwndbg 增强命令
pwndbg> nearpc $rip # 显示当前位置附近的反汇编
pwndbg> context code # 在上下文中显示代码程序信息
# 查看程序入口点
(gdb) info files
(gdb) i files
# 查看所有函数
(gdb) info functions
(gdb) i functions
# 查看所有线程
(gdb) info threads
(gdb) i threads
# 切换线程
(gdb) thread 2CTF常用技巧
pwndbg 堆分析命令
# 查看堆信息
pwndbg> heap # 显示堆概览
pwndbg> heap -v # 详细堆信息
pwndbg> bins # 显示所有 bins(fastbin, tcache, unsorted, small, large)
pwndbg> fastbins # 显示 fastbin
pwndbg> tcachebins # 显示 tcache bins
pwndbg> unsortedbin # 显示 unsorted bin
pwndbg> smallbins # 显示 small bins
pwndbg> largebins # 显示 large bins
# 查看特定 chunk
pwndbg> vis_heap_chunks # 可视化堆布局
pwndbg> parse_heap # 解析堆结构
pwndbg> find_fake_fast 0x40 # 查找伪造的 fastbin chunk
# chunk 详情
pwndbg> heap <address> # 查看指定 chunk 的详细信息
pwndbg> chunk <address> # 显示 chunk 头部信息
# 分配/释放追踪
pwndbg> malloc_chunk <address>
pwndbg> free_chunk <address>pwndbg ROP 分析
# 搜索 ROP gadget
pwndbg> ropgadget # 搜索 ROP gadgets
pwndbg> rop --grep "pop rdi" # 搜索特定 gadget
pwndbg> rop --grep "ret" # 搜索 ret 指令
# 搜索 JOP gadget
pwndbg> jop # 搜索 JOP gadgetspwndbg 内存搜索
# 搜索内存中的值
pwndbg> search "flag" # 搜索字符串
pwndbg> search 0x401000 # 搜索地址
pwndbg> search --hex 41424344 # 搜索十六进制模式
pwndbg> search --stack "flag" # 只在栈中搜索
# 搜索可执行内存
pwndbg> search -e "flag" # 在可执行段中搜索pwndbg 进程信息
# 查看进程信息
pwndbg> procinfo # 进程信息
pwndbg> checksec # 检查安全机制
pwndbg> vmmap # 内存映射
pwndbg> got # GOT 表
pwndbg> plt # PLT 表
# 查看共享库
pwndbg> libs # 加载的共享库pwndbg 调试技巧
# 上下文自动刷新
pwndbg> context # 显示完整上下文
pwndbg> context reg # 只显示寄存器
pwndbg> context code # 只显示代码
pwndbg> context stack # 只显示栈
pwndbg> context backtrace # 只显示调用栈
# 调试辅助
pwndbg> pid # 显示进程 ID
pwndbg> retval # 显示函数返回值
pwndbg> args # 显示函数参数调试利用脚本
# 使用 pwntools 配合 GDB 调试
from pwn import *
# 启动进程并附加 GDB
p = process('./vuln')
gdb.attach(p, '''
b main
b *0x401234
c
''')
# 或使用 GDB 脚本
p = process('./vuln')
gdb.attach(p, gdbscript='''
b main
c
telescope $rsp 20
''')
# 使用 GDB 调试远程目标
p = remote('challenge.ctf.com', 1337)
gdb.attach(p, '''
b main
c
''')
# 交互模式
p.interactive()分析栈溢出
# 设置断点在返回地址处
(gdb) b *main+100 # 在 ret 指令处断点
# 运行程序,输入超长字符串
(gdb) r
# 查看栈内容,确认溢出偏移
pwndbg> telescope $rsp 20
# 查看返回地址是否被覆盖
pwndbg> x/gx $rsp分析格式化字符串漏洞
# 在 printf 调用处断点
(gdb) b *printf
# 运行程序,输入格式化字符串
(gdb) r
# 查看栈上的参数
pwndbg> telescope $rsp 30
# 格式化字符串读取栈内容
# 输入 %p.%p.%p.%p
# 观察输出找到偏移量分析 Use-After-Free
# 在 malloc 和 free 处断点
(gdb) b *malloc
(gdb) b *free
# 追踪分配和释放
# 在 free 后查看指针是否被置空
pwndbg> telescope $rsp 20
# 查看堆状态
pwndbg> vis_heap_chunks
pwndbg> bins核心转储分析
# 启用核心转储
ulimit -c unlimited
# 程序崩溃后分析
gdb ./program core
# 查看崩溃位置
(gdb) bt
# 查看寄存器状态
(gdb) i r
# 查看内存
(gdb) x/20x $rsp常见问题
pwndbg 命令不可用
原因:pwndbg 未正确加载。
解决:
# 检查 .gdbinit 配置
cat ~/.gdbinit
# 重新安装 pwndbg
cd pwndbg && ./setup.sh
# 手动加载
(gdb) source /path/to/pwndbg/gdbinit.py无法调试 ASLR 程序
解决:
# 关闭 ASLR
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
# 或在 GDB 中关闭
(gdb) set disable-randomization on调试多线程程序困难
解决:
# 查看所有线程
(gdb) info threads
# 切换到特定线程
(gdb) thread <id>
# 在所有线程上设置断点
(gdb) break function thread all远程调试
# 在目标机器启动 gdbserver
gdbserver :1234 ./program
# 在本地连接
(gdb) target remote <target_ip>:1234
# 使用 pwntools 远程调试
from pwn import *
p = remote('target', 1337)
gdb.attach(p)GDB 配置优化
# 在 ~/.gdbinit 中添加
set disassembly-flavor intel # 使用 Intel 汇编语法
set follow-fork-mode child # 跟踪子进程
set detach-on-fork off # 不分离子进程
set pagination off # 关闭分页
set history save on # 保存历史命令
set history filename ~/.gdb_history