Python 爬虫进阶必备 | 当 Js 逆向遇上 wasm(一)
点击上方“咸鱼学Python”,选择“加为星标”
第一时间关注Python技术干货!
图源:极简壁纸
前言
Wasm 是一种底层汇编语言,具有文本格式支持,其目标是可移植、安全和高效。
Wasm 的模块可以被导入的到一个网络 app(或Node.js)中,并且暴露出供 JavaScript 使用的 Wasm 函数。
Wasm 与其他虚拟机的主要区别在于,它没有针对任何特定的编程语言进行优化,而只是抽象底层硬件,字节码直接对应于现代 cpu 的指令和内存模型。
简单的来说就是它是比较底层的汇编语言,它比较难懂,它比较安全
上面的概念部分只是了解下关于 wasm 的基本概念,主要还是得看实操
今日网站
aHR0cHM6Ly9tYXRjaC55dWFucmVueHVlLmNvbS9tYXRjaC8xNQ==
抓包分析与加密定位
访问网站可以看到要求我们获取到当前页面的总数
所以先开抓包看看页面信息的获取
大致分析一下可以知道访问首页是没有加密参数的,但是翻页的时候是需要一个加密参数m
所以需要分析的参数就是这个m
我们找到 js 的堆栈
在第三个的位置可以找到这个 js 加密的位置
可以看到这里提交了参数list
,这里的m
是window.m
调用后的结果
通过箭头2
可以找到window.m
的逻辑
这里就引出了window.q
这个函数
打上断点再点击翻页可以断在window.q
中
我们跟进去看看这里window.q
的逻辑
通过上一个的js
逻辑我们大概可以猜出来上面这一大段应该是来自wasm
文件应该是从/static/match/match15/main.wasm
加载
我们找到这个wasm
文件
复现
这里的wasm
文件拿到了但是我们要怎么去分析它呢?
这里有两种方法,看了下网上关于 wasm 的轮子非常多,可以将 wasm 转换成 c、c++ 等,方法远不只两个
方法一
第一种是使用wasm2js
# 项目地址
https://github.com/thlorenz/wasm2js
安装
npm install wasm2js
然后可以使用这个包读取这个wasm
文件还原成js
,然后扣逻辑就可以了
方法二
第二种是使用现成的 python 第三方包pywasm
安装
pip install pywasm
使用 demo
import pywasm
# pywasm.on_debug()
runtime = pywasm.load('./examples/fib.wasm')
r = runtime.exec('fib', [10])
print(r) # 55
看了下官方的 demo,好像非常简单
那我们也试一下
这里比较难受的是,我们在读取wasm
之后要调用那个方法?
还是要找到wasm
的入口才行,所以又回到了解析 wasm 的路子上
还好网上轮子不少,下面这个网站提供
wat2wasm
wasm2wat
两种格式的互转
https://webassembly.github.io/wabt/demo/
我们这里需要选择的是wasm2wat
,就是将wasm
转化为c
语言
解析之后的样子像下面这样
这里其实就可以看到大概的逻辑了,这里文件导出了encode
,我们可以在外部调用这个方法,传入t1、t2
即可
如果你感觉转化为c
语言也不是很好懂的话,可以再用下面的这个包
https://github.com/WebAssembly/wabt
https://github.com/WebAssembly/wabt/blob/main/docs/decompiler.md
但是编译一次发现还不如wasm2js
好用
通过在线编译器我们已经知道了这个 wasm 文件的导出方法是encode
,所以试着带入计算
import math
import random
import time
import pywasm
t = int(time.time())
t1 = int(t / 2)
t2 = int(t / 2 - math.floor(random.random() * 50 + 1))
wasm_vm = pywasm.load("demo1.wasm")
m = wasm_vm.exec("encode", [t1, t2])
print(m)
print(str(m) + '|' + str(t1) + '|' + str(t2))
这样就可以得出m
的值了
之后会再写两篇关于 wasm 的内容,wasm 还是很有意思的,主要是轮子很多可以拿来就用,过程全靠躺。
好了,以上就是今天的全部内容了。
我是没有更新就在摸鱼的咸鱼
收到请回复~
我们下次再见。
对了,看完记得一键四连,这个对我真的很重要。