news 2026/9/15 19:43:15

pwndbg go-dump 命令详解:在 GDB/LLDB 中原生解析与转储 Go 内存值

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
pwndbg go-dump 命令详解:在 GDB/LLDB 中原生解析与转储 Go 内存值

pwndbg go-dump 命令详解:在 GDB/LLDB 中原生解析与转储 Go 内存值

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

go-dump(别名god)是 pwndbg 内存(memory)分类下专为 Go 二进制设计的命令,它能在调试会话中按 Go 类型语法直接解析指定地址上的内存,并以接近 Go 语言字面量的形式输出结构体、切片、map、接口等复合值。读完本文,你将掌握go-dump的完整用法、全部可选参数与格式控制配置项,理解其底层"运行期类型解码"(runtime type decoding)机制,并能结合go-type命令对任意 Go 类型地址进行自省与转储。

命令概览:用法、别名与参数

go-dump的完整帮助信息位于 docs/commands/memory/go-dump.md,命令实现位于 pwndbg/commands/godbg.py。其用法为:

usage: go-dump [-h] [-x] [-f [DECIMALS]] [-d] [-p] ty address

命令接受两个必选位置参数与若干可选参数,详见下表:

位置参数说明
ty要转储值的 Go 类型,例如map[int]string;也可以是运行期类型对象的地址(如0x408860),pwndbg 会在运行时解析该地址处的反射类型
address要转储的内存地址,由pwndbg.commands.AddressExpr解析,支持表达式(如&x、寄存器等)
短参数长参数说明
-h--help显示帮助信息并退出
-x--hex以十六进制显示非指针整数
-f--decimals配置浮点数显示的小数位数
-d--debug显示调试信息,例如切片/map 元素的地址、切片容量等
-p--pretty启用美化输出(pretty printing)

从命令实现(pwndbg/commands/godbg.py)可以看到,命令处理器会先尝试把ty按整数解析为运行期类型地址并调用pwndbg.aglib.godbg.decode_runtime_type()解码;若解析失败(ValueError),则退化为调用parse_type()按类型字符串语法解析,最终统一构造FormatOpts并调用parsed_ty.dump(address, fmt)完成内存转储。

支持的 Go 类型语法

go-dump的类型语法与 Go 语言本身高度一致,可以转储如下类型(详见 docs/tutorials/go-debugging.md):

  • 整数类型intint8int16int32int64int128以及对应的uint系列;
  • 杂项类型boolruneuintptrstring
  • 浮点类型float32float64
  • 复数类型complex64complex128
  • 接口类型any(表示空接口interface{}),interface(表示所有非空接口);
  • 函数类型funcptr(表示任意函数类型);
  • 指针*ELEM
  • 切片[]ELEM
  • 数组[LEN]ELEM
  • mapmap[KEY]VAL

注意:Go 中的 map 变量本质上是内部 map 结构的指针,因此要转储一个 map 变量时通常需要使用*map[KEY]VAL(即先解引用一次)。

结构体也受支持,但语法与 Go 略有不同:为了免去用户自行计算字段偏移(并支持只提供部分字段信息),结构体以偏移:字段名:类型三元组、用分号分隔后包裹在struct(SIZE){}中。例如struct(24){0:foo:string;16:bar:int64}表示 24 字节的 Go 结构体struct { foo string; bar int64 }

在 pwndbg/aglib/godbg.py 中,parse_type()依次尝试_parse_runtime_ty_parse_struct_ty_parse_map_ty_parse_array_ty_parse_pointer_ty_parse_slice_ty_parse_basic_ty七种语法解析器,全部失败时抛出ValueError。类型名称解析失败时会给出提示,例如源码中提示未知类型可改用type hexdump[n]以指定大小的方式查看(pwndbg/aglib/godbg.py)。

实战示例

以下示例来自 docs/tutorials/go-debugging.md,可直接在 pwndbg 中复现:

pwndbg> go-dump map[string]int 0xc0000b20f0 {"a": 1, "b": 2, "c": 3} pwndbg> go-dump any 0xc0000ace40 ([]struct { a int; b string }) [struct {a: 1, b: "first"}, struct {a: 2, b: "second"}] pwndbg> go-dump struct(24){0:a:int;8:b:string} 0xc000108120 struct {a: 1, b: "first"}

第一个示例直接按map[string]int解析 map 内存;第二个示例用any转储一个空接口值——由于接口内部携带运行期类型信息,pwndbg 能自动还原出底层类型(一个[]struct{...}切片)并递归转储;第三个示例展示了结构体的struct(SIZE){...}语法。测试用例 tests/library/dbg/tests/test_go.py 验证了go-dump any &x输出(map[uint8]uint64) &{1: 2, 3: 4, 5: 6}(map[string]int) &{"a": 1, "b": 2, "c": 3}以及go-dump -f 1 any &x输出复数数组([3]complex64) [(1.1 + 2.2i), (-2.5 - 5.0i), (4.2 - 2.1i)]等行为。

可选参数与输出格式控制

  • -x / --hex:将非指针整数以十六进制显示。对应FormatOpts.fmt_int()(pwndbg/aglib/godbg.py),开启后str(val)变为hex(val)
  • -f / --decimals N:浮点数(含复数实部/虚部)保留N位小数,对应FormatOpts.fmt_float()中的format(val, f".{N}f")
  • -d / --debug:在转储结果中为每个元素附加内存地址信息——切片元素、map 的 key/val、字符串的数据指针与长度、指针的解引用地址、接口的类型与数据地址等都会以单独颜色标注。该颜色的主题参数为go-dump-debug(默认蓝色,定义见 pwndbg/aglib/godbg.py)。
  • -p / --pretty:启用美化输出。当某一行超过软宽度上限时会换行并按缩进量排版,相关配置项为go-dump-line-width(默认 80,软行宽)与go-dump-indent-amount(默认 4,缩进量),二者定义于 pwndbg/aglib/godbg.py,可在 pwndbg 中通过set命令调整。

运行期类型解析(Runtime Type Parsing)原理

Go 编译器会为程序使用到的每一个类型发射类型对象(type object),这正是go-dump能自动转储接口值、甚至无需用户提供类型名即可转储任意类型的基础。定位类型的一种常用方法是找到传入堆分配函数(如runtime.newobjectruntime.makeslice)的类型指针。

找到类型指针后,可以用配套命令go-type(别名goty,见 docs/commands/memory/go-type.md)检查该类型:

pwndbg> go-type 0x49fbc0 Name: struct { a int; b string } Kind: STRUCT Size: 24 (0x18) Align: 8 Parse: struct(24){0:a:int;8:b:string} Field a: Offset: 0 (0x0) Type name: int Type addr: 0x498ce0 Field b: Offset: 8 (0x8) Type name: string Type addr: 0x498aa0

go-type输出名称、种类(Kind)、大小、对齐方式、可直接交给go-dump使用的 Parse 字符串,以及每个字段的偏移与类型信息(实现见 pwndbg/commands/godbg.py)。go-dump同样可以直接接受类型地址作为ty参数:

pwndbg> go-dump 0x49fbc0 0xc000108120 struct {a: 1, b: "first"}

从源码结构看,类型解码的核心是decode_runtime_type()(pwndbg/aglib/godbg.py),它按 Go 官方src/internal/abi/type.goType结构体的内存布局读取Size_PtrBytesHashTFlagAlign_FieldAlign_Kind_EqualGCDataStrPtrToThis等字段,其中Kind_低 5 位映射到GoTypeKind枚举(pwndbg/aglib/godbg.py),涵盖BOOLINTFLOAT32ARRAYCHANFUNCINTERFACEMAPPOINTERSLICESTRINGSTRUCT等全部种类。解码过程使用cache配合BackrefType占位符处理递归类型(如type a []a),最后统一替换回真实类型。

几个值得注意的底层细节:

  • 类型名称读取:Go 1.17 之前类型名是 1 字节位标志后跟 2 字节大端长度前缀的字符串,1.17 之后改为 varint 长度前缀编码,read_type_name()会根据检测到的 Go 版本选择解码路径(pwndbg/aglib/godbg.py)。
  • Go 版本探测:优先读取runtime.buildVersion符号,否则回退到.go.buildinfo段解析(pwndbg/aglib/godbg.py)。版本不仅影响类型名格式,还影响结构体字段偏移的移位(Go 1.19 前后)与 map 的布局。
  • 类型区段定位:类型名以相对moduledata的偏移存储,get_type_start()优先遍历runtime.firstmoduledata符号链表获取types/etypes区间,找不到调试符号时退化为用type:*符号或.rodata段启发式猜测(pwndbg/aglib/godbg.py)。
  • map 的两种布局:Go 1.24 之前 map 采用hmap/bucket 结构(dump_noswiss),Go 1.24 起采用新的 Swiss Table 布局(dump_swiss),pwndbg 根据探测到的 Go 版本自动切换解析路径(pwndbg/aglib/godbg.py)。
  • 架构相关字长与对齐word_size()max_align()依据当前架构返回 Go 的字长与最大对齐值(如 x86-64/aarch64/rv64 为 8 字节,i386/arm 为 4 字节,见 pwndbg/aglib/godbg.py),所有布局计算均以此为基础。

类型系统的源码对应关系

go-dump的类型模型是一个抽象基类Type(定义dump()size()align()get_typename()四个抽象方法,见 pwndbg/aglib/godbg.py)下的具体子类:

  • BasicType:基本类型。复数按实部+虚部两个浮点布局,字符串按"指针+长度"布局,空接口记为any、带方法接口记为interface、函数指针记为funcptr(pwndbg/aglib/godbg.py);
  • SliceType:切片,按"指针、长度、容量"三个字布局,-d时可输出容量信息(pwndbg/aglib/godbg.py);
  • PointerType:指针,空指针输出nil,否则解引用并递归转储(pwndbg/aglib/godbg.py);
  • ArrayType:定长数组,按连续内存布局逐个转储元素(pwndbg/aglib/godbg.py);
  • MapType:map,内部按前述两种布局之一遍历所有桶/组并按键排序输出(pwndbg/aglib/godbg.py);
  • StructType:结构体,按字段偏移定位各字段内存(pwndbg/aglib/godbg.py);
  • RuntimeType:以runtime(SIZE)ADDRESS表示"运行期类型地址 + 值大小"的类型,用于序列化循环类型(pwndbg/aglib/godbg.py)。

每种类型都实现了additional_metadata(),供go-type命令输出字段偏移、元素/键值类型地址等元数据。

使用提示与适用前提

  • go-dump只有在程序运行中才可用(命令注册了OnlyWhenRunning装饰器,见 pwndbg/commands/godbg.py)。
  • 类型字符串解析不依赖调试符号;但运行期类型解码(ty传地址)在部分路径上依赖符号(如runtime.firstmoduledata),缺失时 pwndbg 会打印警告并退化为启发式定位,见 pwndbg/aglib/godbg.py。
  • map 转储对 Go 1.24+(Swiss Table)与旧版(hmap)分别处理,且 map 实际为指针语义,注意使用*map[KEY]VAL解引用。
  • 从源码结构看,channel(CHAN)类型当前尚不支持转储(pwndbg/aglib/godbg.py 注释标明 "currently channels and functions are unsupported",其中函数可通过funcptr处理)。
  • 若遇到非法或无法解析的类型,parse_type会抛出ValueError,命令会给出类型解析失败的错误信息。

结合配套的 docs/tutorials/go-debugging.md 教程,你可以在 pwndbg 调试 Go 程序时,用go-type自省任意类型对象、用go-dump直接以 Go 字面量形式读取内存中的复合值,显著提升 Go 逆向与漏洞调试效率。

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 19:43:07

青岛依玛壁挂炉故障维修电话|频繁启停上门排查|欧米到家报修热线

文章简介青岛壁挂炉冬季频繁出现不点火、热水忽冷忽热、地暖制热不足、运行反复掉压、管路漏水等常见故障,受本地气候、水质及采暖系统使用习惯影响,故障成因更具地域性,需结合设备型号、采暖管路系统、运行工况全方位检测排查。欧米到家专注…

作者头像 李华
网站建设 2026/9/15 19:41:29

湖南关键词优化排名推广实战:新手入门避坑指南

湖南关键词优化排名推广实战:新手入门避坑指南 网站做好了没人访问,这大概是所有独立站长最绝望的时刻。你花了几万块甚至几十万,找团队开发、买服务器、搞备案,结果上线一个月,百度指数查询,每天UV(独立访客)个位数,连自家亲戚点进来都不到三个。很多湖南的老板和新手在咨询湖南关键词优化排名推广时,第一反应…

作者头像 李华
网站建设 2026/9/15 19:37:34

AI如何通过智能写作工具提升学术论文效率

1. 项目概述:AI如何重塑学术写作体验在凌晨三点的大学图书馆里,面对堆积如山的文献资料和闪烁的光标,每个经历过毕业论文写作的人都能理解那种"学术写作困境"。传统写作工具往往只能提供基础的格式检查,而"书匠策A…

作者头像 李华