最近公司正好安排在开发一款微信小程序,是一个政府的政策查询和展示的小程序。已接近完成,有一些功能需要参考其他的成熟的微信小程序,一些比较复杂的功能实现技术上可能有点难度,于是就只好看看能不能获取它的源码,然后参考下哈哈。所以就想着有什么办法能够获取和反编译小程序的源码解读参考一下。
网上一搜果然有人研究过了,并且还有个大神写了个反编译的工具。通过这个工具我们就可以反编译微信小程序的源码了。
准备工作,下载工具
首先我们应该都知道,微信小程序是先从其微信的服务器下载小程序代码下载到本地后再执行和渲染的。所以我们可以可以通过从手机的本地微信目录中获取到其源码。但是如果是iOS设备,其沙箱机制你是获取不到了,除非越狱。安卓的貌似也获取不到(没有安卓设备,没尝试)。这是可以使用模拟器安装和运行微信,然后从其目录中获取,需要工具:
- 夜神安卓模拟器,下载地址
- 安装RE管理器,网上搜索一下,下载apk然后拖进模拟器即可
- 本机node.js环境。可使用node -v来检查下使用安装
- 反编译的工具,wxappUnpacker
安装完夜神模拟器后,在模拟器里面安装微信。注意如果是直接安装微信的话,打开会闪退。可能是新版微信做了些校验吧。这时我们需要下载安装旧版本的微信,可从这个获取这个版本的微信:https://bbs.yeshen.com/forum.php?mod=viewthread&tid=10366&extra=page%3D1
安装这个版本后是登录不了的。需要升级到最新版本,然后就可以打开登录了。最后再安装下QQ,用于发送小程序文件到电脑。
开始获取.wxapkg包
接下来就是从模拟器中获取微信小程序的源码了。
首先得知道微信小程序的存放目录:
/data/data/com.tencent.mm/MicroMsg/{{一串32位的16进制字符串名文件夹}}/appbrand/pkg/
赋予RE管理器超级用户权限,然后从RE管理器中访问这个路径进行获取。
访问上述的路径:
长按这些包,然后可多选进行压缩:
压缩后会弹出一个查看,点击后查看这个压缩包,然后选择发送到电脑或QQ:
最后就得到了一个或多个小程序包了。
开始反编译.wxapkg
clone 这个GitHub上的开源库,wxappUnpacker
安装一些依赖
安装其提到的一些依赖:
npm install esprima -g
npm install css-tree -g
npm install cssbeautify -g
npm install vm2 -g
npm install uglify-es -g
npm install js-beautify -g
npm install escodegen -g
npm执行出现问题:
ker-farm/node_modules/errno/node_modules
npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules/npm/node_modules/worker-farm/node_modules
npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules
原因是权限问题,我们需要把npm配置在其他目录。
新建一个全局的安装目录:
$ mkdir ~/.npm-global
配置npm用一个新的路径:
$ npm config set prefix '~/.npm-global'
编辑~/.profile文件:
$ export PATH=~/.npm-global/bin:$PATH
使其生效:
$ source ~/.profile
测试:
$ npm install -g jshint
详细参考:
https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally
开始反编译
使用命令:
# $node wuWxapkg.js [-o] [-d] [-s=]
$ $ node ~/develop/wxappUnpacker/wuWxapkg.js ~/study/微信小程序/microwxpkg/_-1919813009_6.wxapkg
执行后可能会出现如下错误:
throw this._internal.Decontextify.value(e);
^
ReferenceError: $gwx is not defined
at vm.js:3:3
at Script.runInContext (vm.js:107:20)
at VM.run (/Users/dev/node_modules/vm2/lib/main.js:210:72)
at runVM (/Users/dev/develop/wxappUnpacker/wuWxss.js:69:6)
at runOnce (/Users/dev/develop/wxappUnpacker/wuWxss.js:88:27)
解决:在runVM(name,code)方法中修改代码即可。
(更新:增加runVM方法中要替换的代码)
代码如下,注释掉原来方法中的代码,增加以下代码:
let wxAppCode = {};
let handle = {cssFile:name};
let gg = new GwxCfg();
let tsandbox = {
$gwx:GwxCfg.prototype["$gwx"],
__mainPageFrameReady__:GwxCfg.prototype["$gwx"],
__wxAppCode__: wxAppCode,
setCssToHead:cssRebuild.bind(handle)
}
let vm = new VM({sandbox:tsandbox});
vm.run(code);
for(let name in wxAppCode){
if(name.endsWith(".wxss")){
handle.cssFile = path.resolve(frameName,"..",name);
wxAppCode[name]();
}
}
最终反编译成功。不过只有主包的有完整的文件,分包的只有json文件。