上周末突然想到,某个人项目代码一直在个人的MAC上没有进行源码管理,于是尝试了一下GIT,在IDEA和Visual Code上弄了小半天,居然都没弄出来,郁闷了一会放弃。结果周日一看不对,不知道什么时候IDEA上的代码全部都清空了,只剩下目录。悲剧的是,前端代码和微信小程序代码都放在后端工程的子目录,一并消失,于是进入了为期三天的源码恢复自救工程。
整个源码恢复自救工程包括Java后端代码、微信小程序代码和Vue前端代码,通过文言一心、百度、CSDN等各种手段,最大的感触是网上资料良莠不齐,大浪淘沙始见真金,所以专门整理一篇文章供有需要的小伙伴参考。
具体环境信息如下表所示:
子项名称 | 子项内容 | 版本 |
Java后端 | IDEA | 2023.2.2 |
Vue2管理前端 | Visual Code | 1.86.0 |
微信小程序 | 微信小程序官方开发工具 | 1.06.23 |
个人电脑 | Macbook Pro M1pro | Sonama 14.2.1 |
微信MAC版 | 用于下载小程序包 | 3.8.6 |
不幸中之大幸是在2023年10月18日备份过一个版本,对照了一下,一共有35个需求或Bug的修复工作需要重新做一遍。
一、Java后端代码恢复
Java代码的恢复最为成熟,就是JAR的反编译,本来想通过IDEA的java-decompiler插件完成,结果安装完成后,用IDEA死活打不开.jar文件(文件对话框中jar文件一直是灰色无法选择),所以就只能用jd-gui了,因为反编译方案成熟的缘故,网上一堆可供下载,我用的是jd-gui-osx-1.6.6版本。
用jd-gui打开jar包,然后选择“File”菜单中的“Save All Sources”,然后就会出现对话框开始生成反编译后的代码压缩包,这个过程要好几分钟,不过因为不影响直接在jd-gui中查看jar包的源码,所以在对比代码的同时,不知道什么时候压缩包就生成了。
生成后的代码没有注释,但会包含如@Data等注解自动生成的初始化、getter和setter代码,也会有部分的代码优化,如省略不需要的变量等。
代码反编译很快,花时间最长的是要根据之前的备份,与反编译出来的代码进行逐个文件比对,加入新增类、更新一些代码,重新形成可用版本,因为反编译出来的代码毕竟可读性差很多,以及许多的注解变成了执行状态,因此不能拿来作为后续维护和迭代的基线。
二、微信小程序代码恢复
在恢复之前,还抱着万一的想法,印象中微信小程序开发工具好像有代码管理,而且每次上传都要扫描上传,是不是能直接恢复呢?打开工具的版本管理才发现自己想多了,需要先开通的。
微信小程序代码恢复主要包括两大步骤,第一步是下载微信小程序包,第二步是使用工具反编译出源码。
1、下载微信小程序包
(1)微信版本升级到3.8.0以上后,好消息就是小程序包不需要解密了,不过要找到微信小程序包存放的路径找了好一会儿,很多文章的目录都已经随着微信版本的升级过时了。
目前的版本小程序存放的路径是~/Library/Containers/com.tencent.xinWeChat/Data/.wxapplet/packages。
用自带终端app进入该目录,或者在Finder中按下shift command g,输入路径后可跳转到该目录。
目录下是所有的微信小程序包存放目录列表,目录名称是小程序的AppId。
(2)找到小程序的AppId,进入对应目录并将小程序包拷贝出来。
小程序查询AppId的方法:手机打开小程序 -> 右上角菜单 -> 点击小程序名称 -> 更多资料。
注意:这个目录下的小程序包是缓存信息,因此需要先访问一次小程序,才会找到对应AppId的目录。
2、反编译出源码
(1)下载工具wxappUnpacker
本以为是比较简单的事情,结果发现版本太多了,而且绝大部分版本都有Bug,主要是样式文件.wxss出不来,变成了.html,且用微信小程序开发者工具都打不开。
最后找到了一个百度云盘的工具包,https://pan.baidu.com/s/1NtCpQpqK4_29IbCMNRo3jA,提取码9999,解压后其中的wxappUnpacker.zip下可以找到好用的版本。
(2)安装Node环境并运行
// 在解压后的wxappUnpacker目录下
npm install
cp ../__APP__.wxapkg .
./bingo.sh __APP__.wxapkg
// 会将小程序代码解压到当前目录的子目录__APP__下面
// 如果bingo.sh不可执行,chmod x bingo.sh即可
解析出来的代码跟源代码有些差异,一是没有注释,二是进行过编译器优化,三是js中的临时变量、函数调用参数变量都变成了a、b、c等单字符变量。
所以对我来说需要进行最后一个代码补充环节,即参考反编译出来的代码,在之前的版本上参照反编译的代码重新写一遍,这样形成的版本才便于后续的维护和迭代。
三、前端代码恢复
前端代码线上只留下发布后混淆版本,目录和文件完全与开发时的结构、变量名称不同。
在网上百度了好一会儿,认为可以的文章都是使用reverse-sourcemap进行基于.js.map文件进行反编译,但绝大部分根本没说清楚是从哪里找到这些文件,很不巧,我发布到现网的目录中就没有map文件,看了不少网友的文章后终于把原理基本弄清楚,具体如下:
1、是否产生.map文件,取决于productionSourceMap属性,设置为true则在build打包时会生成.map文件,但对应的包的体积会变大,看到有网友在实际项目中,代码从2.8M变成9.6MB(未压缩的dist目录)。
当然,这里默认是使用webpack进行打包的。具体可通过代码在Vue的配置文件中进行控制,如下所示:
// 在vue.config.js中
module.exports = defineConfig({
productionSourceMap: false,
})
如果设置成true,则可以在发布包中的js目录下看到许多.js.map文件。
2、如果生成了map文件,那么可以根据map文件进行打包后的文件恢复,步骤包括:
(1)安装reverse-sourcemap;
(2)使用命令行进行单个文件恢复或脚本恢复整个目录;
// 1,安装reverse-sourcemap
npm install --global reverse-sourcemap
// 2.1 单文件恢复
// 将main.js文件反编译/反混淆回源码,并输出到sourcecode目录下
reverse-sourcemap -v dist/main.a8ebc11c3f03786d8e3b.js.map -o sourcecode
// 2.2 全目录恢复
// 将./static/js目录下所有的.js.map类型文件(递归)反编译/反混淆回源码,输出到origin目录下
reverse-sourcemap -o origin -v ./static/js
3、反思
其实map文件的初衷是为了在线上调试时,能够通过它来定位到底哪段代码有问题,但通过它却可以完全得到源码,所以在生产环境上正常情况下是不会有map文件的,否则就容易造成代码泄露,所以,这种方法大概率在实践中是无法使用的,只能说保留了极小的可能而已,而这可能性还建立在开发和运维的小伙伴出错的基础上,细想也是醉了。
而我虽然犯了迷糊弄丢了个人电脑上的代码,但在线上环境上并没有犯这么低级的错误,所以只能接受前端代码无法找回的现实,不过看过我文章的小伙伴应该知道,目前正在做基于Vben Admin框架进行前端重构,所以只能加快那边的进展,寄希望于在新框架完成之前不会有太多的前端业务需求或Bug了。
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved