一种Wasm逆向静态分析方法
字数 1720 2025-08-05 08:17:20
WebAssembly(Wasm)逆向静态分析方法详解
一、WebAssembly基础
WebAssembly(缩写为Wasm)是基于堆栈的虚拟机的二进制指令格式,设计为可编程C/C++/Rust等高级语言的可移植目标,可在Web上部署客户端和服务器应用程序。
Wasm汇编特点
- 基于栈的虚拟机架构,不同于x86的寄存器+栈架构
- 局部变量保存在
local中,全局变量保存在global中 - 变量操作使用
get_local入栈,操作后使用set_local设置局部变量
Wasm汇编示例
C++代码:
int testFunction(int* input, int length) {
int sum = 0;
for (int i = 0; i < length; ++i) {
sum += input[i];
}
return sum;
}
对应的WAT(WebAssembly文本格式)代码:
(module
(func $_Z12testFunctionPii
(param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(set_local $2 (i32.const 0))
(block $label$0
(br_if $label$0 (i32.lt_s (get_local $1) (i32.const 1)))
(loop $label$1
(set_local $2 (i32.add (i32.load (get_local $0)) (get_local $2)))
(set_local $0 (i32.add (get_local $0) (i32.const 4)))
(br_if $label$1 (tee_local $1 (i32.add (get_local $1) (i32.const -1))))
)
)
(get_local $2)
)
)
二、Wasm逆向分析工具链
1. 反汇编工具
- IDA Pro:自带WebAssembly处理器模块,可直接反汇编wasm文件
- wasm2wat:将wasm二进制转换为文本格式的.wat文件
$ ./wasm2wat wasm.wasm -o wasm.wat
2. 反编译工具
wasm2c:将wasm转换为C代码(来自WABT项目)
$ ./wasm2c wasm.wasm -o wasm.c
生成的C代码特点:
- 行数庞大(可能上万行)
- 代码结构与wat相似,主要是变量名替换和省略栈操作
- 可读性较差,需要进一步优化
3. 代码优化方法
使用GCC编译后再用IDA反编译:
- 准备文件:wasm.c, wasm.h, wasm-rt.h, wasm-rt-impl.c, wasm-rt-impl.h
- 编译但不链接:
$ gcc -c wasm.c -o wasm.o - 将wasm.o放入IDA分析,可得到更友好的伪代码
三、Wasm逆向分析技巧
1. 字符串分析
- Wasm字符串通常存放在二进制文件末尾
- 可直接在wasm.c中查看字符串定义
- 注意:字符串引用不是直接地址引用,查找引用较困难
2. 常量分析
- 关注文件开头的常量,可能包含关键信息
- 常见模式:连续相同字节可能暗示加密方式(如异或)
- 常量偏移通常从0x400开始
3. 关键函数识别
- 认证函数:通常命名为
_authenticate或类似名称 - 校验函数:包含比较逻辑的函数
- 加密/解密函数:包含位操作或数学运算的函数
4. 内存操作分析
- 注意
i32_load/i64_load等内存操作指令 - 跟踪内存地址,特别是固定偏移(如0x400)
- 内存操作可能揭示数据流和算法逻辑
四、实战案例分析
案例1:DEF CON CTF 2019 Quals
-
字符串分析:
- 发现flag格式提示"OOO{}"
- 开头连续三个相同字节可能暗示异或或偏移
-
关键函数f24:
v11 = i32_load8_s(Z_envZ_memory, a1 + v13); return (unsigned __int8)(v11 - 66); // 减66得到flag -
主逻辑函数_authenticate:
- 从0x4D0和0x4D4加载数据
- 成功(0x4D5)和失败(0x4DD)分支
案例2:Simple Wasm(上交大运维赛)
-
字符串发现:
- Base64表和密文
- 解码得到:
iodj~44h393d5fh4;e:9h6i598f798;gd<4hf€
-
check函数分析:
while (v14 != 38) { v5 = i32_load8_s(Z_envZ_memory, v4 + a1); f797(v21, (unsigned __int8)(v5 + 3)); // 凯撒密码+3 }- 解法:所有字符减3得到flag
案例3:Where_u_are(国赛初赛)
-
字符串定位:
- 确定main函数位置
- 识别scanf(0x1170)和printf(0x1173, 0x1168, 0x117C)
-
加密函数f23:
- 输入字符映射到32字符表
0123456789bcdefghjkmnpqrstuvwxyz - 分离每一位(右移j%5 & 1)
- 输入字符映射到32字符表
-
核心算法f24:
- 二分查找算法
- 两组分别在[-180,180]和[-90,90]区间内二分
- 目标值:175和25
五、总结与建议
-
静态分析流程:
- 使用wasm2wat/wasm2c进行初步转换
- GCC编译优化后IDA分析
- 重点关注字符串、常量和内存操作
-
动态调试补充:
- 使用Chrome/Firefox进行动态调试验证静态分析结果
- 结合浏览器开发者工具观察运行时行为
-
Wasm逆向特点:
- 工具链仍在发展,分析方法有待完善
- 内存操作模式相对固定,容易识别关键逻辑
- 常量区域(如0x400偏移)常包含重要数据
-
进一步学习:
- 熟悉WAT文本格式
- 了解Wasm内存模型和指令集
- 跟踪WABT等工具的最新发展
通过系统化的静态分析方法,结合动态调试验证,可以有效逆向分析WebAssembly程序,理解其内部逻辑和算法实现。