解包 Electron 的 app.asar 只有部分文件?六个原因

Electron 应用的 resources/app.asar 解开看,只有一部分源码 / 资源——很多明明代码里 require 过的模块或者用到的图片、模型完全找不到。不是解包工具坏,是 Electron 应用故意这么组织的。

1. 文件在 app.asar.unpacked

最常见。resources/ 目录下有两个:

resources/
├── app.asar               # 归档
└── app.asar.unpacked/     # 不归档,直接文件系统

electron-builder / electron-packagerasarUnpack 配置,指定哪些文件不打进 asar。原因:

  • 原生模块 .node:Node 加载 native addon 只认真实文件路径
  • 可执行文件ffmpeg.exe、外部工具)
  • 大文件(模型、字体、图片)——放 asar 会导致启动时全部读到内存
  • 需要写入的资源(缓存、配置模板)

解决:同时解 asar 和 unpacked 目录,才能拿全资源。

npx asar extract app.asar out/
# 然后手动合并 app.asar.unpacked 里的内容

2. 运行时动态下载

很多 AI / IDE / 客户端首次启动会拉模型或 SDK:

  • Cursor / VSCode 下载语言服务
  • Notion / Figma 缓存 web 资源
  • Whisper.cpp 下运行 GGUF 模型
  • 客户端更新组件到 %AppData%

常见落地目录:

Windows

%APPDATA%\<AppName>\
%LOCALAPPDATA%\<AppName>\

macOS

~/Library/Application Support/<AppName>/
~/Library/Caches/<AppName>/

Linux

~/.config/<AppName>/
~/.cache/<AppName>/

这些目录不属于 asar,别在 asar 里找。

3. webpack chunk 打包 / 混淆

代码里看到:

require("./modules/wallet.js")

在 asar 里 modules/ 目录空空如也。原因是打包时被 webpack 摊平:

(() => {
  var __webpack_modules__ = {
    123: (e, t, r) => { /* wallet.js 的内容 */ },
    456: (e, t, r) => { /* something else */ },
  };
  // ...
})();

wallet.js 变成模块 ID 123,塞进主 bundle。名字都没了,找源文件是找不到的。

恢复思路

  • webcrackreact-native-decompiler 尝试还原模块结构
  • source map 有的话直接 .map 文件恢复
  • 主 bundle 里搜函数名 / 字符串手工定位

4. asar 完整性校验

Electron 的 --asar-integrity 特性(v22+)——启动时校验 asar 的 SHA-256,被改过就直接崩:

Integrity check failed: 0x...

有的应用还会自校验:

const hash = crypto.createHash("sha256").update(fs.readFileSync(asarPath)).digest("hex");
if (hash !== EXPECTED_HASH) app.exit();

改过 asar 塞回去,应用启动就退。想跑起来得同时改校验逻辑。

5. 资源加密

商业 Electron 应用常见做法:

方式 A:启动时解密

const encryptedBuffer = fs.readFileSync("./data.bin");
const source = decrypt(encryptedBuffer, KEY);
new Function(source)();     // 或 eval, vm.runInNewContext

asar 里只能看到加密后的 blob。想读得先拿到 KEY——通常在主 bundle 里硬编码或经过混淆。

方式 B:V8 Bytecode(bytenode)

xxx.jsc
xxx.bin

这些是 bytenode 编译的 V8 字节码,普通反编译工具还原不了源码。只能在运行时逆向。

6. 解包工具版本太老

老的第三方解包工具不支持新版 asar 格式:

  • 新版 asar header 有 offset
  • 大文件跨块
  • unicode 文件名编码变化

永远优先用官方

# 官方 CLI
npx @electron/asar extract app.asar out/
npx @electron/asar list app.asar

或者装全局:

npm i -g @electron/asar
asar extract app.asar out/

一张排查表

看到”资源缺”,按这个顺序查:

现象大概率原因
.node / ffmpeg 找不到app.asar.unpacked
模型 / 大图找不到unpacked 或运行时下载
require 的模块找不到源文件webpack 打包混淆
.jsc / .bin 打不开V8 bytecode 或加密
改了 asar 应用启动就退完整性校验
一部分目录空 / 文件小解包工具太老,换 @electron/asar

一句话总结

Electron 解包”少东西”是常态。先看 app.asar.unpacked、再看 %AppData% 用户目录、再考虑 webpack chunk / 加密 / bytecode。用 @electron/asar 官方工具,别用老的第三方版本。