pwndbg r2 命令实战:在 GDB 会话中无缝启动 radare2 协同分析
2026/9/15 9:54:42 网站建设 项目流程

pwndbg r2 命令实战:在 GDB 会话中无缝启动 radare2 协同分析

【免费下载链接】pwndbgExploit Development and Reverse Engineering with GDB & LLDB Made Easy项目地址: https://gitcode.com/GitHub_Trending/pw/pwndbg

本文围绕 pwndbg 的r2(别名radare2)命令展开,讲解如何在 pwndbg 调试会话中一键拉起 radare2、把当前进程的 ELF 文件与基址自动传递给 radare2,从而在 GDB 与 radare2 之间无缝切换进行反汇编、分析(-AA)与协同逆向。读完本文,你将掌握r2命令的全部参数语义(--no-seek--no-rebasearguments)、底层命令构造逻辑,以及配套的r2pipe状态化管道用法,可以直接在真实调试会话中复现。

一、命令总览

r2是 pwndbg 集成 radare2 的入口命令,其功能一句话即可概括:在 pwndbg 会话中启动一个 radare2 实例,并把当前正在调试的可执行文件交给它。该命令定义在 pwndbg/commands/radare2.py,分类属于CommandCategory.INTEGRATIONS(集成类命令),并注册了别名radare2,即r2radare2完全等价。

在 docs/commands/index.md 的命令索引中,它被归入 integrations 分区:

  • r2— Launches radare2(启动 radare2)
  • r2pipe— Execute stateful radare2 commands through r2pipe(通过 r2pipe 执行有状态的 radare2 命令)

1. 完整用法

usage: r2 [-h] [--no-seek] [--no-rebase] [arguments ...]

2. 参数一览

位置参数说明
arguments传给 radare2 的命令行参数
可选参数说明
-h,--help显示帮助信息并退出
--no-seek不把 radare2 的光标 seek 到当前 PC(程序计数器)位置
--no-rebase不为 PIE(位置无关可执行文件)根据当前映射设置基址

3. 官方示例

pwndbg> r2 -- -S -AA WARN: Relocs has not been applied. Please use `-e bin.relocs.apply=true` or `-e bin.cache=true` next time INFO: Analyze all flags starting with sym. and entry0 (aa) [...] INFO: Debugger commands disabled in sandbox mode [0x0001d3d0]> help Welcome to radare2! [...]

注意示例中的关键细节:

  • --是 argparse 的位置参数分隔符,它之后的-S -AA才会被当作arguments原样透传给 radare2(否则 radare2 自己的-S-AA会被 pwndbg 的参数解析器拦截)。
  • 命令执行后 pwndbg 终端直接转入 radare2 交互界面(提示符形如[0x0001d3d0]>),意味着这是阻塞式调用——radare2 退出后才返回 pwndbg 命令行。
  • 示例中的WARN: Relocs has not been applied. Please use -e bin.relocs.apply=true or -e bin.cache=true是 radare2 加载 ELF 重定位时的提示,与 pwndbg 传入的io.cache=true相关(详见下文实现剖析)。

二、源码实现剖析:pwndbg 到底把什么传给了 radare2

r2命令的实现位于 pwndbg/commands/radare2.py,核心逻辑分为“取目标文件”“构造参数”“执行子进程”三步。

1. 目标文件来源

filename = pwndbg.aglib.file.get_proc_exe_file()

命令装饰了@pwndbg.commands.OnlyWithFile,即只有在当前会话已经确定目标文件(如加载了可执行文件)时才可用,随后通过get_proc_exe_file()拿到正在被调试的进程对应的可执行文件路径。

2. 构造 radare2 命令行

cmd = ["radare2"] flags = ["-e", "io.cache=true"] exe = pwndbg.aglib.elf.exe() if pwndbg.aglib.proc.alive() and exe is not None: addr = pwndbg.aglib.regs.pc if pwndbg.aglib.elf.get_elf_info(filename).is_pie: if no_rebase: addr -= exe.address else: flags.extend(["-B", hex(exe.address)]) if not no_seek: cmd.extend(["-s", hex(addr)]) cmd.extend(flags) cmd += arguments cmd.extend([filename])

从源码可以还原出 pwndbg 最终拼出的完整命令形态:

radare2 [-s <当前PC地址>] -e io.cache=true [-B <PIE基址>] [arguments...] <目标文件>

关键决策点逐一说明:

  • -e io.cache=true:pwndbg 始终会为 radare2 启用 IO 缓存,这是示例中那条 “Relocs has not been applied” WARN 出现的直接背景。
  • PIE 处理:当被调试文件是 PIE 且进程存活时,默认做法是给 radare2 传入-B hex(exe.address),即用当前内存映射中的实际加载基址重设 radare2 的 bin 基址,让 radare2 中的地址与 pwndbg/GDB 中的运行时地址对齐;若指定--no-rebase,则改为把 PC 减去exe.address(即还原成文件偏移),radare2 将按静态文件布局工作。
  • seek 处理:默认(不传--no-seek)会用-s hex(addr)让 radare2 一启动就把光标定位到当前 PC 处,与 GDB 正在执行的位置保持同步;--no-seek则关闭该行为,radare2 停在默认的入口点。
  • arguments透传:用户输入的所有额外参数原样追加到命令行末尾、目标文件之前,这也是示例中-S -AA(跳过调试器 attach、执行完整分析)能够生效的原因。

3. 异常兜底

try: subprocess.call(cmd) except Exception: print("Could not run radare2. Please ensure it's installed and in $PATH.")

命令以subprocess.call阻塞执行;一旦 radare2 不在$PATH或启动失败,pwndbg 会打印提示,要求确保 radare2 已安装且可执行。

三、两个开关参数的实际使用场景

--no-seek:摆脱“光标跟随”

默认情况下 r2 会把 radare2 光标 seek 到当前 PC。当你并不关心当前执行位置,而是想从入口点或自定义地址开始分析时,可以关闭跟随:

pwndbg> r2 --no-seek -- -AA

此时 radare2 将从文件的入口点(entry0)开始展示。

--no-rebase:回到静态文件视角

当目标是 PIE 程序时,默认的-B重基址会让 radare2 中的地址呈现为运行时地址(如0x55...高位基址)。如果你更习惯以文件偏移/静态地址(如0x1d3d0)进行分析——例如与未运行时提取的二进制对比、或使用基于文件偏移的工具链——可以用--no-rebase

pwndbg> r2 --no-rebase -- -S -AA

两个开关可以组合使用,r2 --no-seek --no-rebase -- <参数>会得到一个完全“静态视角”且不跟随 PC 的 radare2 会话。

四、进阶联动:r2pipe命令保持状态复用

在同一源码文件 pwndbg/commands/radare2.py 中,还定义了同主题的r2pipe命令(独立文档见 docs/commands/integrations/r2pipe.md),用于在 pwndbg 内直接执行有状态的 radare2 命令,而不需要离开 GDB:

usage: r2pipe [-h] arguments [arguments ...]
pwndbg> r2pipe pdf @ sym.main ; ICOD XREF from entry0 @ 0x1d3e8(r) ┌ 6786: int main (uint32_t argc, char **argv, char **envp); │ `- args(rdi, rsi, rdx) vars(21:sp[0x40..0x18c]) │ 0x0001b920 f30f1efa endbr64 │ 0x0001b924 4157 push r15 [...]

两者构成完整的 radare2 协作方案:

  • r2:交互式拉起完整 radare2 终端(适合深度手工分析);
  • r2pipe:把 radare2 的命令字符串直接交给后台管道执行并把结果打印回 pwndbg(适合脚本化、状态化地连续调用,如反复pdf @ sym.mainsafl)。

r2pipe的底层逻辑

r2pipe最终调用pwndbg.aglib.radare2.r2cmd()(见 pwndbg/aglib/radare2.py),其上游r2pipe()工厂函数有若干值得注意的实现事实:

  1. 句柄缓存:r2pipe 句柄被cache_until("start", "objfile")缓存,即同一个目标文件、同一轮调试内多次r2pipe调用复用同一个 radare2 会话,保证“有状态”。
  2. 依赖检查:需要本机同时安装 radare2 与 Python 的 r2pipe 库,缺失时返回带错误码的失败状态(ErrorCode.NO_IMPORT)。
  3. PIE 自动基址:与r2命令一样,对 PIE 文件会自动追加-B hex(exe.address)重基址。
  4. r2ghidra 插件要求:会执行LD检查支持的伪代码命令列表,若输出中不含pdg,则返回失败,提示 “radare2 plugin r2ghidra must be installed and available from r2”——也就是说r2pipe pdc/pdg反编译能力依赖 r2ghidra 插件。
  5. 内核调试适配:从源码结构看,在 QEMU 内核调试(is_qemu_kernel())场景下会改用bin.cache=truebin.relocs.apply=true并依据内核基址设置bin.baddr

五、环境前提与常见问题

  • radare2 必须安装r2命令通过subprocess.call执行radare2,需要该可执行文件位于$PATH;未安装或不在路径中时,pwndbg 会打印Could not run radare2. Please ensure it's installed and in $PATH.
  • 必须有目标文件r2r2pipe都带OnlyWithFile装饰器,在未确定目标文件时不可用。
  • --分隔符:向 radare2 传递以-开头的选项时,务必先用--与 pwndbg 自身的参数解析隔离开。
  • WARN 提示的处理:若在 radare2 内看到 “Relocs has not been applied”,可按提示在 radare2 侧执行-e bin.relocs.apply=true-e bin.cache=true后重新加载。

六、相关资源

  • 命令文档:docs/commands/integrations/r2.md、docs/commands/integrations/r2pipe.md
  • 命令实现:pwndbg/commands/radare2.py
  • r2pipe 底层封装:pwndbg/aglib/radare2.py
  • 命令索引:docs/commands/index.md
  • 同类集成:Rizin 生态对应命令rz/rzpipe(见 docs/commands/integrations/rz.md、docs/commands/integrations/rzpipe.md 与 pwndbg/commands/rizin.py)

【免费下载链接】pwndbgExploit Development and Reverse Engineering with GDB & LLDB Made Easy项目地址: https://gitcode.com/GitHub_Trending/pw/pwndbg

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询