pwndbg 中使用 r2pipe 调用 radare2:状态化反汇编与逆向分析实战
2026/9/15 19:50:58 网站建设 项目流程

pwndbg 中使用 r2pipe 调用 radare2:状态化反汇编与逆向分析实战

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

导读

r2pipe是 pwndbg 提供的 radare2 深度集成命令:它会在调试会话中启动一个有状态(stateful)的 r2pipe 句柄,让你直接在 pwndbg 提示符下执行任意 radare2 命令,例如r2pipe pdf @ sym.main即可立刻得到当前二进制中main函数的反汇编与控制流图。读完本文,你将掌握 r2pipe 命令的完整用法、底层实现原理(PIE 自动重定位、QEMU 内核支持、r2ghidra 校验),以及它与交互式r2命令、rizin 系rzpipe命令的差异与选型。

r2pipe 命令概览:用法与参数

r2pipe命令由 pwndbg 自动生成文档,完整用法如下(见 r2pipe.md):

usage: r2pipe [-h] arguments [arguments ...]

命令描述为:Execute stateful radare2 commands through r2pipe(通过 r2pipe 执行有状态的 radare2 命令)。

位置参数

Positional ArgumentHelp
arguments要传递给 r2pipe 的参数(Arguments to pass to r2pipe)

注意arguments使用nargs="+"(源码见 pwndbg/commands/radare2.py#L70),即至少需要传入一个参数,空调用会报错。

可选参数

ShortLongHelp
-h--help显示帮助信息并退出

命令注册上下文

该命令在源码中以如下方式注册(pwndbg/commands/radare2.py#L67-L100):

parser = argparse.ArgumentParser( description="Execute stateful radare2 commands through r2pipe.", ) parser.add_argument("arguments", nargs="+", type=str, help="Arguments to pass to r2pipe") @pwndbg.commands.Command( parser, category=CommandCategory.INTEGRATIONS, examples="""...""", ) @pwndbg.commands.OnlyWithFile def r2pipe(arguments: list[str]) -> None: print(pwndbg.aglib.radare2.r2cmd(arguments))

两个关键细节:

  • 命令归类为CommandCategory.INTEGRATIONS(集成类命令),与r2decompai等并列;
  • 带有@pwndbg.commands.OnlyWithFile装饰器,即只有在存在被调试目标文件(objfile)时才能执行——r2pipe 需要基于当前进程的可执行文件启动 radare2 实例。

前置依赖与安装

r2pipe并非开箱即用,底层实现(pwndbg/aglib/radare2.py)会在首次调用时检查三类依赖:

  1. radare2 本体:用于驱动 r2 的 r2pipe 需要 radare2 已安装并可用;
  2. r2pipe Python 库:代码中通过import r2pipe检测,若缺失返回错误Could not import r2pipe python library. Is it installed?(对应ErrorCode.NO_IMPORT);
  3. r2ghidra 插件:句柄打开后,pwndbg 会执行LD命令(LD -> list supported decompilers)检查输出中是否包含pdg,若不存在则返回radare2 plugin r2ghidra must be installed and available from r2.(见 pwndbg/aglib/radare2.py#L63-L68)。

也就是说,一个完整可用的环境大致为:安装 radare2 →pip install r2pipe→ 安装并启用 r2ghidra 插件。若三者任一缺失,命令会给出明确的失败状态而非静默出错。

工作原理:从 pwndbg 命令到 r2pipe 句柄

r2pipe命令的执行链路很短但信息量很大:

pwndbg> r2pipe pdf @ sym.main └─ pwndbg.commands.radare2.r2pipe(arguments) # 命令层 └─ pwndbg.aglib.radare2.r2cmd(arguments) # 拼接并执行 └─ pwndbg.aglib.radare2.r2pipe() # 获取/创建句柄(带缓存) └─ r2pipe_mod.open(filename, flags) # 启动 radare2 管道 └─ r2.cmd("pdf @ sym.main") # 执行 radare2 命令

句柄缓存:保证"状态化"

r2pipe()函数带有缓存装饰器(pwndbg/aglib/radare2.py#L22):

@pwndbg.lib.cache.cache_until("start", "objfile") def r2pipe() -> r2pipe_mod.open | Status:

cache_until("start", "objfile")意味着:句柄在进程重新启动(start)或目标文件(objfile)发生变化时才会被重建,其余时间所有r2pipe调用都复用同一个 radare2 实例。这正是"有状态"的体现——你在某次调用中执行了s(seek)或修改了配置,后续调用仍然生效,就像一直坐在同一个 radare2 交互式会话里。

自动附加与 PIE 重定位

句柄创建时(pwndbg/aglib/radare2.py#L56-L62),非 QEMU 场景下:

flags = ["-e", "io.cache=true"] exe = pwndbg.aglib.elf.exe() if pwndbg.aglib.elf.get_elf_info(filename).is_pie and exe is not None: flags.extend(["-B", hex(exe.address)]) r2 = r2pipe_mod.open(filename, flags=flags)
  • -e io.cache=true:开启 radare2 的 I/O 缓存,避免调试时对文件的实际写入;
  • -B <base>:当检测到被调试目标为 PIE 时,pwndbg 会根据当前 ELF 的加载基址自动设置 radare2 的基地址。这样你在 r2pipe 里看到的地址就是与 gdb 中一致的真实运行地址,可以直接和 pwndbg 的telescopevmmap等命令输出的地址对照,无需手动换算;
  • 打开句柄后,pwndbg 会自动对二进制进行分析(docstring 中注明 "the binary is automatically analyzed")。

QEMU 内核调试的特殊处理

如果当前处于 QEMU 内核模式(pwndbg.aglib.qemu.is_qemu_kernel()),则使用另一组 flags(pwndbg/aglib/radare2.py#L45-L55):

flags = ["-e", "bin.cache=true", "-e", "bin.relocs.apply=true"] if (kbase := pwndbg.aglib.kernel.kbase()) and filename == pwndbg.aglib.proc.exe(): urand = pwndbg.aglib.elf.get_vmlinux_unrand_base(filename) if urand is not None: flags.extend(["-e", "bin.baddr=" + hex(kbase - urand)])

这里启用了bin.relocs.apply=true并利用内核基址kbase与 vmlinux 未随机化基址urand的差值计算bin.baddr,使 radare2 能够正确分析 KASLR 下的内核映像。

r2cmd:把参数拼成一条命令

最终执行由r2cmd完成(pwndbg/aglib/radare2.py#L72-L79):

def r2cmd(arguments: list[str]) -> str: r2 = r2pipe() if isinstance(r2, Status): return message.error(r2.message) return str(r2.cmd(" ".join(arguments)))

所有位置参数被空格拼接后整体传给r2.cmd(),因此你可以使用 radare2 的完整命令语言,包括@地址操作符、;命令分隔、临时 seek 等语法。返回结果以字符串形式直接打印在 pwndbg 中。

实战示例:反汇编当前目标函数

原文档给出的官方示例即针对main函数的反汇编(pdf即 radare2 的 "print disassembly of function"):

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 │ 0x0001b926 4156 push r14 │ 0x0001b928 4155 push r13 │ 0x0001b92a 4154 push r12 [...] │ 0x0001b966 85c0 test eax, eax │ ┌─< 0x0001b968 7545 jne 0x1b9af │ │ 0x0001b96a e8311b0100 call sym.xtrace_init │ │ 0x0001b96f e80cff0000 call sym.check_dev_tty │ │ ; CODE XREF from main @ 0x1b988(x) │ ┌──> 0x0001b974 833dd1680f.. cmp dword [obj.debugging_login_shell], 0 ; [0x11224c:4]=0 │ ┌───< 0x0001b97b 743d je 0x1b9ba │ │╎│ 0x0001b97d bf03000000 mov edi, 3 [...]

由于参数原样透传给 radare2,你可以在此之上组合出大量实用调用,例如:

# 列出所有函数(radare2 自动分析已完成) pwndbg> r2pipe afl # 查看字符串 pwndbg> r2pipe iz # 反编译当前 PC 附近的伪代码(依赖 r2ghidra,pdg 由 LD 校验) pwndbg> r2pipe pdg @ $PC # 以图形方式打印函数(输出适合在终端查看的控制流结构) pwndbg> r2pipe afi @ sym.main # 组合多个命令,以 ; 分隔 pwndbg> r2pipe s sym.main ; pdf

因为句柄是状态化的,这些操作会互相影响——比如先s sym.main再执行pdf,会打印同一地址处的函数。这与 pwndbg 自身的decomp命令(decomp.md)互补:decomp走的是统一的"当前集成"抽象层,而r2pipe让你直接使用 radare2 原生命令语言。

状态化 vs 一次性调用:与r2命令的区别

同一个源文件里还定义了r2命令(pwndbg/commands/radare2.py#L14-L64,别名radare2),用法为:

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

两者的核心区别:

维度r2piper2
交互方式通过 r2pipe 管道,在 pwndbg 内直接返回命令输出通过subprocess.call启动独立的交互式 radare2 终端
状态保持是(句柄缓存,跨调用保持 seek/配置)否(每次启动新的 radare2 进程)
额外选项无(参数全部透传)--no-seek(不跳转到当前 PC)、--no-rebase(不为 PIE 设置基址)
适用场景在 gdb 会话中快速查询反汇编/伪代码进入完整 radare2 环境进行深度逆向

r2命令在启动时会自动 seek 到当前 PC(除非--no-seek),同样会为 PIE 传入-B <base>(除非--no-rebase),并使用-e io.cache=true。文档示例(r2.md):

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) [...] [0x0001d3d0]> help Welcome to radare2! [...]

注意示例中--之后的-S -AA是传给 radare2 自身的参数(-AA表示深度自动分析),这正是r2r2pipe在参数语义上的不同。

兄弟命令:rizin / rzpipe

pwndbg 对 rizin 提供了完全对称的集成(源码见 pwndbg/commands/rizin.py 与 pwndbg/aglib/rizin.py):

  • rz:交互式启动 rizin(别名rizin),选项与r2相同(--no-seek--no-rebase);
  • rzpipe:通过 rzpipe 执行有状态的 rizin 命令,用法与r2pipe完全一致(rzpipe.md)。

二者仅在底层实现上有细微差异:rizin 版本通过Lc(列出 core 插件)命令校验ghidra插件是否可用(对应 r2ghidra 的rzghidra)。rzpipe 示例(rzpipe.md):

pwndbg> rzpipe pdf @ sym.main ; DATA XREF from entry0 @ 0x1d3e8 ┌ int main(int argc, char **argv, char **envp); │ ; arg int argc @ rdi │ ; arg char **argv @ rsi │ ; arg char **envp @ rdx [...] │ ; var int64_t canary @ stack - 0x40 │ 0x0001b920 endbr64 │ 0x0001b924 push r15 [...]

如果你的环境中同时安装了 radare2 与 rizin,可以根据个人偏好选择r2piperzpipe;命令语言基本兼容(r2 与 rz 同源)。

常见问题与排查

结合实现代码,r2pipe可能出现的失败场景与对应信息如下:

现象原因处理建议
Could not find objfile to create a r2pipe for.当前没有已加载的被调试文件(pwndbg/aglib/radare2.py#L34-L36)file <binary>start加载目标
Could not import r2pipe python library. Is it installed?缺少 r2pipe Python 库(pwndbg/aglib/radare2.py#L38-L43)pip install r2pipe
radare2 plugin r2ghidra must be installed and available from r2.radare2 中未安装/未启用 r2ghidra,LD输出不含pdg(pwndbg/aglib/radare2.py#L63-L68)安装 r2ghidra 插件(如通过r2pm -ci r2ghidra
OnlyWithFile限制命令被@pwndbg.commands.OnlyWithFile装饰(pwndbg/commands/radare2.py#L98)先加载可执行文件再调用

另外需要注意:句柄一旦创建即被缓存(cache_until("start", "objfile")),因此如果调试过程中切换到另一个二进制,pwndbg 会在objfile变化后自动重建句柄,无需手动干预;如果你觉得缓存中的 radare2 状态已经混乱,也可以使用reinit-pwndbg或重启调试会话来刷新。

小结

r2pipe命令将 radare2 强大的反汇编、分析与伪代码能力无缝注入 gdb/LLDB 调试流程:

  • 有状态管道:一次启动、复用句柄,地址经过 PIE 自动重定位,与 gdb 视角完全对齐;
  • 完整命令语言:任意 radare2 命令原样透传,@;、变量等语法全部可用;
  • 可靠的前置校验:对 r2pipe 库与 r2ghidra 插件的缺失给出明确错误,方便排查;
  • 生态对称:与r2(交互式)、rz/rzpipe(rizin 系)互为补充,可覆盖从快速查询到深度逆向的完整工作流。

建议在调试环境准备好 radare2 + r2pipe + r2ghidra 后,用r2pipe pdf @ $PCr2pipe afl作为第一个命令体验这一集成能力。相关的集成类命令文档可进一步参考 integrations 命令索引、r2 命令文档 与 decompiler-integration.md。

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

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

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

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

立即咨询