本文仅供技术交流和技术学习 不做其他用途
接着上一篇继续讲:
上篇地址:
JS逆向之wasm逆向(二进制)
网址:
aHR0cHM6Ly93d3cuN3E2Y3lqLmNvbTo5MDAxL3JlZ2lzdGVyNDY5Njg/aV9jb2RlPTQ0Mjc5OTU1
这个网站我们后面可以继续讲他的debugger 和滑块和登录加密
上一篇我们把定位和原理讲得差不多了 现在讲这个我们怎么去调用他;
两种方法调用:
我们这里只讲一种 node调用 因为c调用的话估计很多人听不懂了 比较麻烦。
node里面有WebAssembly这个api 比较坑就是必须版本16以上的node才能调用的
cmd查看node的版本 自己查看一下版本
node --version
在这里插入
后面我们来分析代码
function() {var e, c, t, f, n = {};var d = {38464: function() {return {"./wasm_api_sign_bg.js": {__wbg_now_513c8208bd94c09b: function() {return void 0 === e && (e = a.c[88867].exports),e.ei()},__wbg_random_9f33d5bdc74069f8: function() {return void 0 === c && (c = a.c[88867].exports),c.Aw()},__wbg_floor_a68aa7c1b572044e: function(e) {return void 0 === t && (t = a.c[88867].exports),t.OS(e)},__wbindgen_throw: function(e, c) {return void 0 === f && (f = a.c[88867].exports),f.Or(e, c)}}}}}, r = {2284: [38464]};a.w = {},a.f.wasm = function(e, c) {(r[e] || []).forEach((function(t, f) {var r = n[t];if (r)c.push(r);else {var b, o = d[t](), i = fetch(a.p + "static/wasm/" + {2284: {38464: "63d1a0a2a2e13f93b6f2"}}[e][t] + ".wasm");if (o && "function" === typeof o.then && "function" === typeof WebAssembly.compileStreaming)b = Promise.all([WebAssembly.compileStreaming(i), o]).then((function(e) {return WebAssembly.instantiate(e[0], e[1])}));else if ("function" === typeof WebAssembly.instantiateStreaming)b = WebAssembly.instantiateStreaming(i, o);else {b = i.then((function(e) {return e.arrayBuffer()})).then((function(e) {return WebAssembly.instantiate(e, o)}))}c.push(n[t] = b.then((function(e) {return a.w[t] = (e.instance || e).exports})))}}))}}()
他用fetch去加载了wasm的代码 (相对网络请求去获取二进制文件)
下面是我们改写的代码
var o = function () {return {"./wasm_api_sign_bg.js": {__wbg_now_513c8208bd94c09b: function () {return Date.now()},__wbg_random_9f33d5bdc74069f8: function () {return Math.random()},__wbg_floor_a68aa7c1b572044e: function (e) {return Math.floor(e)},__wbindgen_throw: function (e, c) {return void 0 === f && (f = a.c[88867].exports),f.Or(e, c)}}}
};
let i = fetch("https://www.7q6cyj.com:9001/_next/static/wasm/63d1a0a2a2e13f93b6f2.wasm");
let b = WebAssembly.instantiateStreaming(i, o())
b.then(function(e) {let s=e.instance.exports;console.log(s)
}
)
写完之后执行就拿到了sign方法 和其他几个我们需要执行的方法 o方法非常的简单 我这里怎么还原的 你们随便调试一下就知道了
WebAssembly.instantiateStreaming这个方法的讲解可以去官网看一下https://developer.mozilla.org/zh-CN/docs/WebAssembly/JavaScript_interface/instantiateStreaming_static
这里下面就继续跟着我们咋天调试的步伐继续还原 还原b方法 b方法里面取值的一些方法就不一一调试了 里面的方法非常的简单
var o = function () {return {"./wasm_api_sign_bg.js": {__wbg_now_513c8208bd94c09b: function () {return Date.now()},__wbg_random_9f33d5bdc74069f8: function () {return Math.random()},__wbg_floor_a68aa7c1b572044e: function (e) {return Math.floor(e)},__wbindgen_throw: function (e, c) {return void 0 === f && (f = a.c[88867].exports),f.Or(e, c)}}}
};
let i = fetch("https://www.7q6cyj.com:9001/_next/static/wasm/63d1a0a2a2e13f93b6f2.wasm");
let f=0;
function a(n, e, t,rs) {let r = n.length, o = e(r);const u = c(rs);let i = 0;for (; i < r; i++) {const e = n.charCodeAt(i);if (e > 127)break;u[o + i] = e}if (i !== r) {0 !== i && (n = n.slice(i)),o = t(o, r, r = i + 3 * n.length);const e = c().subarray(o + i, o + r);i += _(n, e).written}return f = i,o
}
function w(r) {let l = new Int32Array(r.memory.buffer);return l;
}
function c(r) {return new Uint8Array(r.memory.buffer);
}
let u = new ("undefined" === typeof TextDecoder ? (0,n.require)("util").TextDecoder : TextDecoder)("utf-8", {ignoreBOM: !0,fatal: !0});
function is(n, e, r) {return u.decode(c(r).subarray(n, n + e));
}
let b = WebAssembly.instantiateStreaming(i, o())
b.then(function (e) {let r = e.instance.exports;const u = r.__wbindgen_add_to_stack_pointer(-16), c = a("/act/api", r.__wbindgen_malloc, r.__wbindgen_realloc,r), d = f, _ = a("prod", r.__wbindgen_malloc, r.__wbindgen_realloc,r), l = fr.sign(u, c, d, _, l);var t = w(r)[u / 4 + 0], o = w(r)[u / 4 + 1];console.log(is(t, o, r))
}
)
执行结果输出
感兴趣的朋友去可以看看这个网站 里面有滑块 debugger 还有wasm 这些都值得去练习和玩玩的
感谢大家观看 拜拜
欢迎大家关注我的公众号 后面会持续输出更多的好文章