资讯动态

WABT wasm2wat 使用指南:3 分钟把 Wasm 二进制读成文本

发布时间:2026/9/20 22:18:46 来源:尧图企业网站定制
WABT wasm2wat 使用指南3 分钟把 Wasm 二进制读成文本【免费下载链接】wabtThe WebAssembly Binary Toolkit项目地址: https://gitcode.com/GitHub_Trending/wa/wabt你拿到一个编译好的 .wasm 文件想读懂里面的逻辑打开却只有一片字节。WABTWebAssembly Binary Toolkit里的 wasm2wat 就是干这个的把 WebAssembly 二进制模块还原成可读的 .wat 文本。它不做优化、不猜测意图只做一件事——保真地把二进制翻译成规范文本格式。先搞清楚wasm2wat 是干什么的wasm2wat 是 WABT 工具链里的反向翻译器与 wat2wasm 互为逆操作读入 .wasm 二进制输出 .wat 文本。适合这几类人逆向分析拿到无源码 wasm 的开发者工具链开发者需要检查自己的编译器生成了什么指令想学 Wasm 文本格式wat的人——用真实二进制做教材。核心能力完整二进制解析覆盖 SIMD、多线程、memory64 等提案多数默认启用以 README 的支持表为准转换前先做模块验证validate文本不合法的模块会直接报错--fold-exprs把栈式指令折叠成嵌套表达式可读性大幅提升--generate-names给无名函数、类型自动命名目标明确1:1 保真往返指令逐条对应不增不减。它和 Binaryen 这类工具的定位不同不追求优化或高级编译器目标只追求对规范的完整还原。第一次跑起来编译环境与参数速查环境只需要 CMake。clone 后按官方步骤编译记得带子模块git clone --recursive https://gitcode.com/GitHub_Trending/wa/wabt cd wabt mkdir build cd build cmake .. cmake --build .注意不能在仓库根目录直接 cmake因为会生成一个叫 wasm2c 的可执行文件和 wasm2c/ 目录冲突README 明确提醒。最小可运行命令bin/wasm2wat input.wasm不指定输出时结果直接打到 stdout。编译产物路径各系统略有差异make 构建默认在 out/ 下以仓库实际为准。参数速查参数作用位置参数输入 .wasm 文件-o FILE输出 .wat 文件缺省写 stdout-f, --fold-exprs能折叠的表达式写成嵌套 s 表达式--generate-names给无名函数、类型等自动命名--no-debug-names忽略二进制里的调试名称--no-check跳过模块验证-v输出更多诊断信息可叠加使用--enable-xxx/--disable-xxx提案开关如--enable-simd具体以--help为准跑完bin/wasm2wat --help也能看到全部选项。读懂输出的三层结构一次转换的输出从外到内分三层。第一层type 声明。每个函数签名一条带索引注释(module (type (;0;) (func (result f32))) (type (;1;) (func (result i32)))函数后面引用的type 0就指向这里的第一条签名。第二层func 声明头把签名摊开写(func (;1;) (type 1) (result i32)result i32是该函数的返回值类型后面跟参数则写成param。第三层函数体即指令序列。默认输出是扁平的——一条指令一行值靠隐式栈传递这来自 Wasm 的栈机本质。三层合起来就是一整个模块。示例取自仓库测试 test/roundtrip/fold-block.txt。两个开关把输出变得可读熟悉基本读法后值得试两个参数。-ffold-exprs优化前加法是一行三句i32.const 1 i32.const 2 i32.add优化后操作数直接挂在指令下数据流向一眼看清(i32.add (i32.const 1) (i32.const 2))控制流折叠后块边界会显式标出跳转目标写在注释里(block ;; label 1 (f32.const 0x1.8p1 (;3;)) (br 0 (;1;)))没有-f时同样的代码要自己数end配几层块有-f时br 0直接告诉你跳到 1。--generate-names模块没带 name section 时函数只会显示成(func (;0;)这样的匿名索引。加上这个参数wasm2wat 会生成占位名称引用关系立刻可读配合调试名称恢复效果更完整。完整走查从 wat 到 wasm 再读回文本按输入→命令→输出→解读四步走一遍。输入一个最小的 add 函数(module (func (export add) (param i32 i32) (result i32) local.get 0 local.get 1 i32.add))命令正反两个方向bin/wat2wasm add.wat -o add.wasm bin/wasm2wat add.wasm -o out.wat输出out.wat 核心部分(module (type (;0;) (func (param i32 i32) (result i32))) (func (;0;) (type 0) (param i32 i32) (result i32) local.get 0 local.get 1 (i32.add)))解读add.wasm 用十六进制打开基本不可读而 out.wat 把 export、签名、三条指令全部还原local.get 0到i32.add的逻辑与输入完全一致——这就是往返保真的含义。避坑清单四个高频问题现象转换失败提示验证错误。 原因wasm2wat 默认先 validate模块不合法就中止。 处理确认二进制确实有问题或加--no-check只转换不验证。现象输出里全是(func (;0;)匿名索引。 原因模块没带 name sectionwasm2wat 默认不瞎编名字。 处理加--generate-names生成占位名称。现象报出类似 simd 指令不支持的解析错误。 原因相关提案未默认启用或开关名记错。 处理加上对应开关如--enable-simd拿不准就--help查 README 的支持表。现象bad magic之类的头错误。 原因文件根本不是 Wasm 模块魔数不对。 处理这不是参数能解决的先确认拿对了文件。能力边界它不做什么不做优化。指令数量、顺序与二进制一一对应别指望它看懂你的循环或结构体不还原高级语言语义。C 的类、Rust 的枚举出了编译器就只剩指令wasm2wat 不会帮你找回来不产出可编译的 C。要 C 代码用 wasm2c见 wasm2c/README.md那是另一个工具的活儿。扩展方向一句话想在文本之外直接执行模块交给同工具链的 wasm-interp。wasm2wat 的定位就是看得见的保真指令不多不少名字能恢复多少算多少。相关工具wat2wasm反方向转换、wasm-objdump二进制级查看、wasm-interp直接执行、wasm-validate单独验证。文档docs/doc/wasm2wat.1.html更多输出样例见 test/roundtrip/源码src/tools/wasm2wat.cc项目源码https://gitcode.com/GitHub_Trending/wa/wabt【免费下载链接】wabtThe WebAssembly Binary Toolkit项目地址: https://gitcode.com/GitHub_Trending/wa/wabt创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

免费获取报价