小程序反编译

3,852 阅读6分钟

前言

最近连续过两个购物节,想必大家对于自己究竟点开了多少次某网购 App 都记不清楚了,本人手机一向以精简为宗旨,所以没有那几个 App……

因为懒得装那些 App,这直接导致我使用 小程序 的频率越来越高了。

经常使用,就会发现这些小程序的体验变得越来越好,无论是加载速度、动效、H5、算法,AR 还是小游戏等都让人很感兴趣。

所以产生了学习借鉴的念头……

本文将记录 微信小程序反编译 的过程,注意禁止使用此方法盗取他人的开发成果

步骤

这里通过安卓模拟器获取小程序 pkg

说下原因:

如果想通过手机直接获取 pkg 文件,你需要有一部安卓手机;如果你只有一部苹果手机,那需要先越狱。

以上的条件你都没达到,那么就可以使用 PC 端的模拟器了。

1. PC 下载 MuMu 模拟器 并安装。

2. 去模拟器的应用中心下载并安装:微信RE 文件管理器

注意点:因为这里模拟的是移动端登录,所以会踢掉你手机软件的账号。

其次,后续需要转移文件到模拟器外进行反编译,我们采用的是 RE 文件管理器的分享文件功能,你有 3 条路可选。

  • 分享给微信-你的 文件传输,但你需要保证 PC 端另外还有一个在线的账号,因为你的手机已经掉线了。
  • 分享给你的好友,让他转发回来给你。
  • 分享给 QQ (你需要再装个 QQ ?)。

3. 加载资源缓存本地

  1. 微信登录
  2. 打开小程序

比如某宝,假设你中意它的某个活动页的小游戏,它的图案、算法等,那么你需要进入该页面停留一点时间,让该页面资源缓存到本地,毕竟,你知道的,小程序的代码是 分包 构建的,按需加载内容。

4. 查找资源位置

对了,你可能需要先给 RE 管理器 ROOT 权限!!否则有些路径是无法访问的。

ROOT Mac 端你需要这样操作:选项设置-ROOT权限-打勾

瞅瞅,这就是分包,好家伙,一堆 pkg:

其中小程序的主包会先加载,拥有 /TabBar 页面和一些公共资源,不会超过 2M。

5. 迁移到沙盒外

现在想办法将这些 pkg 复制到模拟器外,长按这些 pkg 文件(模拟的移动端操作),然后创建tar 文件、查看、发送到电脑加压。

6. 下载开始反编译 反编译工具

下载完成后解压,然后进入 nodejs/nodejs 文件下,创建文件夹 node_modules,将其中的 node_modules.zip 解压到 node_modules 文件夹中。

完成之后,将之前准备好的 .wxapkg 包 放入到 wxapkg 文件夹中。

启动工具 exe,选择执行文件,然后开始反编译。

执行完成之后,生成的源码文件和 wxapkg 包在相同目录下,现在可以使用 VSCode 查看源码了,巧用搜索,配合 Fiddle 等抓包工具,找到你所需要的。

如果只是出于学习借鉴,到这一步就足够了,开始你的探索之旅吧。

7. 文件分析

反编译后,你会发现这些文件大部分被混淆了,可读性很差,所以需要将进一步分析,尽可能地把 .wxapkg 包的内容还原为编译前的内容。(也有没混淆的,那真是 thank god!)

通常,一个小程序工程主要包括如下几类文件:

  • .json 后缀的 JSON 配置文件
  • .wxml 后缀的 WXML 模板文件
  • .wxss 后缀的 WXSS 样式文件
  • .js 后缀的 JavaScript 脚本逻辑文件

但是客官你看图...???

简单分析下:

  • app-config.json:其实就是 app.json 和各个页面的配置文件的汇总
  • app-service.js:主要包括 app.js,每个页面的 page.js,开发者自定义的 JS 文件和引入的第三方 JS 文件,在“编译”后所有这些 JS 文件都会被汇总到 app-service.js 文件中。
  • page-frame.html:包括各自页面的 page.wxss 和 page.wxml。

因此,到这里我们需要第 2 个 反编译工具 wxappUnpacker

wxappUnpacker 项目克隆到本地,yarn or npm install ... 安装项目依赖。

打开 terminal,输入命令进行最后的努力...

  • node wuConfig.js <files...> :将 app-config.json 中的内容拆分到各个文件对应的 .json 和 app.json , 并通过搜索 app-config.json 所在文件夹下的所有文件尝试将 iconData 还原为 iconPath 。
  • node wuJs.js <files...> :将 app-service.js (或小游戏中的 game.js ) 拆分成一系列原先独立的 javascript 文件,并使用 Uglify-ES 美化,从而尽可能还原编译前的情况。
  • node wuWxml.js [-m] <files...> :将编译/混合到 page-frame.html ( 或 app-wxss.js ) 中的 wxml 和 wxs 文件还原为独立的、未编译的文件。如果加上 -m 指令,就会阻止block块自动省略,可能帮助解决一些相关过程的 bug 。
  • node wuWxss.js <dirs...> :通过获取文件夹下的 page-frame.html ( 或 app-wxss.js ) 和其他 html 文件的内容,还原出编译前 wxss 文件的内容。

当然,wxappUnpacker 也能代替前面的可视化工具反解析,不过有一点 bug,我查看了下是文件命名、解包顺序等逻辑变更了(混淆的文件类型和明命名方式并不统一)。

8. 尝试运行

打开 微信开发者工具 试着运行下解析出来的文件夹吧。

导入之后,可能并不能一次编译成功,一般都是环境问题导致,根据报错开始调试吧。

经 @太帅搞全栈 的提示,这里增加备注:

  • 不是所有小程序都可以获得源码,反编译和获得源码是两个不同的概念,使用 uniapp 或 taro 开发的小程序,反编译后代码不具备可读性。
  • 大多小游戏获取不到源码,仅以学习和获取图片资源等为动机。

最后

如果你觉得这篇内容对你挺有启发,记得点个 丫,让更多的人也能看到这篇内容,拜托啦,这对我真的很重要。

往期精选

「中高级前端面试」手写代码合集(上)

「中高级前端面试」手写代码合集(下)

TLS 握手流程详解