
最近把 e0e1-wx 更新了一把顺手把手头几个小程序包重新反编译测试了一遍。这个工具一直是微信小程序逆向这一块比较能打的选手更新之后在解密逻辑和还原率上都有明显变化值得重新梳理一下完整的用法。下面这篇东西不搞虚的从环境准备到实操命令再到踩坑记录和结果利用全是我自己实测过的流程想拿它做代码研究、数据分析和二次开发的可以直接照着走。微信小程序反编译这件事说穿了就是把线上跑的wxapkg包还原成浏览器能读、开发者工具能打开的源码工程。它解决的痛点是你手上只有一个小程序的线上包想研究它的页面结构、接口逻辑、组件写法或者单纯想把某个已经无法维护的旧项目捞回来但原始源码已经丢了。e0e1-wx 就是这个流程里最核心的那把刀适合前端开发者、小程序安全研究者和做竞品分析的工程师。下面开始讲正事。1. 更新核心解读这版到底改了什么1.1 从 wxapkg 到源码的完整链路先说基础原理因为很多人第一次用这个工具容易卡在为什么别人能还原我却老是报错。微信小程序发布到线上之后代码不是以源码明文形式存在的而是被编译打包成了一种专有的二进制格式wxapkg。这个包里混合了三类东西编译后的 JS 代码经过压缩和混淆处理WXML 模板数据编译成了中间表示形式不再是直接的 XML 标签WXSS 样式、JSON 配置、图片资源等静态文件老一代工具比如 wxappUnpacker 处理的是早期版本很多新版本小程序的包做了加密处理直接用老工具解会得到一堆乱码或者直接报错。e0e1-wx 更新后最大的变化就是内置了解密模块能自动识别包是否走加密逻辑然后通过内置规则还原出可解析的文件结构。这一步完成后剩下的工作就是拆包、还原目录结构、美化代码。我举个例子方便理解可以把反编译想象成拆快递。外层的纸箱是wxapkg的二进制封装里面的填充物是加密数据而内层真正值钱的东西是压缩后的 JS 和模板文件。e0e1-wx 更新后相当于多了一个智能开箱器会用合适的工具拆掉外层再把泡沫掰开把你要的东西完整取出来。1.2 新版本更新的几个关键点我这次实测下来觉得这版最值得关注的更新是以下四个方向自动解密支持新版本对近几年发布的小程序包加密格式兼容性大幅提升不再需要额外提取 key 或手动拼接解密脚本命令里加个参数就能自动处理。分包还原优化很多小程序用了分包加载机制主包和分包分散在多个wxapkg里。老版本需要分开还原再手动合并新版本支持自动索引分包还原时能拼出一个相对完整的工程结构。WXML 还原精度提升之前版本还原出来的 WXML 偶尔会出现标签丢失或属性错位的问题更新后对模板指令的解析更准wx:for、wx:if这类指令基本能保持一致。Windows 路径兼容修复这个是我个人比较高兴的之前写好的脚本里因为文件名太长或者路径含特殊字符在 Windows 下总是中断新版算是把这个坑填了。还要提醒一句工具的更新不等于全自动。市面上没有哪个反编译工具能做到 100% 还原出和开发时一模一样的工程。e0e1-wx 的定位是把还原率做到行业里的第一梯队但混淆很重的代码、动态拼接的组件名、通过字符串拼接生成的 WXML 标签这些在还原后还是需要人工修复。提前有这个预期后面用起来就不会心理落差太大。1.3 谁能用、怎么用才合适聊完原理说说这个东西适合谁。第一类是前端开发工程师不管是出于学习目的想看别人怎么写复杂组件还是想考古自己两年前做的但已经丢失源码的旧项目反编译都是最后的救命稻草。第二类是安全测试人员做小程序渗透测试或者合规审计时经常要查看逻辑代码反编译能大幅提高分析效率。第三类是产品和技术教研人员想拆解某个行业头部小程序的实现方案作为参考。同时必须把边界说清楚。反编译工具本身是中性技术但使用对象和使用目的决定了它是否合规。拿着它去扒别人未授权的小程序核心逻辑、复制接口实现、直接抄袭商业产品这是明确有法律风险的。我自己的原则是只用于已授权项目、自己开发的代码恢复、公开的学习研究样本以及有正规合同支撑的合规审计。这个原则建议每个人都记住技术学起来没有错用歪了就是另一回事了。2. 环境准备与安装实测2.1 运行环境与前置依赖e0e1-wx 是个跨平台工具Windows、macOS、Linux 都能跑但前提是机器上得有 Node.js 环境。建议装 Node.js 14 以上的版本我测试时用的是 16.x运行很稳定。装 Node 的时候注意两点不要图省事用系统自带的旧版 node版本太低会导致工具运行时缺少 ES Module 特性支持装完后先在终端里跑一下node -v确认版本号正常再继续另外需要一份自己手头的小程序包。包怎么来的正规渠道有这么几种自己开发的小程序通过开发者工具上传后的产物备份、有授权协议的测试样本、公开漏洞库或教学项目里附带的样本包。具体的获取过程各显神通我在这里不展开讲重点说拿到包之后怎么处理。2.2 安装步骤与验证安装这块直接走 npm 就行命令很简洁npm install -g e0e1-wx装完之后验证一下e0e1-wx --version如果终端能打印出版本号说明核心模块已经就位。这里有个常见问题Windows 下如果提示e0e1-wx 不是内部或外部命令多半是 npm 全局安装目录没加到系统 PATH 里。解决办法是把 npm 的 prefix 目录找出来手动加进环境变量或者干脆用 npx 方式调用npx e0e1-wx --version我个人习惯用 npx因为这样永远不会遇到全局环境污染导致版本冲突的问题尤其是在一台机器上要跑多个 Node 工具的场景下。2.3 文件命名与目录规范准备输入文件的时候有个小技巧把wxapkg文件重命名成带有 appid 或者项目名的格式再操作比如wx1234567890abcdef__myapp.wxapkg。这样做的原因是还原出来的工程目录会默认沿用输入文件名一个清晰的名字能让你在反编译多个小程序后快速找到对应项目。目录结构建议单独建一个存放区wechat-unpack-workspace/ ├── input/ # 存放所有待处理的 wxapkg 包 ├── output/ # e0e1-wx 输出还原结果 └── temp/ # 中间文件和解密缓存别小看这点整理工作实际项目里当你同时研究十来个包的时候一个规范的目录结构能省掉大量查找时间。3. 完整反编译实操流程3.1 解密前置操作识别包类型拿到 wxapkg 文件后第一步不是急着跑命令而是先识别包的加密状态。用文本编辑器或者命令行 hexdump 工具打开文件头观察前几个字节的特征。未加密的老版本包文件头通常是常见的可读字符串或者固定的解包标识加密后的新包文件头看上去是一段无明显规律的十六进制数据。e0e1-wx 更新后的自动识别能力能省掉手动判断这一步但了解判断原理依然有用尤其是在工具识别出错的时候你可以自己判断到底走哪条处理链路。这里插一句实操经验如果你发现一个包工具识别不了先看它的版本号。小程序基础库版本和包加密策略是有对应关系的老工具配老包新工具配新包拿新工具解老包可能会因为兼容逻辑太多而误判加密。3.2 命令行参数详解与全局配置这次更新之后命令行参数做了一次大的梳理我实测过后把最常用的参数整理成表参数作用使用说明-i, --input指定输入文件路径必填指向待处理的 wxapkg 文件-o, --output指定输出目录可选默认在当前目录下生成同名文件夹-d, --auto-decrypt自动解密遇到加密包时启用内置解密逻辑--merge-subpackages合并分包自动搜索同目录下分包并整合到主工程-p, --pretty美化代码还原后的 JS 代码做格式化处理--no-obfuscation-detect关闭混淆检测处理混淆代码时可能用到的开关-v, --verbose输出详细日志排查问题时强烈建议开启一个最基础的完整命令长这样e0e1-wx -i ./input/wx1234567890abcdef__myapp.wxapkg -o ./output/ -d -p --merge-subpackages -v说说这几个参数背后的逻辑。-d启用自动解密这是新版核心卖点遇到加密包直接走内置规则--merge-subpackages会扫描输入文件同级目录下的分包包比如名字带__sub1、__sub2前缀的那些文件-p做代码美化方便阅读-v输出详细日志这样每一步干了什么都看得清楚排错时不至于两眼一抹黑。3.3 核心实操跑一次全流程下面用我自己的一个测试包走一遍完整流程。假设我手头有wxabcdef123456__demo.wxapkg尺寸大概 3.8MB放置在input目录下。第一步执行反编译e0e1-wx -i ./input/wxabcdef123456__demo.wxapkg -o ./output/ -d -p --merge-subpackages -v执行过程中工具会先做包类型识别然后走解密逻辑接着解包还原最后输出工程结构。全程耗时取决于包的大小和内部文件数量3.8MB 的包在我机器上大概 10 秒出结果。第二步查看输出目录output/ └── wxabcdef123456__demo/ ├── app.js ├── app.json ├── app.wxss ├── project.config.json ├── pages/ │ ├── index/ │ │ ├── index.js │ │ ├── index.wxml │ │ └── index.wxss │ └── logs/ │ ├── logs.js │ ├── logs.wxml │ └── logs.wxss ├── components/ │ ├── custom-nav/ │ │ ├── custom-nav.js │ │ ├── custom-nav.json │ │ ├── custom-nav.wxml │ │ └── custom-nav.wxss ├── utils/ │ ├── util.js │ └── request.js ├── images/ └── subpackages/看到app.json和pages目录说明核心还原已经成功。这时用微信开发者工具导入output/wxabcdef123456__demo这个目录正常情况下能直接编译预览不过有概率会遇到一些小问题后面会说。3.4 高还原率的小技巧实测经验告诉我想让还原率更高有几个细节值得注意。第一分包文件不要手动改名。e0e1-wx 是根据文件名里的包标识自动关联分包和主包的你要是手欠把分包名改了合并逻辑就识别不出来了。正确做法是把所有包文件原封不动放在同一个目录下保持原始命名。第二--pretty参数建议默认加上。不美化的话还原出来的 JS 虽然语义没变但阅读体验极差尤其是线上包都经过压缩所有代码挤在一行里人眼根本没法看。第三如果遇到命令行卡住不动先按 CtrlC 停掉然后用-v参数重新跑。详细日志能看到它卡在哪个环节绝大多数情况是某个分包文件损坏或者路径里有中文导致编码问题。搞清楚卡点再针对处理比盲目多跑几遍有用得多。4. 还原后代码的利用与二次开发4.1 解读还原产物从文件到真实逻辑反编译只是一半工作剩下的一半是读懂还原出来的代码。很多人拿到还原结果面对几百个 JS 文件一脸茫然不知道从哪里看起。我的习惯是先看app.json这是整个小程序的地图上面注明了每个页面的路由、窗口样式、分包配置。通过app.json把整体框架在脑子里搭起来再按页面逐个击破。接下来重点看utils目录下的公共模块比如request.js、util.js这些文件里通常藏着接口请求封装、鉴权逻辑、公共函数。理解这些之后再回到具体页面基本上就能串起来整个业务链路了。一个小提示反编译出来的 JS 代码里混淆后的变量名大多是a、b、c或者_0x1a2b这种格式读的时候不要被吓到。优先关注函数调用关系、接口 URL、数据处理的逻辑分支而不是纠结单个变量名。变量名只是一个代号逻辑关系才是核心资产。4.2 手动清理与修复常见点还原结果一般不会完美大概率要手动修几个地方。最常见的三类问题绝对路径和相对路径错乱。分包里的资源路径还原后偶尔会带上绝对路径前缀导致开发者工具里图片加载不出来。需要手工调整为相对路径。动态组件注册丢失。如果原项目用了require方式动态加载组件或者插件还原后页面 JSON 文件里的usingComponents配置可能会缺项表现为组件空白或报错。修复方式是在对应页面的 json 文件里补上组件路径。ES6 转 ES5 的兼容问题。线上包在发布时通常做了语法降级还原出来的代码反而比较保守。这不算 bug但如果你打算在此基础上二次开发建议顺手升级成现代写法后续维护会舒服很多。修复时有一个特别烦人的点WXML 里如果用了自定义事件传参比如>