pingan好车主小程序 充电站、加油站列表vmp+wasm
逆向
声明:仅供学习使用
1.接口概览
url:
https://a1d5ce9f4-wx621112590b635086.sh.wxgateway.com/__wx__/call?token=97_6m4bQno7K7H4qamt18Bf8tj-i8zK8oFkQkSgh8N-_6t5L2Inf0ToWz4w55Emj9zRrsmuxhv7dVfm-Q5gzTDQoGW5RDGArAst_mR5cWY4jc3JPUYOkkT5ymObKNCCEARQlJDQolev-ltVq2v48IfraxoLtLgxKGo0-E0KBh2td5hMyAEs58sV0YUlodXuqC3X6cN0vyJJKbovyImNcpw4KBgLaSKPZnZ8ajmKsO-URIAysAAZZBx8AwAY0xKYLi1mUKsQIQ1-GRmtgur2KPwNFx1pw8PdfKWqkLtTWj-jUN1lIDjD9-J7MN_uIlU13CAi6qlz4_zwOoRMh-RT5_Ts4immt_wVhcn2_8qOmRxgrwvW-LCEgCl3A-VtWfQKz8rNsf8s7IH_yU9FHCF4LGIOSZwk3Z19bjCY0Di9XylYt2t505mVoe9rOB3N6CE7BxgidN5GZZ5JSPMXPROrc59Zb3hFlE778TgQRLcqexjVvZXL8LWFm42ONCLmKFnGHBT85zYFJr32qdDl9qC28TSX24JbaBRx5VlpfgDqTRDKmN4Nnkk33I-TYGpC_mplavTma-CpTUWLcMpVLdFFU9jeIq9vfNPIOl5UbpZa-fBC91K21_a71bZBFUlSzN8&callid=1760268810868-GVcPn6zG&devtools_ignore=true
请求体:
POST /__wx__/call?token=97_6m4bQno7K7H4qamt18Bf8tj-i8zK8oFkQkSgh8N-_6t5L2Inf0ToWz4w55Emj9zRrsmuxhv7dVfm-Q5gzTDQoGW5RDGArAst_mR5cWY4jc3JPUYOkkT5ymObKNCCEARQlJDQolev-ltVq2v48IfraxoLtLgxKGo0-E0KBh2td5hMyAEs58sV0YUlodXuqC3X6cN0vyJJKbovyImNcpw4KBgLaSKPZnZ8ajmKsO-URIAysAAZZBx8AwAY0xKYLi1mUKsQIQ1-GRmtgur2KPwNFx1pw8PdfKWqkLtTWj-jUN1lIDjD9-J7MN_uIlU13CAi6qlz4_zwOoRMh-RT5_Ts4immt_wVhcn2_8qOmRxgrwvW-LCEgCl3A-VtWfQKz8rNsf8s7IH_yU9FHCF4LGIOSZwk3Z19bjCY0Di9XylYt2t505mVoe9rOB3N6CE7BxgidN5GZZ5JSPMXPROrc59Zb3hFlE778TgQRLcqexjVvZXL8LWFm42ONCLmKFnGHBT85zYFJr32qdDl9qC28TSX24JbaBRx5VlpfgDqTRDKmN4Nnkk33I-TYGpC_mplavTma-CpTUWLcMpVLdFFU9jeIq9vfNPIOl5UbpZa-fBC91K21_a71bZBFUlSzN8&callid=1760268810868-GVcPn6zG&devtools_ignore=true HTTP/2
host: a1d5ce9f4-wx621112590b635086.sh.wxgateway.com
content-length: 1122
x-wx-ev: 3
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467
xweb_xhr: 1
content-type: application/octet-stream
x-wx-rid: 2264223105
accept: */*
sec-fetch-site: cross-site
sec-fetch-mode: cors
sec-fetch-dest: empty
referer: https://servicewechat.com/wxf225684ee1536a5f/630/page-frame.html
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9
priority: u=1, i
<binary body>
响应体:
HTTP/2 200
date: Sun, 12 Oct 2025 11:33:30 GMT
content-type: application/octet-stream
content-length: 530
x-wx-mesh-upstream-service-time: 8,3
x-wx-envoy-service-time: 126
x-wx-server-timing: 1760268810787,1760268810913
server: envoy
<binary body>
2.分析
大概一看url中有token、callid,以及body有二进制数据
多次请求发现token固定,callid为时间戳加随机数形式:
尝试逆向body的二进制数是关键
进入调试后发现是vmp+wasm架构的形式,通过共享内存和方法的形式实现加密操作。
wasm处理思路,网上搜一下,有个比较全的介绍了wasm处理的常见思路,调试分析思路等,比如wasm2c等的,借助ida等工具的……
我分享的是,实操的一般方法,wasm可以通过补环境的方式,最朴素的wasm没有导入外部函数,这样的很简单,但是需要导入外部函数的情况下,就必须保证正确将所有需要用到的函数都成功导入,一般来讲可以通过hook WebAssembly.instantiate
方法监视实例化的入参获取信息,同时可以hook其中可能用到的环境检测函数做一些过检测操作,如下:
WebAssembly.instantiate = function (bufferSource, importObject) {
debugger;
mylog('WebAssembly.instantiate called!');
mylog('Buffer size:', bufferSource.byteLength);
mylog('Import object:', importObject);
//hook snipest
mylog("hook环境检测...")
if (importObject['./snippets/wxcloud-c178ccf6f2599ff9/src/js/platform.js']) {
importObject['./snippets/wxcloud-c178ccf6f2599ff9/src/js/platform.js'] = {
//环境检测函数,hook返回值直接不用补环境了,需要经验
detectPlatform: function () { return 0 },
detectHost: importObject['./snippets/wxcloud-c178ccf6f2599ff9/src/js/platform.js']['detectHost'],
detectSystemInfo: importObject['./snippets/wxcloud-c178ccf6f2599ff9/src/js/platform.js']['detectSystemInfo'],
detectUserAgent: importObject['./snippets/wxcloud-c178ccf6f2599ff9/src/js/platform.js']['detectUserAgent'],
detectUserAgentSync: importObject['./snippets/wxcloud-c178ccf6f2599ff9/src/js/platform.js']['detectUserAgentSync'],
}
}
// Call original function
return originalInstantiate.call(WebAssembly, bufferSource, importObject)
.then(result => {
result.instance && result.instance.exports && console.log('Exports:', result.instance.exports);
algo.handler = result.instance && result.instance.exports && result.instance;
mylog('WASM module instantiated successfully');
return result;
})
.catch(error => {
console.error('WASM instantiation failed:', error);
throw error;
});
};
通过上述处理,如果能够成功实例化,那么可以进行下一步,找加密调用入口,比如:
var d = "a1d5d4319-wx621112590b635086.sh.wxgateway.com"
var h = new window.cloud.Cloud({
identityless: !0,
resourceAppid: "wxf225684ee1536a5f",
config: {
customDomain: "https://" + d
}
});
h.init();
var g = h.services.Gateway({
domain: d
});
mylog('初始化完成...',g)
g.call("待加密的文本....")
通过上述入口激发wasm加密流程,持续追踪相关错误信息和可能的日志信息,实现加密流程,本案例中,wasm完成加密后,只是修改了内存里的值,并不会直接返回加密后的数据,而且在wasm里直接调用了外部的request函数发起了fetch请求,获取数据,封装成了异步的函数,因此,可以直接使用它的逻辑,不拘泥于追求加密后的文本,可以直接让js代码完成请求返回响应内容也可以。
当然,如果想截获加密后的文本,也可以hook request函数,截获即可。
3.总结
注意:另外可以hook fetch不从远端下载wasm代码,直接使用本地替换,也可以在fetch中截获需要的加密参数。
如果你想寻找纯算法还原的,那么是需要去反编译wasm跟踪内存的,调试时间需要比较长。。。自行探索吧,。,,
放一张成功截图: