一种Wasm逆向静态分析方法
字数 1720 2025-08-05 08:17:20

WebAssembly(Wasm)逆向静态分析方法详解

一、WebAssembly基础

WebAssembly(缩写为Wasm)是基于堆栈的虚拟机的二进制指令格式,设计为可编程C/C++/Rust等高级语言的可移植目标,可在Web上部署客户端和服务器应用程序。

Wasm汇编特点

  1. 基于栈的虚拟机架构,不同于x86的寄存器+栈架构
  2. 局部变量保存在local中,全局变量保存在global
  3. 变量操作使用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反编译:

  1. 准备文件:wasm.c, wasm.h, wasm-rt.h, wasm-rt-impl.c, wasm-rt-impl.h
  2. 编译但不链接:
    $ gcc -c wasm.c -o wasm.o
    
  3. 将wasm.o放入IDA分析,可得到更友好的伪代码

三、Wasm逆向分析技巧

1. 字符串分析

  • Wasm字符串通常存放在二进制文件末尾
  • 可直接在wasm.c中查看字符串定义
  • 注意:字符串引用不是直接地址引用,查找引用较困难

2. 常量分析

  • 关注文件开头的常量,可能包含关键信息
  • 常见模式:连续相同字节可能暗示加密方式(如异或)
  • 常量偏移通常从0x400开始

3. 关键函数识别

  1. 认证函数:通常命名为_authenticate或类似名称
  2. 校验函数:包含比较逻辑的函数
  3. 加密/解密函数:包含位操作或数学运算的函数

4. 内存操作分析

  • 注意i32_load/i64_load等内存操作指令
  • 跟踪内存地址,特别是固定偏移(如0x400)
  • 内存操作可能揭示数据流和算法逻辑

四、实战案例分析

案例1:DEF CON CTF 2019 Quals

  1. 字符串分析

    • 发现flag格式提示"OOO{}"
    • 开头连续三个相同字节可能暗示异或或偏移
  2. 关键函数f24

    v11 = i32_load8_s(Z_envZ_memory, a1 + v13);
    return (unsigned __int8)(v11 - 66);  // 减66得到flag
    
  3. 主逻辑函数_authenticate

    • 从0x4D0和0x4D4加载数据
    • 成功(0x4D5)和失败(0x4DD)分支

案例2:Simple Wasm(上交大运维赛)

  1. 字符串发现

    • Base64表和密文
    • 解码得到:iodj~44h393d5fh4;e:9h6i598f798;gd<4hf€
  2. 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(国赛初赛)

  1. 字符串定位

    • 确定main函数位置
    • 识别scanf(0x1170)和printf(0x1173, 0x1168, 0x117C)
  2. 加密函数f23

    • 输入字符映射到32字符表0123456789bcdefghjkmnpqrstuvwxyz
    • 分离每一位(右移j%5 & 1)
  3. 核心算法f24

    • 二分查找算法
    • 两组分别在[-180,180]和[-90,90]区间内二分
    • 目标值:175和25

五、总结与建议

  1. 静态分析流程

    • 使用wasm2wat/wasm2c进行初步转换
    • GCC编译优化后IDA分析
    • 重点关注字符串、常量和内存操作
  2. 动态调试补充

    • 使用Chrome/Firefox进行动态调试验证静态分析结果
    • 结合浏览器开发者工具观察运行时行为
  3. Wasm逆向特点

    • 工具链仍在发展,分析方法有待完善
    • 内存操作模式相对固定,容易识别关键逻辑
    • 常量区域(如0x400偏移)常包含重要数据
  4. 进一步学习

    • 熟悉WAT文本格式
    • 了解Wasm内存模型和指令集
    • 跟踪WABT等工具的最新发展

通过系统化的静态分析方法,结合动态调试验证,可以有效逆向分析WebAssembly程序,理解其内部逻辑和算法实现。

WebAssembly(Wasm)逆向静态分析方法详解 一、WebAssembly基础 WebAssembly(缩写为Wasm)是基于堆栈的虚拟机的二进制指令格式,设计为可编程C/C++/Rust等高级语言的可移植目标,可在Web上部署客户端和服务器应用程序。 Wasm汇编特点 基于栈的虚拟机架构,不同于x86的寄存器+栈架构 局部变量保存在 local 中,全局变量保存在 global 中 变量操作使用 get_local 入栈,操作后使用 set_local 设置局部变量 Wasm汇编示例 C++代码: 对应的WAT(WebAssembly文本格式)代码: 二、Wasm逆向分析工具链 1. 反汇编工具 IDA Pro :自带WebAssembly处理器模块,可直接反汇编wasm文件 wasm2wat :将wasm二进制转换为文本格式的.wat文件 2. 反编译工具 wasm2c :将wasm转换为C代码(来自WABT项目) 生成的C代码特点: 行数庞大(可能上万行) 代码结构与wat相似,主要是变量名替换和省略栈操作 可读性较差,需要进一步优化 3. 代码优化方法 使用GCC编译后再用IDA反编译: 准备文件:wasm.c, wasm.h, wasm-rt.h, wasm-rt-impl.c, wasm-rt-impl.h 编译但不链接: 将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 : 主逻辑函数_ authenticate : 从0x4D0和0x4D4加载数据 成功(0x4D5)和失败(0x4DD)分支 案例2:Simple Wasm(上交大运维赛) 字符串发现 : Base64表和密文 解码得到: iodj~44h393d5fh4;e:9h6i598f798;gd<4hf€ check函数分析 : 解法:所有字符减3得到flag 案例3:Where_ u_ are(国赛初赛) 字符串定位 : 确定main函数位置 识别scanf(0x1170)和printf(0x1173, 0x1168, 0x117C) 加密函数f23 : 输入字符映射到32字符表 0123456789bcdefghjkmnpqrstuvwxyz 分离每一位(右移j%5 & 1) 核心算法f24 : 二分查找算法 两组分别在[ -180,180]和[ -90,90 ]区间内二分 目标值:175和25 五、总结与建议 静态分析流程 : 使用wasm2wat/wasm2c进行初步转换 GCC编译优化后IDA分析 重点关注字符串、常量和内存操作 动态调试补充 : 使用Chrome/Firefox进行动态调试验证静态分析结果 结合浏览器开发者工具观察运行时行为 Wasm逆向特点 : 工具链仍在发展,分析方法有待完善 内存操作模式相对固定,容易识别关键逻辑 常量区域(如0x400偏移)常包含重要数据 进一步学习 : 熟悉WAT文本格式 了解Wasm内存模型和指令集 跟踪WABT等工具的最新发展 通过系统化的静态分析方法,结合动态调试验证,可以有效逆向分析WebAssembly程序,理解其内部逻辑和算法实现。