因为想研究某小程序的某功能实现,因此打算把小程序反编译,来研究一下源码
网上搜索发现了项目:wxappUnpacker
根据项目文档操作,拿到小程序wxapkg包,使用node wuWxapkg.js ../gw.wxapkg 开始反编译
中途报错:
ReferenceError: __vd_version_info__ is not defined
at vm.js:3:3
at Script.runInContext (vm.js:130:20)
at VM.run (D:\adr\wxappUnpacker\node_modules\vm2\lib\main.js:218:62)
at runVM (D:\adr\wxappUnpacker\wuWxss.js:69:6)
at runOnce (D:\adr\wxappUnpacker\wuWxss.js:86:27)
at Array.preRun (D:\adr\wxappUnpacker\wuWxss.js:166:5)
at CntEvent.decount (D:\adr\wxappUnpacker\wuLib.js:17:43)
at ioLimit.runWithCb.err (D:\adr\wxappUnpacker\wuLib.js:73:11)
at agent (D:\adr\wxappUnpacker\wuLib.js:54:14)
at FSReqWrap.args [as oncomplete] (fs.js:140:20)
查看日志和生成文件的目录发现:
components,pages,plugins,images,app.js,app.json等关键文件和目录都已经解析成功,只是所有wxml对应的wxss文件没有解析出来,应该是卡在了解析css上。
随便从wxml文件中找一个节点的class名称对项目目录搜索,发现page-frame.html里有css数据,形式如下:
setCssToHead(["body{ height: 100%; }\n.",[1],"container { height: 100%; display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; -webkit-align-items: center; align-items: center; -webkit-justify-content: space-between; justify-content: space-between; padding: ",[0,200]," 0; box-sizing: border-box; }\nwx-button { background: inherit; padding: 0; }\nwx-button::after { border: none; }\nwx-cover-view { white-space: normal; line-height: inherit; }\n",],"Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors.(./app.wxss:26:1)",{path:"./app.wxss"})();
__wxAppCode__['common/Dialog/Dialog.wxss'] = setCssToHead([".",[1],"back-page{ position: fixed; top:0; left: 0; right: 0; bottom: 0; z-index: 10000; background: rgba(0,0,0,0.40); }\n.",[1],"dialog-content{ position: absolute; top: 50%; left: 50%; -webkit-transform: translate(-50%,-75%); transform: translate(-50%,-75%); width: ",[0,540],"; height: ",[0,266],"; background: #f3f3f3; border-radius: ",[0,12],"; text-align: center; }\n.",[1],"dialog-text{ font-family: PingFangSC-Regular; font-size: ",[0,28],"; color: #333333; text-align: center; margin: ",[0,48]," ",[0,70]," ",[0,48],"; }\n.",[1],"btn-line{ display: -webkit-flex; display: flex; -webkit-flex-direction: row; flex-direction: row; -webkit-justify-content: center; justify-content: center; }\n.",[1],"log-btn{ width: 50%; height: ",[0,90],"; padding: 0; background: none; border-top: ",[0,1]," #dfdfdf solid; font-family: PingFangSC-Regular; font-size: ",[0,32],"; color: #636363; border-radius: 0; }\n.",[1],"contact{ color: #1B9AF4; border-left: ",[0,1]," #dfdfdf solid; }\n",],undefined,{path:"./common/Dialog/Dialog.wxss"});
if (__vd_version_info__.delayedGwx) __wxAppCode__['common/Dialog/Dialog.wxml'] = [ $gwx, './common/Dialog/Dialog.wxml' ];
else __wxAppCode__['common/Dialog/Dialog.wxml'] = $gwx( './common/Dialog/Dialog.wxml' );
看来css数据和对应关系都在,只要稍做格式化就能解析出来,因此新建一个js文件,构造以下方法:
var cssList = {};
// 保存原始的css字符串
function setCssToHead(cssStrArr,info,opts){
if(!opts){
console.error('异常参数',cssStrArr,info,opts)
}else{
var path = opts.path;
cssList[path] = cssStrArr;
}
return function(){}
}
// 占位,防止报错
var __vd_version_info__ = {
delayedGwx:false
};
// 占位,防止报错
var __wxAppCode__ = {};
// 占位,防止报错
function $gwx () {
return '------'
}
把构造方法和css数据合在一起放到浏览器里运行一下,效果如下:
css并不能直接用,里面插进了一些奇怪的数组,总结了一下,有三种模式
1. [1] 总是出现在点号和class名中间,把点号和class名直接做字符串连接即可
2. [0,48] 数组是两个元素,第一项是0,第二项是一个数字,此项其实是使用rpx单位的数值,[0,48]可转化为48rpx,然后字符串连接即可
3. [2,1] 数组是两个元素,第一项是2,第二项是一个数字,此项是css import 形如 `@import '../a.wxss';`
css import数据定义在setCssToHead方法里
var setCssToHead = function(file, _xcInvalid, info) {
var Ca = {};
var css_id;
var info = info || {};
var _C= [[".",[1],"dx { box-sizing: border-box; width: 100%; height: ",[0,68],"; padding-left: ",[0,24],"; background-color: #fff; border-bottom: ",[0,1]," solid #e6e6e6; display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; -webkit-justify-content: flex-start; justify-content: flex-start; }\n.",[1],"dx .",[1],"icon { width: ",[0,30],"; height: ",[0,30],"; }\n.",[1],"dx .",[1],"title { font-size: ",[0,28],"; color: #939393; margin-left: ",[0,8],"; }\n.",[1],"dx .",[1],"title-blue { color: #507daf; }\n",],[".",[1],"slim-border { position: absolute; z-index: 9; -webkit-transform: scale(0.5); transform: scale(0.5); }\n",],];
//...
}
[2,1]代表取_C的第二个元素,把字符串取出来替换即可
完整代码在这里,用node在项目根目录运行,将css格式化并生成对应wxss文件