GEF 逆向实战:用 pattern 命令基于 De Bruijn 序列定位溢出偏移量

发布时间:2026/9/25 7:32:51

GEF 逆向实战:用 pattern 命令基于 De Bruijn 序列定位溢出偏移量 网络安全开发工具【免费下载链接】gefGEF (GDB Enhanced Features) - a modern experience for GDB with advanced debugging capabilities for exploit devs reverse engineers on Linux项目地址https://gitcode.com/gh_mirrors/gef/gef点击查看免费下载在缓冲区溢出分析中被覆盖的寄存器里残留着哪段数据、溢出发生在第几个字节是必须回答的问题。GEF 的pattern命令通过生成与搜索 De Bruijn德布鲁恩循环序列把猜偏移量变成一次可复制的查表操作先向目标程序灌入一段每个子串都唯一的填充串崩溃后读取被破坏的寄存器值再用搜索子命令反查出精确的字节偏移。本文以 pattern 命令文档 为核心结合 gef.py 中的实现源码与 tests/commands/pattern.py 测试用例完整讲解pattern create/pattern search的参数、底层算法与端到端使用流程。读完本文你将能够独立生成与 pwntools 完全兼容的 De Bruijn 序列理解 GEF 如何根据架构字长与字节序自动选择搜索方向掌握从崩溃寄存器值反推返回地址、栈指针偏移的完整工作流。1. De Bruijn 循环序列为什么它能唯一定位偏移pattern命令生成的字符串由大量互不重复的定长子串组成。以n4为例aaaabaaacaaadaaae...中任意连续 4 个字符都是唯一的——因此当这段字符串覆盖了某个缓冲区并在溢出后残留在寄存器中时只要读出寄存器里的 4 个字符就能在序列中反查出这 4 个字符起始位置的字节偏移即溢出点距离缓冲区首地址的距离。官方文档指出一个关键设计决策GEF 实现的算法与 pwntools 完全一致因此两侧工具生成的序列互为兼容崩溃后即使脱离 GDB 也可以把泄漏值贴进 pwntools 脚本求偏移from pwn import * p cyclic(128, n8)1.1 源码实现与 pwnlib 兼容的递归生成器生成逻辑位于 gef.pydef de_bruijn(alphabet: bytes, n: int) - Generator[int, None, None]: De Bruijn sequence for alphabet and subsequences of length n (for compat. w/ pwnlib). k len(alphabet) a [0] * k * n def db(t: int, p: int) - Generator[int, None, None]: if t n: if n % p 0: for j in range(1, p 1): yield alphabet[a[j]] else: a[t] a[t - p] yield from db(t 1, p) for j in range(a[t - p] 1, k): a[t] j yield from db(t 1, t) return db(1, 1) def generate_cyclic_pattern(length: int, cycle: int 4) - bytearray: Create a length byte bytearray of a de Bruijn cyclic pattern. charset bytearray(babcdefghijklmnopqrstuvwxyz) return bytearray(itertools.islice(de_bruijn(charset, cycle), length))从源码可以看出几个实现细节字母表固定为 26 个小写字母a-z即charset babcdefghijklmnopqrstuvwxyz这也是为什么泄漏值通常是aaaab...这类纯字母序列de_bruijn是一个惰性生成器按 DAWGDe Bruijn 序列标准构造法递归产出字符generate_cyclic_pattern再用itertools.islice截取所需的length字节因此生成任意长度的序列都不会一次性构造完整超串docstring 中明确标注 for compat. w/ pwnlib印证了与 pwntoolscyclic()的算法级兼容。2.pattern create生成并暂存序列2.1 语法与参数pattern create [-h] [-n N] [length]参数含义默认值length生成的序列总字节数配置项pattern.length默认1024-n N唯一子串的定长周期当前架构指针宽度gef.arch.ptrsizex86_64 为 832 位为 4默认长度来自命令自身注册的配置项——PatternCommand.__init__中self[length] (1024, Default length of a cyclic buffer to generate)见 gef.py可通过 GEF 的config机制持久化修改对应文档见 config 命令。2.2 运行示例gef➤ pattern create -n 4 128 [] Generating a pattern of 128 bytes (n4) aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaab [] Saved as $_gef0执行流程对应 PatternCreateCommand.do_invoke解析length缺省读gef.config[pattern.length]与n缺省读gef.arch.ptrsize→ 调用generate_cyclic_pattern(length, n)生成字节串 → 打印明文 → 通过gef_convenience(pattern_str)存入一个GDB 便捷变量。2.3 便捷变量$_gef0溢出 payload 的搬运工gef_conveniencegef.py按$_gef0、$_gef1…… 的递增序号命名字符串值会被定义为形如$_gef0 aaaabaaac...的便捷变量。这个设计让 payload 的传递非常自然gef➤ pattern create 256 [] Generating a pattern of 256 bytes (n8) ... [] Saved as $_gef0 gef➤ set args $_gef0 gef➤ run在命令行直接引用$_gef0即可把整段循环序列作为目标程序的输入参数无需手动拷贝长字符串。3.pattern search从泄漏值反查偏移量3.1 语法与参数pattern search [-h] [-n N] [--max-length MAX_LENGTH] [pattern]search子命令在 De Bruijn 序列中查找给定pattern返回其偏移。参数说明参数含义默认值pattern待搜索的值GDB 符号如寄存器名、字符串或十六进制数无必填-n N子串定长应与pattern长度一致gef.arch.ptrsize--max-length搜索所覆盖的序列最大长度即假设溢出最多发生在前 N 字节内pattern.length默认 1024pattern search还有一个别名pattern offset源码中_aliases_ [pattern offset]见 gef.py语义上更直白地表达求偏移。源码中的参数校验值得注意PatternSearchCommand.do_invokemax_length args.max_length or gef.config[pattern.length] n args.period or gef.arch.ptrsize if n not in (2, 4, 8) or n gef.arch.ptrsize: err(Incorrect value for period)即-n只接受 2/4/8且不能超过当前架构指针宽度——这是为了保证子串长度 ≥ 泄漏值宽度时查表结果不产生歧义。3.2 三种输入形式与官方示例文档给出的三组示例覆盖了全部输入形式gef➤ pattern search 0x6161616161616167 [] Searching 0x6161616161616167 [] Found at offset 48 (little-endian search) likely [] Found at offset 41 (big-endian search) gef➤ pattern search $rbp [] Searching $rbp [] Found at offset 32 (little-endian search) likely [] Found at offset 25 (big-endian search) gef➤ pattern search aaaaaaac [] Searching for aaaaaaac [] Found at offset 16 (little-endian search) likely [] Found at offset 9 (big-endian search)三种形式分别对应十六进制值寄存器里读出的原始机器码GDB 符号直接传$rbp这类寄存器名GEF 会先gdb.parse_and_eval取值明文字符串直接粘贴泄漏的字符。4. 搜索原理小端/大端双向查找与 likely 标记PatternSearchCommand.search 的实现揭示了输出中little-endian / big-endian / likely三个词的由来def search(self, pattern: str, size: int, period: int) - None: # 1. check if its a symbol (like $sp or 0x1337) symbol safe_parse_and_eval(pattern) if symbol: addr int(abs(to_unsigned_long(symbol))) ... mask (1 (8 * period)) - 1 addr mask pattern_le addr.to_bytes(period, little) pattern_be addr.to_bytes(period, big) else: # 2. assume its a plain string pattern_be gef_pybytes(pattern) pattern_le gef_pybytes(pattern[::-1]) cyclic_pattern generate_cyclic_pattern(size, period) off cyclic_pattern.find(pattern_le) if off 0: ok(fFound at offset {off:d} (little-endian search) f{Color.colorify(likely, bold red) if gef.arch.endianness Endianness.LITTLE_ENDIAN else }) return off cyclic_pattern.find(pattern_be) ...可以归纳出四条机制符号优先解析先用safe_parse_and_eval尝试按 GDB 表达式求值。成功则按数值处理并用(1 8*period) - 1掩码只保留低n字节——因为 8 字节的$rbp值里可能混入非 pattern 的高位如 0x7ffd... 的栈地址只有低n字节落在循环序列上明文字符串则构造双字节序把字符串本身当大端字节串、反转后当小端字节串各自在序列中find先小端、后大端命中哪一端就报告哪一端并只报告第一个命中的方向所以输出里同时出现两行如 48 与 41是文档示例在不同场景下的组合展示实际单次运行按小端优先短路返回likely 由架构字节序决定当前架构是小端时小端命中行加粗红色标注likely大端架构则反之gef.py。这个提示告诉用户该结果与目标机器字节序一致可信度更高在跨字节序分析如远程调试时另一端的偏移同样有用。搜索所用的序列是按--max-length默认 1024与-n现场重新生成的——由于生成器确定性与 pwntools 兼容无需与pattern create时保存的$_gefN严格一致但两者参数保持一致才能覆盖真实 payload 长度如果实际 payload 有 2048 字节而搜索时max_length仍是默认 1024超过 1024 的偏移将显示 not found。5. 端到端工作流以 strcpy 溢出为例仓库自带的测试二进制 tests/binaries/pattern.c 就是一个标准的栈溢出靶场void greetz(char* buf) { char name[8] {0,}; strcpy(name, buf); // 8 字节缓冲无边界检查 printf(Hello %s\n, name); }tests/commands/pattern.py 中的自动化用例完整演示了标准工作流可直接照搬为手动调试步骤gef➤ file tests/binaries/pattern gef➤ pattern create 64 -n 4 [] Generating a pattern of 64 bytes (n4) aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaab [] Saved as $_gef0 gef➤ set args aaaabaaacaaadaaaeaaafaaagaaahaaa gef➤ run # 在 strcpy 崩溃点断住后查看 $rbp gef➤ pattern search -n 4 $rbp [] Found at offset 8 (little-endian search) likely测试用例 test_cmd_pattern_search 在不同架构下验证了相同偏移结论x86_64 上-n 4搜索$rbp期望得到 offset 8即 8 字节缓冲name之后恰好是保存的帧指针-n 8搜索同样期望 832 位 i686 因栈布局不同期望 16。用例最后还断言了搜索不存在模式JUNK时输出 not found 的分支tests/commands/pattern.py。得到 offset 后的典型利用动作是偏移 4/8 覆盖saved rbp后ret地址的起始位置从而精确控制返回地址。5.1 与 pwntools 联合使用的注意事项由于算法兼容同一泄漏值可以离线复算from pwn import * offset cyclic_find(baaaag\x00\x00\x00, n4) # 注意字节序与 n 必须与 GEF 端一致需要保持两侧n周期一致GEF 端-n 4对应 pwntools 端n4若一侧用 8 另一侧用 4偏移结果会完全不同。文档示例p cyclic(128, n8)即与pattern create -n 8 128一一对应。6. 小结命令作用关键默认值pattern create [-n N] [length]生成 De Bruijn 序列并存入$_gefNlength1024pattern.lengthn架构指针宽度pattern search [-n N] [--max-length L] [pattern]在序列中反查偏移别名pattern offsetn架构指针宽度max-length1024GEF 的pattern命令把缓冲区溢出分析中偏移计算这一环节封装成了两步操作且其 De Bruijn 生成器与 pwntools 保持算法级兼容见 gef.py 的de_bruijn与generate_cyclic_pattern。配合$_gefN便捷变量传参、寄存器直接作为搜索参数、小/大端双向查找与字节序 likely 提示它构成了从 payload 注入到偏移反查的闭环。理解-n与max-length两个参数如何共同决定搜索空间是避免 not found 假阴性的关键。赞分享网络安全开发工具【免费下载链接】gefGEF (GDB Enhanced Features) - a modern experience for GDB with advanced debugging capabilities for exploit devs reverse engineers on Linux项目地址https://gitcode.com/gh_mirrors/gef/gef点击查看免费下载相关推荐pwntools cyclic 模块详解De Bruijn 序列生成、偏移定位与 Metasploit 模式pwntools cyclic 模块详解De Bruijn 序列生成、偏移定位与 Metasploit 模式 pwnlib.util.cyclic 是 pwn网络安全渗透测试逆向工程ESP-DL实战教程在ESP32上部署YOLO11n目标检测模型ESP DL实战教程在ESP32上部署YOLO11n目标检测模型 ESP DLEspressif deep learning library是乐鑫科技推出人工智能推理引擎嵌入式pwndbg 的 hi 命令堆地址归属快速定位与 malloc_chunk 逆向解析实战pwndbg 的 hi 命令堆地址归属快速定位与 malloc_chunk 逆向解析实战 导读 hi 是 pwndbg 面向 glibc ptmalloc2逆向工程调试器应用安全开发工具上一篇【免费下载】 探索Tikhonov正则化与L曲线MATLAB代码资源推荐【matlab下载】下一篇Matrix-Game-3.0开发者指南自定义动作控制与模型微调教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/25 7:27:51

福建正规的蒸发冷空调定制工厂 定制服务好的源头生产厂家推荐

蒸发冷空调基础科普:是什么、能解决什么问题蒸发冷空调是依托蒸发吸热原理的新型节能降温设备,区别于传统压缩式风冷空调,通过水蒸发吸收热量实现降温,核心优势就是节能,适配工业厂房、开放式/半开放式空间以及各类高温…

2026/9/25 10:03:00

50+营销Skill装进AI Agent:架构拆解与实操接入指南

1. 从"营销Skill"这个词说起:它到底解决了什么问题第一次看到"把50多种营销Skill装进AI Agent"这个说法,我脑子里冒出来的第一个疑问是:Skill和Prompt到底差在哪?很多人做AI应用,第一步就是把一堆…

2026/9/25 10:03:00

OpenResearch深度解析:开源AI研究如何重塑大模型协作与可复现性?

最近后台不少朋友在问,OpenResearch 到底是干什么的,它跟 OpenAI、开源社区、以及当前这些动不动就“颠覆一切”的AI大模型项目之间是什么关系。我自己翻了一堆资料,又把整个项目从定位到技术路线拆了一遍,今天就用一篇长文把这个…

2026/9/25 10:03:00

供应商网站想被大模型读懂,llms.txt 要写什么

更新说明(2026年9月23日):已更正 MapleBridge 的当前产品介绍。本文的供应商网站模板仅为内容组织示例,不是 MapleBridge 供应商数据库或工厂核验结果。最近在整理 MapleBridge 的中文页面时,我发现一个很常见的问题&a…

2026/9/25 10:03:00

Agent Skills 架构实战:从技能设计到调度落地的完整指南

1. 从"会聊天的模型"到"能交付的智能体":Agent Skills 到底在解决什么很多人第一次接触 Agent 这个概念,脑子里浮现的是"一个能对话的机器人"。但真正做过 Agent 项目的人都知道,对话只是最表层的东西。一个能…

2026/9/24 20:24:47

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/23 12:06:55

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/25 0:02:35

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:02:35

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:02:35

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑