wasm加载流程与逆向实战
WebAssembly(Wasm)加载运行
mdn文档:https://developer.mozilla.org/en-US/docs/WebAssembly/Loading_and_running
查看文档可知:
获取网络资源Fetch或者XMLHTTPRequest
获取、编译和实例化Wasm模块有两种方法:
较新的 WebAssembly.compileStreaming/WebAssembly.instantiateStreaming 方法效率更高 - 它们直接对来自网络的原始字节流执行操作,从而无需执行该 ArrayBuffer 步骤。
旧的 WebAssembly.compile/WebAssembly.instantiate 方法要求您在获取原始字节后创建一个 ArrayBuffer 包含 WebAssembly 模块二进制文件,然后编译/实例化它。
实例化Wasm模块的时候需要传入两个参数:
module:要被实例化的 WebAssembly.Module 对象
一个包含值的对象,导入到新创建的 实例, 比如函数或 WebAssembly.Memory 对象。There must be one matching property for each declared import of module否则抛出 WebAssembly.LinkError 异常
Synchronously instantiating a WebAssembly module
The preferred way to get an Instance is asynchronously, for example using the WebAssembly.instantiateStreaming() function like this:
The WebAssembly.Instance() constructor function can be called to synchronously instantiate a given WebAssembly.Module object, for example:
WebAssembly(Wasm)逆向实战
网址:aHR0cHM6Ly93d3cuc2F0ZW5hLmNvbS8=
追栈,找目标值
全局搜索"wasm_token"
r值
继续追
单步进入
单步进入
获取、编译和实例化wasm模块
搜索 "WebAssembly.instantiateStreaming"
上面这个是void.wasm文件,继续追
看到WebAssembly.instantiate关键词,它的传入是binary,info两个参数,binary是wasm文件的字节数据,info是导入实例的对象
现在看binary是如何生成的,这里明显是getBinaryPromise()这个异步方法成功的回调,进入该方法
这里直接fetch目标的wasm文件,然后将响应转成arrayBuffer,然后用WebAssembly.instantiate(binary, info)进行实例化
binary, info
binary
info
把info扣出来即可
wasm模块导出
wasm模块调用
将依赖的函数和变量等都扣出来之后,即可调用
效果展示
结束
破解Wasm的方法不止一种,纯算(依赖工具wasm代码转成c++/js等进行静态分析)、直接把wasm文件拿出来调用(文章写的这种)......