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),仅供参考

相关新闻

小米平板4 Plus刷Droidian:从解锁分区到蓝牙修复的完整指南

小米平板4 Plus刷Droidian:从解锁分区到蓝牙修复的完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 7:31:52 阅读更多 →
Chat2DB 实战解析:Springboot + React 多数据库客户端与 AI 辅助 SQL 的工程实践

Chat2DB 实战解析:Springboot + React 多数据库客户端与 AI 辅助 SQL 的工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 7:31:52 阅读更多 →
AI Agent技能库工程化实践:从Prompt乱象到可控工具调用

AI Agent技能库工程化实践:从Prompt乱象到可控工具调用

如果你最近在研究AI Agent,一定遇到过类似的困局:模型什么都能聊,但一落到具体业务就抓瞎。我去年接手了一个智能客服项目,最初的方案是“一个大模型 一套大而全的Prompt 一份工具列表”,结果模型频繁选错工具、传错…

2026/9/25 7:31:52 阅读更多 →

最新新闻

docling实战:文档转结构化数据,PDF解析的AI新方案

docling实战:文档转结构化数据,PDF解析的AI新方案

1. 为什么我最终选择了docling:文档转结构化数据这件事到底难在哪去年我接到一个内部知识库的整理需求,几百份PDF要转成结构化文本入库。我一开始想得很简单:PDF转txt嘛,用现成库循环一遍不就行了。结果第一批文档跑完&#xff0c…

2026/9/25 8:05:21 阅读更多 →
在 Redwood 中使用 GoTrue 构建自托管身份认证(Sign Up / Sign In / Sign Out 全流程)

在 Redwood 中使用 GoTrue 构建自托管身份认证(Sign Up / Sign In / Sign Out 全流程)

后端前端Web框架开发工具 【免费下载链接】redwood RedwoodGraphQL 项目地址: https://gitcode.com/gh_mirrors/re/redwood 点击查看 免费下载 这篇指南将带你脱离 Netlify Identity Widget 的“一键式”束缚,改用 GoTrue-JS 客户端库直接对接 Netlify …

2026/9/25 8:05:21 阅读更多 →
AI工程落地指南:从arxiv-cs.AI论文到可运行RAG与Agent代码

AI工程落地指南:从arxiv-cs.AI论文到可运行RAG与Agent代码

1. 这不是一份“论文清单”,而是一份AI工程实践的实时快照如果你点开过arxiv-cs.AI这个分类页面,大概率会陷入一种熟悉的眩晕感:每天新增几十甚至上百篇论文,标题里塞满了LLM、RAG、Multi-Agent、Agentic、Ontology、Self-Refine……

2026/9/25 8:05:21 阅读更多 →
Atlas 300V 24G部署YOLO:从环境搭建到推理加速的实战指南

Atlas 300V 24G部署YOLO:从环境搭建到推理加速的实战指南

Atlas 300V 24G这个型号最近被问得特别多,尤其是在“能不能跑YOLO”这个问题上。我自己的测试环境里长期插着这张卡,从YOLOv5一路做到YOLOv8、YOLOv10,踩过不少坑,也总结出了一套比较顺手的部署流程。这篇东西就围绕atlas部署yolo…

2026/9/25 8:05:20 阅读更多 →
Atlas 300V 24G推理加速卡深度解析:从规格到YOLO部署实战

Atlas 300V 24G推理加速卡深度解析:从规格到YOLO部署实战

1. 先说结论:Atlas 300V 24G到底算什么卡最近后台和群里总有人问同一个问题:Atlas 300V 24G是运算加速卡吗?这问题看着简单,但真要一两句话说清楚,还真不行。我的回答是:它是一块AI推理加速卡,不…

2026/9/25 8:05:20 阅读更多 →
jQuery对象与DOM对象互转:本质差异与实战避坑指南

jQuery对象与DOM对象互转:本质差异与实战避坑指南

写 jQuery 写了两三年,见过不少新同事第一个卡壳的地方不是复杂插件,反而是最基础的三个概念:$到底是什么、document.getElementById拿到的对象和$(#id)拿到的对象差在哪、为什么有时候能直接.val(),有时候又要[0]一下。这套对象体…

2026/9/25 8:04:20 阅读更多 →

日新闻

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

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

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

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

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

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

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

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

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

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →