什么是反编译

微信小程序可以运行在手机微信或者 pc 版微信环境下,它是以一个应用包的形式存在的,这个应用包的后缀通常是 .wxapkg。如果想知道某个微信小程序的功能模块是如何实现的,就需要把这个包给解开,这个过程就叫反编译。

获取小程序包

要反编译微信小程序,那首先就需要获取微信小程序的应用包。

可以在 pc 版本微信上获取包,那么就需要在 pc 版微信上先运行某个小程序;运行完成后,就会在电脑某个目录下生成这个小程序的包,我们需要找到这个目录,那么就找到了这个包了。

windows 和 mac 环境不同,包的位置也会不一样。

windows 系统

打开微信设置-文件管理-就能看到微信的目录了,继续往下找到 /applet 这个目录,就能看到小程序的包了。示例:D:\软件\WeChat Files\WeChat Files\Applet\小程序 AppID__APP__.wxapkg

mac 系统

包通常是被放在:/System/Volumes/Data/Users/你的用户名/Library/Containers/com.tencent.xinWeChat/Data/.wxapplet/packages/小程序 AppID/随机数/APP.wxapkg

知道了目录后,就可以拿到包了。

在 mac 下进入某个目录可以这样做:

  • 访达-前往-前往文件夹-然后把目录路径贴到输入框,选择某个路径就可以进去了;
  • 或者在终端用命令:open 目录路径;

如果 mac 系统的包不在刚刚说的目录下,还有一种方式可以找到。那就是通过微信小程序 AppID 来搜索目录。那就需要先知道某个微信小程序的 AppID 是什么。

可以通过如下这张图的操作路径来获取 AppID:

获取AppID

拿到了 AppID 后,就可以通过终端里输入命令来进行搜索了:

1
find / -name 某个AppID

当搜索到这种路径的时候就说明找到了,就可以停止搜索了。

反编译

拿到了小程序应用包,接下来就需要通过代码把这个包给解开,然后还原成可以跑在微信开发者工具上的微信小程序项目代码了。

反编译使用的是 github 上的开源项目:wxappUnpacker

把这个项目 clone 到本地后,安装好依赖,就可以使用如下命令进行反编译了:

1
node wuWxapkg.js /System/Volumes/Data/Users/你的用户名/Library/Containers/com.tencent.xinWeChat/Data/.wxapplet/packages/小程序AppID/随机数/__APP__.wxapkg

由于这个库的程序比较旧了,而小程序的项目结构或者语法再时时更新,所以在解包的时候有可能会报错,这个不用管。

解包完成后,会在 APP.wxapkg 的同级目录生成一个 APP 的文件夹,这个文件夹就是微信开发者工具的可识别的项目目录。把它复制到外面,好让微信开发者工具方便导入,导入项目过程中的 AppID 使用测试号即可。

在微信开发者加载代码的过程中,正常不会很顺利,我自己反编译了几个小程序也都会有问题。比如如下图:

报错

问题一:require(…)() is not a function

比如如下文件 miniprogram_npm/@vant/weapp/wxs/utils.wxs 中的 require(…)() 改成 require(…) 即可。

1
2
3
4
5
6
7
8
9
10
11
-  var bem = require('p_./miniprogram_npm/@vant/weapp/wxs/bem.wxs')();
+ var bem = require('p_./miniprogram_npm/@vant/weapp/wxs/bem.wxs');
- var memoize = require('p_./miniprogram_npm/@vant/weapp/wxs/memoize.wxs')();
+ var memoize = require('p_./miniprogram_npm/@vant/weapp/wxs/memoize.wxs');
- var addUnit = require('p_./miniprogram_npm/@vant/weapp/wxs/add-unit.wxs')();
+ var addUnit = require('p_./miniprogram_npm/@vant/weapp/wxs/add-unit.wxs');
module.exports = ({
bem: memoize(bem),
memoize: memoize,
addUnit: addUnit,
});

问题二:_typeof2 is not a function

这个错误文件是 @babel/runtime/helpers/typeof.js,把如下代码替换掉原文件代码即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function _typeof2(o) {
"@babel/helpers - typeof";
return (_typeof2 =
"function" == typeof Symbol && "symbol" == typeof Symbol.iterator
? function (o) {
return typeof o;
}
: function (o) {
return o &&
"function" == typeof Symbol &&
o.constructor === Symbol &&
o !== Symbol.prototype
? "symbol"
: typeof o;
})(o);
}

function _typeof(o) {
return (
"function" == typeof Symbol && "symbol" === _typeof2(Symbol.iterator)
? (module.exports = _typeof =
function (o) {
return _typeof2(o);
})
: (module.exports = _typeof =
function (o) {
return o &&
"function" == typeof Symbol &&
o.constructor === Symbol &&
o !== Symbol.prototype
? "symbol"
: _typeof2(o);
}),
_typeof(o)
);
}

module.exports = _typeof;

其他一些别的错误,需要看报错信息对应改一下,这里就不再多介绍了。