Skip to content

WebAssembly技术

更新: 2025/2/24 字数: 0 字 时长: 0 分钟

技术简介

WebAssembly也叫浏览器字节码技术,是一种可以使用非JavaScript编程语言编写代码并且能在浏览器上运行的技术方案。

WebAssembly的基本思路是将一些核心逻辑使用其他语言(如C/C++语言)来编写,利用Emscripten工具编译成类似字节码的wasm格式的文件,通过JavaScript调用执行,从而起到二进制级别的防护作用。由于Webassembly是经过编译器编译之后的字节码,因此运行速度更快,体积更小,而且在语法上完全脱离 JavaScript,同时具有沙盒化的执行环境。

使用示例

比如,这就是一个基本的Webassembly示例:

WebAssembly.compile(new Uint8Array(`
  00 61 73 6d  01 00 00 00  01 0c 02 60  02 7f 7f 01
  7f 60 01 7f  01 7f 03 03  02 00 01 07  10 02 03 61
  64 64 00 00  06 73 71 75  61 72 65 00  01 0a 13 02
  08 00 20 00  20 01 6a 0f  0b 08 00 20  00 20 00 6c
  0f 0b`.trim().split(/[\s\r\n]+/g).map(str => parseInt(str, 16))
)).then(module => {
  const instance = new WebAssembly.Instance(module)
  const { add, square } = instance.exports
  console.log('2 + 4 =', add(2, 4))
  console.log('3 ^ 2 =', square(3))
  console.log('(2 + 5) ^ 2 =', square(add(2 + 5)))
})

**这里其实是利用WebAssembly定义了两个方法,分别是 addsquare,分别用于求和和开平方计算。那这两个方法是在哪里声明的呢?其实它们被隐藏在 Uint8Aray 里面。仅仅查看明文代码,我们确实无从知晓里面究竟定义了什么逻辑,但确实是可以执行的。**我们将这段代码输入到浏览器控制台下,运行结果如下:

2 + 4 = 6
3 ^ 2 = 9
(2 + 5) ^ 2 = 49

?> 提示:通过WebAssembly可以成功将核心逻辑“隐藏”起来,这样某些核心逻辑就不能被轻易找出来了。所以越来越多的网站使用WebAssembly技术来保护一些核心逻辑不轻易被人识别或破解,可以起到更好的防护效果。

wasm文件

**通过WebAssembly编译后的文件即为 .wasm 文件。在Python中可以使用第三方库 pywasm 来调用 .wasm 文件里面的方法。**第三方库 pywasm 安装命令和使用方法如下:

pip install pywasm

20211006032331

实战解析

难度:简单

题目地址:https://match.yuanrenxue.com/match/15

访问网址获取任务,在Network里面的Fetch/XHR选项中定位到了该网页数据的来源请求,发现相对于前面的题目还多加载了两次 main.wasm 文件,继续分析:

20211006024318

多次访问前面3页的页面,分析比较请求头参数,得出初步接结论:每次请求,请求头的参数没有发生变化,但参数m的值在不断发生变化,参数page则是页码数。

20211006024903

现在我们需要定位到,哪一行的代码发送了当前的请求,点击左侧的Initiator选项,它主要是标记请求是由哪个对象或进程发起的(请求源),重点关注里面的request请求,显示从一个名称为“15”的文件的第736行代码发送了当前请求,点击后面的地址:

20211006025235

跳转到了该文件的第736行,看上面有两个很熟悉的参数 page 页码和 m 加密参数,参数m的值来源于 window.m() 方法的返回值,其中 window.m() 方法返回值涉及到三个变量,window.q() 方法、t1t2,其中 t1t2 的值和时间戳有关,而 window.q 方法和 resultsencode 方法有关,而 results 就是 main.wasm 文件内容,也正是最开始第一次请求加载的文件:

20211006025420

这下就可以对加密参数完全得出结论了:

参数m:和变量t1、t2、main.wasm文件的encode方法有关
参数page:页码数

下载并保存网站上的 main.wasm 文件,双击开发者工具里的main.wasm文件进行下载:

20211006034209

修改上面的示例代码,结合上面截图的m参数试运行,结果和m参数最前面的数一样:

20211006034456

这里我们就只需要抠生成变量 t1t2 的JS代码,最后返回一个数组即可:

javascript
m = function (){
    t1 = parseInt(Date.parse(new Date())/1000/2);
    t2 = parseInt(Date.parse(new Date())/1000/2 - Math.floor(Math.random() * (50) + 1));
    return Array(t1, t2);
};