十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

pwndbg sigreturn 命令详解:SigreturnFrame 布局解析与 SROP 攻击调试实战

pwndbg sigreturn 命令详解:SigreturnFrame 布局解析与 SROP 攻击调试实战 pwndbg sigreturn 命令详解SigreturnFrame 布局解析与 SROP 攻击调试实战【免费下载链接】pwndbgExploit Development and Reverse Engineering with GDB LLDB Made Easy项目地址: https://gitcode.com/GitHub_Trending/pw/pwndbg导读sigreturn是 pwndbg 提供的一条辅助调试命令用于在指定内存地址默认为当前栈指针 SP处解析并展示SigreturnFrame中保存的寄存器快照。它面向内核sigreturn系统调用与 SROPSigreturn-Oriented Programming攻击场景帮助你在调试器中直接查看伪造或真实存在的信号帧内容。阅读本文后你将掌握sigreturn命令的完整参数用法、它在 x86-64 / i386 / aarch64 / arm 四种架构下的帧布局规则以及如何结合-a、-p参数和输出配色快速定位 ROP 链中的伪造帧并验证其寄存器值。背景sigreturn 系统调用与 SROP 攻击在理解命令本身之前先明确它针对的底层机制。当进程收到信号并进入信号处理流程时内核会把当前寄存器上下文保存到用户栈上的rt_sigframe结构中当信号处理函数返回时程序会执行sigreturn系统调用内核从该结构中恢复全部寄存器状态并继续执行。攻击者由此发展出 SROP 攻击直接伪造栈上的SigreturnFrame再通过syscall; ret之类的 gadget 触发sigreturn系统调用让内核按攻击者写入的寄存器值恢复上下文从而在不依赖 libc gadget 的情况下实现任意系统调用、ROP 链切换乃至 shell 获取。由于帧内容完全位于可控的栈内存中调试时肉眼很难确认每一处偏移对应哪个寄存器——这正是sigreturn命令的价值所在。命令速览用法与全部参数sigreturn是 pwndbg 的 MISC杂项分类命令由 pwndbg/commands/sigreturn.py 定义完整用法如下usage: sigreturn [-h] [-a] [-p] [address]位置参数位置参数说明address要读取 frame 的内存地址可选可选参数短选项长选项说明-h--help显示帮助信息并退出-a--all在通用寄存器之外额外显示 frame 中的所有值-p--print显示 frame 中各值对应的内存地址默认行为从 sigreturn 命令实现 可以看到两条关键默认逻辑不传address时默认从当前栈指针开始解析address pwndbg.aglib.regs.sp if address is None else address。这正契合 SROP 的常见形态——伪造帧通常就位于栈顶附近。命令通过pwndbg.commands.OnlyWhenRunning与pwndbg.aglib.proc.OnlyWithArch([...])装饰器约束运行条件仅在程序运行有可调试进程时可用且只支持x86-64、i386、aarch64、arm四种架构。若当前架构不在支持列表中命令会直接返回而不做任何输出。实战用法示例基础用法直接解析栈顶帧程序暂停时直接执行pwndbg sigreturn等价于sigreturn $sp输出当前栈指针处的 SigreturnFrame。默认只打印核心寄存器通用寄存器、栈指针、帧指针与 PC例如在 x86-64 下输出形如RAX 0x0 RBX 0x0 RCX 0x0 RDX 0x0 RSI 0x0 RDI 0x0 ... RSP 0x7fffffffe000 RBP 0x7fffffffe000 RIP 0x400000 RFLAGS [ ZF SF IF ]指定地址检查 ROP 链中的伪造帧当伪造的 SigreturnFrame 并不位于栈顶例如前面还有若干 padding 或返回地址时可以显式传入地址pwndbg sigreturn 0x7fffffffd8c0该地址是调用sigreturn系统调用那一刻的RSP值对应的帧基址命令会按架构布局从该地址开始逐偏移解析寄存器。组合使用-a与-p完整呈现帧内所有槽位默认模式下帧中不属于核心寄存器集合的槽位会被过滤只留下最常见的寄存器输出更清爽但调试时往往需要确认每个偏移位置到底存放了什么pwndbg sigreturn -a-a会把 frame 中所有槽位的值包括 x86-64 布局中pretcode等特殊条目全部打印出来。配合-p可以同时显示每个值所在的内存地址便于把输出与x/、search等命令的结果相互印证pwndbg sigreturn -a -p 0x7fffffffd8b8: PRETCODE 0x400000 0x7fffffffd8c0: RAX 0x0 0x7fffffffd8c8: RBX 0x0 ...提示-p显示的地址遵循address stack_offset的计算方式即你在命令行传入的帧基址加上该寄存器在布局中的偏移详见 print_value 实现。架构支持与帧布局规则源码级剖析四种架构的布局定义命令支持的帧布局由 SIGRETURN_FRAME_LAYOUTS 定义其寄存器名称与偏移直接取自 pwntools 的pwnlib.rop.srop.registersSIGRETURN_FRAME_LAYOUTS: dict[str, list[tuple[int, str]]] { x86-64: sorted([(-8, pretcode)] list(pwnlib.rop.srop.registers[amd64].items())), i386: sorted(pwnlib.rop.srop.registers[i386].items()), aarch64: sorted(pwnlib.rop.srop.registers[aarch64].items()), arm: sorted(pwnlib.rop.srop.registers[arm].items()), }源码注释明确说明了两点值得注意的事实每个偏移都是syscall 指令执行时相对于栈指针SP的偏移。也就是说帧布局以RSP为基准描述各寄存器在栈上的位置。偏移与名称源自 Linux 内核源码。例如 x86-64 对应内核CONFIG_X86_64下arch/x86/include/asm/sigframe.h中的struct rt_sigframe结构。命令因此天然与内核真实布局保持一致不会因手工维护而偏离实际。其中 x86-64 布局额外包含一项(-8, pretcode)表示帧起始位置比 SP 低 8 字节处存放着预置代码pretcode的地址这也是该架构帧起始偏移为负值的原因。帧起始偏移可为负读取范围的计算命令并非机械地从address开始读内存而是按布局中的最小偏移定位帧真正的起点sigreturn 命令实现frame_start_offset frame_layout[0][0] # 可能为负、0 或正 read_size frame_layout[-1][0] - frame_start_offset ptr_size mem pwndbg.aglib.memory.read(address frame_start_offset, read_size)即从address frame_start_offset一次性读取覆盖整个帧的连续内存块再在块内按mem_offset stack_offset - frame_start_offset索引到每个寄存器的值。这种整块读取、按偏移切片的方式保证了对齐正确且只需一次内存访问。核心寄存器集合与标志寄存器核心寄存器集合 SIGRETURN_CORE_REGISTER 决定了默认输出哪些槽位架构默认打印内容x86-64全部通用寄存器 rbp帧指针rsp栈指针ripPC 标志寄存器rflagsi386全部通用寄存器 ebpespeipeflagsaarch64全部通用寄存器 sppccpsrarm全部通用寄存器 fpipsplrpccpsr这些寄存器定义与 pwndbg/lib/regs.py 中的RegisterSet例如 amd64 寄存器集其中rip为 PC、rsp为栈指针、rbp为帧指针保持一致。在输出渲染上实现做了两类特殊处理核心寄存器的值通过pwndbg.chain.format()格式化能识别指针链并高亮可解引用地址标志寄存器x86 的eflags/ ARM 与 AArch64 的cpsr不走普通数值路径而是调用ctx_color.format_flags()按位展开成可读标志名如[ ZF SF IF ]形式直接可读每个标志位状态。其余非核心槽位仅在-a时输出且使用mem_color.get()着色与普通寄存器输出风格区分。与相关命令的协同sigreturn并非孤立存在其内部通用的从地址按布局打印寄存器帧逻辑print_value被 pwndbg/commands/saved_register_frames.py 直接复用见其第 13 行from pwndbg.commands.sigreturn import print_value用于dump_register_frame命令打印 ARM Cortex-M 异常栈帧。这说明 sigreturn 的实现抽象良好同一套打印/寻址机制可服务不同帧类型。在 SROP 调试流程中sigreturn也常与以下 pwndbg 命令配合使用telescope先对栈内存做逐项展开快速定位伪造帧所在的地址范围search在栈或堆中搜索特定值确认帧中某个寄存器的目标值是否已写入内存xinfo / vmmap确认帧所在页面的权限与映射判断是否为可写可控区域。使用限制与注意事项架构限制命令仅支持x86-64、i386、aarch64、arm。在 MIPS、RISC-V 等其他架构上执行不会报错但会静默返回由 OnlyWithArch 装饰器 的运行时架构判断实现。仅在运行时可用OnlyWhenRunning意味着调试会话必须附着在真实进程上或至少具备可读取的内存纯静态打开二进制时无法使用。地址基准传入的address语义是sigreturn系统调用执行时刻的RSP而非帧中第一个寄存器的地址——在 x86-64 下实际帧起始位置比该地址低 8 字节。确认布局时请结合架构差异。越界与不可读内存命令会一次性读取覆盖整个帧的连续内存块若地址附近存在不可读页面如仅PROT_READ缺失的 guard page内存读取会失败并报错此时应使用vmmap确认帧完全落在可读映射内。输出粒度默认输出只覆盖核心寄存器要验证帧中每一个槽位如pretcode、信号相关数据必须显式加-a。小结sigreturn是 pwndbg 中面向信号帧调试的精简命令一行sigreturn即可把栈顶的 SigreturnFrame 翻译成可读的寄存器快照-a、-p与可选地址参数则提供了完整性与可定位性。其底层直接复用 pwntools 的帧布局数据并锚定 Linux 内核rt_sigframe定义保证了四种主流架构下的解析准确性。对研究 SROP 攻击、分析 shellcode 或调试信号处理逻辑的开发者而言它是连接栈上原始字节与抽象寄存器语义的实用桥梁。【免费下载链接】pwndbgExploit Development and Reverse Engineering with GDB LLDB Made Easy项目地址: https://gitcode.com/GitHub_Trending/pw/pwndbg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表