微信小程序反编译完整教程(Windows 新手版)
本文基于一次真实的完整实操整理,包含全部步骤、踩过的 8 个坑及解决方案。 环境:Windows 11 + PowerShell 5.1 + Node.js v22 + 微信 4.x + 微信开发者工具 1.06
⚠️ 使用前必读:法律边界
只在以下场景使用:
- ✅ 反编译你自己开发的小程序(源码丢失、找回历史版本)
- ✅ 有书面授权的安全评估、渗透测试
- ✅ 学习研究小程序打包与编译原理
禁止:
- ❌ 反编译他人商业小程序并使用/发布其代码 ------ 涉及著作权侵权
- ❌ 破解付费功能、绕过业务校验
- ❌ 窃取他人业务逻辑或数据接口
反编译的技术门槛不高,但法律责任是真实的。本教程默认你在前两种合法场景下操作。
目录
- 原理速览
- 环境准备
- [第一步:定位 wxapkg 包](#第一步:定位 wxapkg 包 "#%E4%B8%89%E7%AC%AC%E4%B8%80%E6%AD%A5%E5%AE%9A%E4%BD%8D-wxapkg-%E5%8C%85")
- 第二步:判断加密状态
- 第三步:解密解包
- 第四步:导入开发者工具
- [常见问题大全(8 个真实坑)](#常见问题大全(8 个真实坑) "#%E4%B8%83%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E5%A4%A7%E5%85%A8")
- 方法论总结
- 工具清单
一、原理速览
1.1 小程序是怎么存在于你电脑上的
当你在微信里打开一个小程序,微信会把它的代码包下载到本地缓存,文件后缀是 .wxapkg。反编译就是把这个包还原成可编辑的工程源码。
获取 .wxapkg → 解密 → 解包 → 还原工程结构 → 导入开发者工具验证
1.2 包的结构
| 文件 | 含义 |
|---|---|
__APP__.wxapkg |
主包 --- 小程序主体代码 |
_pages_xxx_.wxapkg |
分包 --- 按页面拆分出去的部分 |
关键 :主包和分包必须同一版本、全部凑齐才能还原出完整工程。
1.3 源码去哪了
小程序编译后,源码被打散成这几个文件:
| 编译产物 | 还原出什么 |
|---|---|
app-service.js |
所有 .js 逻辑代码 |
page-frame.js / app-wxss.js |
所有 .wxml 视图 + .wxss 样式 |
app-config.json |
app.json 和各页面 .json 配置 |
其中 wxml 最难还原 ------ 它被编译成了名为 $gwx 的 JS 生成函数,需要反解视图树。这也是后面最大的坑所在。
二、环境准备
2.1 需要装的东西
powershell
node -v # 必需,>= 16
git --version # 必需
- Node.js :nodejs.org/ (建议 LTS)
- Git :git-scm.com/
- 微信开发者工具 :developers.weixin.qq.com/miniprogram...
- 电脑版微信:确保能正常登录
2.2 建立工作目录
powershell
New-Item -ItemType Directory -Force -Path "C:\work\decompile" | Out-Null
cd C:\work\decompile
后文都以 C:\work\decompile 为工作目录,可换成你自己的路径。
三、第一步:定位 wxapkg 包
3.1 先让小程序被缓存
打开电脑版微信 → 搜索并打开目标小程序 → 多点几个页面(确保主包和分包都加载过)→ 关闭。
不打开就没有缓存,后面搜不到任何东西。
3.2 找到缓存目录
不同微信版本路径不同:
| 微信版本 | 缓存路径 |
|---|---|
| 微信 4.x(个人版) | %APPDATA%\Tencent\xwechat\radium\users\<用户哈希>\applet\packages\<AppId>\<版本号>\ |
| 微信 3.x(老版本) | Documents\WeChat Files\Applet\<AppId>\ |
| 企业微信 | Documents\WXWork\<ID>\Applets\Applet\<AppId>\<版本>\ |
直接全盘搜索最省事:
powershell
Get-ChildItem -Path "C:\" -Recurse -Filter "*.wxapkg" -ErrorAction SilentlyContinue |
Select-Object FullName, Length, LastWriteTime |
Sort-Object LastWriteTime -Descending
搜索较慢,耐心等 1-3 分钟。也可以只搜微信目录:
powershell
Get-ChildItem -Path "$env:APPDATA\Tencent","$env:LOCALAPPDATA\Tencent" -Recurse -Filter "*.wxapkg" -ErrorAction SilentlyContinue |
Select-Object FullName, Length, LastWriteTime |
Sort-Object LastWriteTime -Descending
3.3 锁定你的小程序 AppId
缓存目录下有一堆 AppId(你用过的所有小程序)。用这个脚本按最近使用排序:
powershell
# 把 <用户哈希> 换成你实际的那一串
$root = "$env:APPDATA\Tencent\xwechat\radium\users\<用户哈希>\applet\packages"
Get-ChildItem $root -Directory | ForEach-Object {
$files = Get-ChildItem $_.FullName -Recurse -Filter *.wxapkg -ErrorAction SilentlyContinue
$latest = $files | Sort-Object LastWriteTime -Descending | Select-Object -First 1
[PSCustomObject]@{
AppId = $_.Name
包数量 = $files.Count
最近修改 = $latest.LastWriteTime
总大小KB = [math]::Round(($files | Measure-Object Length -Sum).Sum / 1KB)
}
} | Sort-Object 最近修改 -Descending | Format-Table -AutoSize
最近修改时间最新的那个,就是你刚打开的小程序。 AppId 也能在微信公众平台后台查到。
3.4 把包拷到工作区
powershell
$src = "$env:APPDATA\Tencent\xwechat\radium\users\<用户哈希>\applet\packages\<你的AppId>"
Copy-Item -Path $src -Destination "C:\work\decompile\<你的AppId>" -Recurse -Force
拷贝而不是直接操作原目录 ------ 避免误删微信缓存。
3.5 确认包的完整性
powershell
Get-ChildItem "C:\work\decompile\<你的AppId>" -Recurse -Filter *.wxapkg |
Select-Object @{n='版本目录';e={$_.Directory.Name}},
Name,
@{n='KB';e={[math]::Round($_.Length/1KB)}},
LastWriteTime |
Sort-Object 版本目录, Name | Format-Table -AutoSize
检查要点:
- 找到包含
__APP__.wxapkg且文件数最多的那个版本目录 - 主包 + 全部分包必须在同一个版本目录下
- 如果散落在多个版本目录(如
651、662),用最新且最全的那一套
四、第二步:判断加密状态
powershell
$pkg = "C:\work\decompile\<你的AppId>\<版本号>\__APP__.wxapkg"
$bytes = [System.IO.File]::ReadAllBytes($pkg)[0..15]
"前16字节(十六进制): " + (($bytes | ForEach-Object { $_.ToString('X2') }) -join ' ')
"前16字节(可见字符): " + ([System.Text.Encoding]::ASCII.GetString($bytes) -replace '[^\x20-\x7E]','.')
| 文件头 | 含义 | 处理方式 |
|---|---|---|
56 31 4D 4D 57 58(V1MMWX) |
PC 微信加密包 | 需要用 AppId 解密 |
第一字节 BE |
未加密标准包 | 可直接解包 |
为什么 AppId 是解密密钥的来源:PC 微信用 AppId 参与派生密钥。这也意味着 ------ 你必须知道 AppId 才能解密,天然限定在"你能识别的小程序"上。
五、第三步:解密解包
5.1 工具选择
| 工具 | 优点 | 缺点 |
|---|---|---|
| unveilr | 对各种 wcc 编译器版本兼容性最好,wxml 还原成功率高 | npm 包已下架,需从 fork 源码构建 |
| KillWxapkg | 开箱即用的 exe,自动化程度高 | 对老版本 wcc 的 wxml 还原会失败(见坑 #1) |
推荐:直接用 unveilr。 想先快速验证能否解密,可以先跑一遍 KillWxapkg。
5.2 方案 A:KillWxapkg(快速上手)
下载 :github.com/Ackites/Kil... → 下载 Windows amd64 版 → 改名为 KillWxapkg.exe 放到工作目录。
⚠️ 第三方开源二进制,建议先杀软扫描。
powershell
cd C:\work\decompile
.\KillWxapkg.exe -h # 先看参数
.\KillWxapkg.exe -id <你的AppId> `
-in "C:\work\decompile\<你的AppId>\<版本号>" `
-out "C:\work\decompile\output" `
-restore -pretty -noClean
| 参数 | 作用 |
|---|---|
-id |
AppId(解密密钥来源) |
-in |
输入目录(整个版本目录,主包分包一起) |
-out |
输出目录 |
-restore |
还原工程目录结构 |
-pretty |
美化代码 |
-noClean |
保留中间文件 (page-frame.js/app-wxss.js)------ 排查问题的关键,强烈建议加上 |
5.3 方案 B:unveilr(推荐,wxml 还原正确)
步骤 1:克隆源码
原仓库 r3x5ur/unveilr 已失效,npm 包也下架了(npm i -g unveilr 报 ENOVERSIONS),需要用 fork:
powershell
cd C:\work\decompile
git clone https://github.com/hzzheyang/unveilr-v2.0.0.git unveilr
备用 fork:
步骤 2:安装依赖
powershell
cd C:\work\decompile\unveilr
npm install --legacy-peer-deps --registry=https://registry.npmmirror.com
--legacy-peer-deps是必需的 ------ 项目的 rollup 版本和 rollup-plugin-terser 有 peer 冲突(见坑 #3)。
步骤 3:配置参数(重要!)
unveilr 用 ts-node 跑源码时会进入开发模式,直接忽略命令行参数(见坑 #4)。所以要把参数写进配置文件。
编辑 src\utils\getConfigurator.ts,把 wx: { ... } 那段改成:
typescript
wx: {
appid: '你的AppId',
format: false,
clearDecompile: true,
clearSave: true,
parse: true,
depth: 1,
output: 'C:/work/decompile/output',
packages: ['C:/work/decompile/你的AppId/版本号'],
},
format必须设为false! 设为true会格式化代码,把 wxml 表达式里的字符串折断成多行导致编译失败(见坑 #2)。路径用正斜杠
/,避免转义问题。
步骤 4:运行
powershell
cd C:\work\decompile\unveilr
npm run run
不要加任何命令行参数 ------ 参数已写死在代码里,加了反而会被当成路径。
步骤 5:验收(最重要的一步!)
别只看文件数量,一定要看内容:
powershell
$all = Get-ChildItem "C:\work\decompile\output" -Recurse -Filter *.wxml -File
"总数: " + $all.Count
"空的: " + ($all | Where-Object Length -eq 0).Count
"平均KB: " + [math]::Round(($all | Measure-Object Length -Average).Average / 1KB, 1)
powershell
# 抽查真实内容
Get-Content "C:\work\decompile\output\pages\home\index.wxml" -TotalCount 10 -Encoding UTF8
| 现象 | 判断 |
|---|---|
空文件 0 个,平均 2-5 KB,内容是 <view class="..."> 标签树 |
✅ 成功 |
大量 0 字节,或内容是 <text>页面路径</text> |
❌ 失败(占位符,见坑 #1) |
六、第四步:导入微信开发者工具
6.1 导入前的必要修复
反编译产物是编译后的成品,有些配置是运行时格式,需要转回源码格式。用这个脚本一次修完:
powershell
$root = "C:\work\decompile\output"
$utf8 = New-Object System.Text.UTF8Encoding $false
# --- 1. app.json 三处修复 ---
$appPath = Join-Path $root "app.json"
$app = Get-Content $appPath -Raw -Encoding UTF8 | ConvertFrom-Json
# 1a. componentFramework 从对象改成字符串
if ($app.componentFramework -and $app.componentFramework -isnot [string]) {
$app.componentFramework = "exparser"
}
# 1b. plugins 里删掉运行时字段 subpackage
if ($app.plugins) {
foreach ($p in $app.plugins.PSObject.Properties) {
$p.Value.PSObject.Properties.Remove('subpackage')
}
}
# 1c. pages 里移除插件页面
$app.pages = @($app.pages | Where-Object { $_ -notlike '__plugin__*' })
[System.IO.File]::WriteAllText($appPath, ($app | ConvertTo-Json -Depth 100), $utf8)
"app.json 已修复"
# --- 2. project.config.json:关闭所有二次编译 ---
$pcPath = Join-Path $root "project.config.json"
if (Test-Path $pcPath) {
$pc = Get-Content $pcPath -Raw -Encoding UTF8 | ConvertFrom-Json
$pc.setting.es6 = $false
$pc.setting.postcss = $false
$pc.setting.minified = $false
$pc.setting.enhance = $false
$pc.setting.minifyWXML = $false
# 关键!防止未引用文件被剔除
$pc.setting | Add-Member -NotePropertyName "ignoreUploadUnusedFiles" -NotePropertyValue $false -Force
$pc.setting | Add-Member -NotePropertyName "ignoreDevUnusedFiles" -NotePropertyValue $false -Force
[System.IO.File]::WriteAllText($pcPath, ($pc | ConvertTo-Json -Depth 100), $utf8)
"project.config.json 已修复"
}
# --- 3. 移走插件残留目录 ---
foreach ($dir in @("__plugin__", "wxlive-components")) {
if (Test-Path "$root\$dir") {
Move-Item "$root\$dir" "C:\work\decompile\${dir}_backup" -Force
"$dir 已移出备份"
}
}
wxlive-components是直播插件的组件目录,如果你的小程序没用直播插件,可能不存在,脚本会自动跳过。
6.2 导入
- 打开微信开发者工具 → 导入项目
- 目录 :
C:\work\decompile\output - AppID:填你的 AppId
- 后端服务:选「不使用云服务」
- 导入后进 详情 → 本地设置 ,勾选:
- ✅ 不校验合法域名、web-view、TLS 版本以及 HTTPS 证书
- ✅ 关闭 ES6 转 ES5
- ✅ 关闭上传代码时样式自动补全
- ✅ 关闭上传代码时自动压缩
修改了
project.config.json后,必须重新打开项目才生效。
七、常见问题大全
以下 8 个坑全部来自真实实操,按遇到顺序排列。
坑 #1:wxml 全是空文件或占位符 ⭐ 最关键
现象:
wxml 总数: 347 空的: 210
打开非空的 wxml,内容却是:
html
<!--pages/test/settings.wxml--><text>pages/test/settings.wxml</text>
日志里明明满屏 Saved file: xxx.wxml,看起来一切正常。
原因:
小程序的 wxml 被编译成名为 $gwx 的 JS 生成函数,存放在 page-frame.js(分包)或 app-wxss.js(主包)里。
某些编译器版本会给这个函数加混淆后缀 ,变成 $gwx_XC_29、$gwx_XC_31 这类变体:
javascript
// app-wxss.js 里的真实形态
var gf = $gwx_XC_29('./components/common/card1.wxml');
KillWxapkg 只匹配标准的 $gwx,遇到变体名找不到 → 不报错,而是兜底写占位符 。这是最阴险的地方:失败被伪装成了成功。
如何确认:
powershell
Select-String -Path "C:\work\decompile\output\app-wxss.js" -Pattern 'gwx_XC_\d+' | Measure-Object
如果匹配到几百上千处,说明用的就是变体格式。
解决:
换 unveilr 。它对各种 wcc 版本和 $gwx 变体的兼容性好得多。同一批包的实测对比:
| 工具 | wxml 结果 |
|---|---|
| KillWxapkg v2.4.1 | 210 空 + 137 占位符 = 0 个真实 |
| unveilr v2.0.0 | 366 个全部真实,平均 3.5 KB |
教训:
工具跑通 ≠ 还原成功。永远打开文件看内容,不要只看文件数量和日志。
坑 #2:wxml 编译报 unexpected \ 或字符串跨行
现象:
bash
[WXML 文件编译错误] ./components/actionTips/infoTips.wxml
Bad value with message: unexpected `\` at pos103.
查看报错处:
html
>{{type==1?self?'已通过认证 \n 会被推荐':'该用户已通过
\n 认证,会被优先推荐':...}}
单引号字符串跨越了多行。
原因:
unveilr 的 format: true 会格式化代码,把长表达式按行宽折行 ------ 结果把字符串字面量也折断了。JS/WXML 的字符串不能跨行。
解决:
改 getConfigurator.ts,把 format 设为 false,重新解包:
typescript
format: false,
不要试图在坏文件上做文本替换修补 ------ 实测不但治标不治本,还会引入编码问题(见坑 #7)。
教训:
格式化是给人读的,不是给机器跑的。反编译先求正确,再求可读。
想要可读的代码?先跑通,之后单独对
.js跑 prettier,别碰.wxml。
坑 #3:npm install 报 ERESOLVE 依赖冲突
现象:
sql
npm error code ERESOLVE
npm error Found: rollup@3.20.5
npm error peer rollup@"^2.0.0" from rollup-plugin-terser@7.0.2
原因:
老项目的构建工具版本对不上。这些只是构建期依赖,不影响工具运行。
解决:
powershell
npm install --legacy-peer-deps --registry=https://registry.npmmirror.com
坑 #4:unveilr 的 --help 报错,命令行参数无效
现象:
powershell
npm run run -- --help
# ExtractorError: File C:\...\unveilr\files cannot be extracted!
莫名其妙去解一个叫 files 的路径。
原因:
读一下 src/utils/isDev.ts:
typescript
export function isDevelopment() {
return PathController.make(process.argv[1]).suffixWithout === 'ts'
}
只要入口文件后缀是 .ts,就判定为开发模式 。而开发模式下,getConfigurator.ts 直接返回硬编码配置(其中 packages: ['files']),完全跳过命令行解析。
用 ts-node 跑源码,入口正好是 src/index.ts → 命令行参数全部作废。
解决:
两条路:
- 改配置(推荐) :把参数写进
getConfigurator.ts的 dev 分支,不加任何命令行参数直接跑 - 构建后跑 :
npm run build生成dist/index.js,再用node dist/index.js wx -i <appid> -o <输出> <包目录>
教训:
读工具源码比试参数快。 三分钟读懂
getConfigurator.ts就能定位,盲试参数可能试一整天。
坑 #5:app.json: componentFramework 字段需为 string
现象:
csharp
[app.json 文件内容错误] app.json: componentFramework 字段需为 exparser,glass-easel
实际值是个对象:
json
"componentFramework": { "allUsed": ["exparser"], "default": "exparser" }
原因:
小程序有两套 json 格式:
| 格式 | 用途 | |
|---|---|---|
源码 app.json |
"componentFramework": "exparser" |
开发者手写 |
编译产物 app-config.json |
{ "allUsed": [...], "default": "..." } |
运行时用 |
反编译是从编译产物逆推源码,这个字段没做格式转换。同类问题还有 plugins.subpackage。
解决:
json
"componentFramework": "exparser",
plugins 里删掉 "subpackage": "__APP__" 这一行:
json
"plugins": {
"livePlayerPlugin": {
"version": "1.3.5",
"provider": "wx2b03c6e691cd7370"
}
}
坑 #6:插件组件找不到 / __plugin__ 报错
现象:
css
["usingComponents"]["page-live-player"]: 在 .../wxlive-components/page-live-player/ 路径下未找到组件
进去一看,该目录只有 .json,没有 .wxml/.js/.wxss。
原因:
第三方插件(如微信官方直播插件 wx2b03c6e691cd7370)的代码不会明文缓存在本地 ------ 微信按需从服务器下发。你反编译只能拿到配置骨架。
| 存在形式 | 能反编译吗 | |
|---|---|---|
| 你的业务代码 | 明文在 wxapkg 里 | ✅ |
| 第三方插件 | 服务器按需下发 | ❌ |
插件本来就不该作为源码存在于工程里 ------ app.json 的 plugins 字段是依赖声明,类似 package.json 写依赖名而不把 node_modules 塞进仓库。
解决:
- 确认
app.json里有plugins声明(通常反编译已带出来) - 从
pages数组删掉所有__plugin__/...开头的页面 - 移走
__plugin__和wxlive-components目录
判断某个目录是不是"死代码"的方法:
powershell
Select-String -Path "C:\work\decompile\output\**\*.json" -Pattern "wxlive-components" | Select-Object -First 5
无输出 = 没人用 = 可以安全移走。
这个方法比闷头修语法高效得多。遇到某文件编译不过,先问"它到底有没有人用"。
坑 #7:PowerShell 读写中文文件变乱码 ⭐ 高频
现象 1 --- 明明正常的 json 报格式错误:
yaml
ConvertFrom-Json : 传入的对象无效
"desc": "浣犵殑浣嶇疆淇℃伅灏嗙敤浜庡皬绋嬪簭...绀?
现象 2 --- 用脚本改过文件后,编译报乱码字符 ?(U+FFFD)。
原因:
Windows PowerShell 5.1 的 Get-Content 默认按系统 ANSI(GBK)解码,而反编译产物是 UTF-8。UTF-8 中文按 GBK 解码会产生"半个字符",甚至把后面的引号一起吞掉 → json 看起来像是断了。
写入同理:Set-Content -Encoding UTF8 会写入带 BOM 的 UTF-8。
解决:
读取必须显式指定编码:
powershell
Get-Content "app.json" -Raw -Encoding UTF8 | ConvertFrom-Json
写入用 .NET 方法(无 BOM,最保险):
powershell
$utf8 = New-Object System.Text.UTF8Encoding $false
[System.IO.File]::WriteAllText($path, $content, $utf8)
读文件同样推荐 .NET 方法:
powershell
$content = [System.IO.File]::ReadAllText($path) # 默认按 UTF-8
记死这条:PowerShell 5.1 处理反编译产物,读加
-Encoding UTF8,写用 .NET 方法。
坑 #8:module 'npm/xxx' is not defined ⭐ 最隐蔽
现象:
swift
Error: module 'npm/@tarojs/async-await/index.js' is not defined,
require args is './npm/@tarojs/async-await/index.js'
Page "pages/home/index" has not been registered yet.
文件明明存在,内容也是合法 JS:
powershell
Test-Path "C:\work\decompile\output\npm\@tarojs\async-await\index.js" # True
原因:
微信开发者工具有个默认开启的设置 ignoreUploadUnusedFiles (默认 true),会做依赖分析、剔除"未被引用"的文件。
反编译出的 js 是压缩后的:
javascript
!function(e){...}(require)
静态分析识别不出这种动态 require,于是判定"没人用这个文件" → 编译时直接剔除 → 运行时 not defined。
app.js 在第一行 require 就挂掉,后面所有页面注册全都没执行,所以还会连带报 Page has not been registered yet。
解决:
在 project.config.json 的 setting 里加两个字段:
json
"ignoreUploadUnusedFiles": false,
"ignoreDevUnusedFiles": false
改完重新打开项目。
教训:
这类"工具的善意优化反而破坏还原产物"的坑最花时间 ------ 因为文件就躺在磁盘上,内容也没问题,一切看起来都对。
附:其他可能遇到的小问题
| 报错 | 原因 | 解决 |
|---|---|---|
WXS 编译错误 Unexpected token } |
WXS 语法比 JS 严格,不支持尾随逗号等 | 去掉 ,} 里的逗号;或确认该组件是否根本没人用,直接移走 |
npm i -g unveilr 报 ENOVERSIONS |
原 npm 包已下架 | 从 GitHub fork 克隆源码构建 |
--help 参数无效 |
npm run 吞参数 + 开发模式忽略参数 | 见坑 #4 |
| 分包解出来不完整 | 主包分包版本不一致 | 确保同一版本目录下的包全部凑齐 |
| 找不到任何 wxapkg | 小程序没在电脑版微信打开过 | 先打开并浏览几个页面 |
__route__ is not defined |
app.js 挂掉导致页面未注册 | 通常是坑 #8 的连带现象,修好 #8 即可 |
八、方法论总结
完整流程
scss
① 定位缓存 微信4.x: %APPDATA%\Tencent\xwechat\radium\users\<hash>\applet\packages\<AppId>\<版本>\
↓
② 判断加密 文件头 V1MMWX = 加密(AppId 是密钥来源) / 0xBE = 未加密
↓
③ 凑齐一套 同版本目录下 __APP__ + 全部 _pages_* 必须完整
↓
④ 解密解包 unveilr(format: false)/ KillWxapkg(-noClean)
↓
⑤ 验收内容 ★ 打开文件看内容,别只看文件数量 ★
↓
⑥ 修复配置 运行时格式 → 源码格式,关掉一切二次编译
↓
⑦ 导入验证 微信开发者工具能编译运行 = 真正成功
三条核心经验
1. 工具跑通 ≠ 还原成功
日志满屏 Saved file、文件数量对得上,内容却可能全是占位符。工具的兜底逻辑会把失败伪装成成功。 唯一可靠的验收方式是打开文件看内容。
2. 关掉一切"聪明"功能
你手里的是编译后的成品,不是源码。任何二次加工都是破坏:
| 功能 | 后果 |
|---|---|
format: true(反编译工具) |
折断 wxml 字符串 |
es6: true(开发者工具) |
重新 babel 编译,打乱模块 ID |
minified: true |
二次压缩,可能破坏结构 |
ignoreUploadUnusedFiles: true |
剔除静态分析识别不出的文件 |
统一原则:不转译、不压缩、不美化、不剔除。
3. 读源码比试参数快
--help 失灵时,直接读 getConfigurator.ts 和 isDev.ts,三分钟定位到"开发模式忽略命令行参数"。
同理,遇到某文件编译不过,先 grep 一下有没有人引用它 ------ 没人用就直接移走,比修语法快得多。
保留中间产物
解包时务必加 -noClean(KillWxapkg)或保留 page-frame.js / app-wxss.js。这些是 wxml 的原料,一旦出问题,有它们才能定位是"解析器不认变体名"还是别的原因。删了就只能重来。
九、工具清单
| 工具 | 地址 | 用途 |
|---|---|---|
| unveilr | 原仓库 github.com/r3x5ur/unve... (已失效) fork: github.com/hzzheyang/u... | 解密解包,wxml 还原成功率最高 |
| KillWxapkg | github.com/Ackites/Kil... | 开箱即用,自动化程度高 |
| wxapkg GUI | github.com/wux1an/wxap... | 图形界面,适合快速尝试 |
| wxappUnpacker | github.com/Ryan-Miao/w... | 经典 Node.js 脚本,适合学原理 |
| 微信开发者工具 | developers.weixin.qq.com/miniprogram... | 验证还原结果 |
附录:完整命令速查
powershell
# ===== 1. 找包 =====
Get-ChildItem -Path "C:\" -Recurse -Filter "*.wxapkg" -ErrorAction SilentlyContinue |
Select-Object FullName, Length, LastWriteTime | Sort-Object LastWriteTime -Descending
# ===== 2. 验加密 =====
$pkg = "路径\__APP__.wxapkg"
$bytes = [System.IO.File]::ReadAllBytes($pkg)[0..15]
"HEX: " + (($bytes | ForEach-Object { $_.ToString('X2') }) -join ' ')
# ===== 3. 拷贝到工作区 =====
Copy-Item -Path "缓存路径\<AppId>" -Destination "C:\work\decompile\<AppId>" -Recurse -Force
# ===== 4. 安装 unveilr =====
git clone https://github.com/hzzheyang/unveilr-v2.0.0.git unveilr
cd unveilr
npm install --legacy-peer-deps --registry=https://registry.npmmirror.com
# 编辑 src\utils\getConfigurator.ts 填参数(format: false!)
npm run run
# ===== 5. 验收 wxml =====
$all = Get-ChildItem "C:\work\decompile\output" -Recurse -Filter *.wxml -File
"总数: " + $all.Count + " 空的: " + ($all | Where-Object Length -eq 0).Count
Get-Content "C:\work\decompile\output\app.json" -Raw -Encoding UTF8 | ConvertFrom-Json | Out-Null
# ===== 6. 修复配置(见 6.1 的完整脚本) =====
# ===== 7. 导入开发者工具,关闭所有编译优化 =====
结语
反编译没有"一条命令跑通"的神话。这次实操里,从第一次解包到最终跑起来,一共踩了 8 个坑 ------ 工具版本、编译器变体、依赖冲突、开发模式陷阱、编码问题、配置格式、插件残留、静态分析剔除。
每个坑的排查方法都比坑本身更值钱:
- 打开文件看内容,而不是相信日志
- 保留中间产物,给排查留后路
- 读工具源码,而不是盲试参数
- grep 引用关系,而不是闷头修语法
学会这些,下次遇到新工具、新版本、新报错,你也能自己走通。
本文档基于真实实操整理,仅用于学习研究与自有项目的源码找回。请遵守法律法规。