资讯动态

pwndbg arenas 命令详解:在 GDB/LLDB 中枚举 glibc ptmalloc2 全部分配区(Arena)

发布时间:2026/9/15 21:57:07 来源:尧图企业网站定制
pwndbg arenas 命令详解在 GDB/LLDB 中枚举 glibc ptmalloc2 全部分配区Arena【免费下载链接】pwndbgExploit Development and Reverse Engineering with GDB LLDB Made Easy项目地址: https://gitcode.com/GitHub_Trending/pw/pwndbg导读本文聚焦 pwndbg 的arenas命令——一条用于**枚举当前进程中 glibc ptmalloc2 全部内存分配区malloc arena**的调试命令。在漏洞利用exploit development与逆向工程中多线程程序的堆布局远比单线程复杂每个 arena 各自维护独立的 bins、fastbins 与 top chunk而arenas命令能帮你一眼看清进程内到底存在哪些 arena、每个 arena 归属哪个堆映射。读完本文你将掌握arenas与配套的arena命令的用法、输出字段含义以及 pwndbg 从符号与启发式两条路径解析 arena 链表的底层原理。arenas命令快速定位进程内全部分配区用法与参数arenas是 pwndbg 内置的 glibc 堆调试命令之一用法极其简洁usage: arenas [-h]它不接收任何位置参数唯一的可选项是标准的帮助参数ShortLongHelp-h--helpshow this help message and exit命令的官方描述只有一句话List this processs arenas.列出当前进程的所有分配区。命令入口定义在 pwndbg/commands/glibc_malloc.py通过pwndbg.commands.Command(parser, categoryCommandCategory.GLIBC_MALLOC)注册到GLIBC_MALLOC命令分类并带有OnlyForSaneHeap装饰器——这意味着当目标进程的堆状态异常无法构建堆对象时命令会安全退出而不是崩溃。适用前提arenas针对 glibc 的 ptmalloc2 分配器实现适用于动态链接了标准 glibc 的目标进程。若目标使用 jemalloc、musl 或 mallocng 等其他分配器arenas不会列出其内部结构这些分配器由 pwndbg 的jemalloc、musl、mallocng等命令族负责。命令调用链在 GDB 或 LLDB 会话中当程序运行到断点处时直接执行pwndbg arenas命令内部的核心逻辑是allocator pwndbg.aglib.heap.glibc.get_allocator() arenas allocator.arenas即通过get_allocator()获取当前进程对应的 glibc 分配器实例详见 pwndbg/aglib/heap/glibc.py再由分配器的arenas属性取得全部 arena 列表。输出格式与字段解读arenas的输出是一张右对齐的表格表头包含 9 个字段arena type arena address heap address map start map end perm size offset file字段含义arena typemain_arena主分配区或non-main arena非主分配区arena addressmalloc_state结构体在内存中的地址heap address该 arena 关联的堆段起始地址map start / map end堆内存映射区间的起止地址perm映射区权限如rw-psize映射区间大小offset映射相对文件偏移file映射来源文件关键实现细节见 pwndbg/commands/glibc_malloc.pyarena type 着色区分主分配区main_arena用成功色绿色标注非主分配区non-main arena用提示色黄色标注便于一眼区分。heap 地址取第一个堆段first_heap arena.heaps[0]展示该 arena 的heaps列表中的第一个堆段起始地址。vmmap 信息联查pwndbg.aglib.vmmap.find(first_heap.start)会去查询该堆地址所属的内存映射返回的映射文本按空格拆分后逐列填入map start / map end / perm / size / offset / file与 pwndbg 的vmmap命令共用同一套映射信息。多堆段折叠展示如果一个非主 arena 拥有多个堆段例如堆通过mmap扩展出第二个 segment则后续堆段以空 arena type 单元格加 Unicode 箭头↳的子行展示箭头指示该堆段归属于上方同一 arena。这一输出设计让你在多线程 堆溢出场景中能快速判断当前进程有几个分配区、哪个是主 arena、各 arena 的堆在哪里、堆映射的权限与大小是否异常例如权限位被篡改、堆越界扩展。与arena命令的分工看单个 vs 看全部arenas展示全局而配套命令arena展示单个分配区的完整内部状态两者共同构成 arena 调试的完整闭环。arena的用法为usage: arena [-h] [addr]不带参数时默认打印当前线程所属的 arena并先输出提示信息Arena for thread tid is located at: 0x7ffff7fa2c80带地址参数时直接打印该地址处malloc_state结构体的完整内容pwndbg arena 0x7ffff7fa2c80其完整字段输出包括mutex、flags、have_fastchunks、fastbinsY、top、bins、binmap、next、next_free、system_mem等 glibcmalloc_state的全部字段字段解析见 pwndbg/aglib/heap/glibc.py 的Arena类。两者的典型配合用法先用arenas看到进程内全部 arena 及其堆位置再用arena address深入某个目标分配区检查其fastbinsY/bins/top/system_mem等内部状态结合 vis-heap-chunks.md、bins.md、top-chunk.md 等命令完成堆布局的进一步可视化。底层原理pwndbg 如何枚举全部 arenaarenas命令只是视图层真正的枚举逻辑位于分配器的arenas属性pwndbg/aglib/heap/glibc.pyproperty pwndbg.lib.cache.cache_until(stop) def arenas(self) - tuple[Arena, ...]: Return a tuple of all current arenas. arenas: list[Arena] [] main_arena self.main_arena if main_arena: arenas.append(main_arena) arena main_arena addr arena.next while addr is not None and addr ! main_arena.address: arena Arena(addr) arenas.append(arena) addr arena.next self._arenas tuple(arenas) return self._arenas枚举算法清晰地复刻了 glibc 的 arena 链表结构先取main_arena主分配区是链表头沿next指针遍历glibc 中每个非主 arena 的malloc_state.next指向下一个 arena直到回到main_arena自身环形链表缓存到 stop 事件pwndbg.lib.cache.cache_until(stop)表示结果缓存在程序停止stop事件上程序继续运行后缓存自动失效避免陈旧堆信息。两条解析路径DebugSymsHeap 与 HeuristicHeappwndbg 的 glibc 分配器分为两种实现main_arena与thread_arena的解析方式也因此不同路径一DebugSymsHeaplibc 带调试符号当 libc 带有调试符号时pwndbg.libc.has_debug_info()为真直接通过符号表定位property def main_arena(self) - Arena | None: self._main_arena_addr pwndbg.aglib.symbol.lookup_symbol_addr( main_arena, prefer_staticTrue ) ... return self._main_arena即从符号main_arena得到其地址prefer_staticTrue优先取静态符号避免被 GOT/PLT 干扰再以该地址构建Arena对象。thread_arena同理通过thread_arena符号读取指针值可能为 NULL表示该线程尚未分配任何内存见 pwndbg/aglib/heap/glibc.py。路径二HeuristicHeap无调试符号启发式当 libc 没有调试符号但能确定版本时pwndbg 使用运行时生成的 C 结构体glibc_structs做启发式解析。main_arena的定位策略是优先用符号main_arena静态链接或已 unstrip 的场景找不到符号时在.data段中按 glibc 默认main_arena的初始化模式做模式匹配——glibc 中main_arena初始为{ .mutex _LIBC_LOCK_INITIALIZER, .next main_arena, .attached_threads 1 }pwndbg 按此特征next自指 attached_threads 1在数据段中搜索匹配的malloc_state结构见 pwndbg/aglib/heap/glibc.py。此外Arena.is_main_arena的判断也很直接self.address _allocator.main_arena.addresspwndbg/aglib/heap/glibc.py这与命令输出中arena type列的着色逻辑一一对应。多堆段的heaps组织Arena.heapspwndbg/aglib/heap/glibc.py负责收集一个 arena 关联的全部堆段主 arena 优先用 sbrk 堆区get_sbrk_heap_region()若top不在 sbrk 区域内则额外补一个堆段非主 arena 沿Heap.prev指针向前回溯把各历史 mmap 堆段全部收进列表列表最后反转保证堆段按地址/时间顺序排列heaps[0]即最早建立的堆段。这解释了arenas输出中第一行取arena.heaps[0]、后续堆段用↳子行展示的行为。实战场景与使用建议场景一多线程程序堆布局侦察对一个多线程二进制程序运行一段时间后执行pwndbg arenas如果看到多个non-main arena行说明进程已为多个线程创建了独立分配区glibc 默认 arena 数量上限约为核数的 8 倍。此时配合thread apply all bt可把哪些线程持有哪些 arena对应起来定位堆风水heap feng shui布局的目标 arena。场景二堆溢出后定位被破坏的 arena在堆利用如 fastbin attack、unsorted bin attack中常需要篡改某个 arena 的top、bins或fastbinsY。先arenas拿到目标 arena 地址再arena addr查看字段最后用 xinfo 或 search 反向验证篡改效果。场景三堆映射权限检查arenas输出的perm列直接来自 vmmap 映射信息。若发现堆段权限异常如堆被 mprotect 成r-x可快速定位是哪一段堆映射被改再结合 vmmap 的详细映射列表交叉验证。注意事项arenas依赖OnlyForSaneHeap当堆结构损坏到无法构建堆对象时命令会静默返回此时应先修复堆状态或用heap命令诊断见 heap.md结果缓存在 stop 事件上若你在一次停止中反复调用malloc例如通过gdb.execute(call malloc(...))执行 inferior call堆可能因brk/mmap扩展而超出缓存的内存映射范围。pwndbg 已通过监听inferior_call事件在 inferior 函数调用完成后清理 stop 缓存来解决此问题对应回归测试见 tests/library/gdb/tests/heap/test_inferior_call_cache.py该测试正是验证thread_arena在多次 inferiormalloc后仍可访问arenas列出的是 arena 的malloc_state结构而非单个 chunkchunk 级视图请使用 malloc-chunk.md 与 vis-heap-chunks.md。小结arenas命令以一张 9 列表格把 glibc ptmalloc2 中散落在各处的 arena 及其堆映射汇总到眼前是分析多线程堆布局的第一站。其背后是对 glibc arena 环形链表、malloc_state结构、vmmap 映射信息的系统解析并同时支持带调试符号的DebugSymsHeap路径与无符号的HeuristicHeap启发式路径。配合单分配区查看命令arena见 arena.md以及 bins.md、fastbins.md、unsortedbin.md 等命令即可在 GDB/LLDB 中完成从进程有几个堆分配区到某个 bins 里挂着哪些 chunk的全链路堆调试。【免费下载链接】pwndbgExploit Development and Reverse Engineering with GDB LLDB Made Easy项目地址: https://gitcode.com/GitHub_Trending/pw/pwndbg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价