本文是对 Cracking Electron apps open 的整理与翻译。
内容结构概览
- 为什么要拆 Electron 应用:为了从 draw.io desktop 中取出 HTML/JS/CSS 资源,用于自己的图表渲染流水线。
- Electron 应用的核心模式 :外层是各平台安装包,内层通常有
resources/app.asar。 - Windows Installer :看起来是
.exe,实际是 NSIS 安装器,里面再包了一层.7z。 - Windows No Installer:名字叫 no installer,但本质仍然是 NSIS 自解压包。
- macOS Universal DMG :DMG 也能从 Linux 上用归档工具打开,最终同样找到
.asar。 - Linux deb :deb 本质是
ar归档,真正应用内容在data.tar.xz里。 - Linux rpm :rpm 解开后通常进入 cpio,再找到 Electron 的
app.asar。 - Linux AppImage :单文件应用镜像,仍能直接看到
resources/app.asar。 - Linux snap:通过 snap store API 找下载地址,snap 本质是 SquashFS 文件系统。
- Chrome OS / CRX:不是 Electron 应用,而是浏览器扩展;CRX 像"前面带额外头部的 zip"。
- ASAR 的意义:Electron 用它把大量小文件合成一个归档,绕开旧 Windows 路径/小文件性能问题。
- Figma 案例 :macOS 下载的 2MB DMG 只是下载器,真正应用地址藏在
Info.plist中。 - Figma 的 native 模块 :实际包里有
.node,包括 Rust/C++/平台相关绑定。 - Discord 案例 :macOS 包里也有
app.asar,但它更像安装器/更新器。 - Discord 的二级更新系统:通过 manifest 和模块更新逻辑下载真正的核心模块。
- 结论:Electron 应用通常很容易拆开看源代码或资源,但这不等于可以绕过授权、复制专有代码或做非法修改。
Electron 应用看起来像普通桌面软件:Windows 上是 .exe 安装包,macOS 上是 .dmg,Linux 上可能是 .deb、.rpm、AppImage 或 snap。但如果把它们剥开,会发现很多 Electron 应用的核心结构相当一致:一个 Chromium/Electron 运行时外壳,加上一坨 HTML、CSS、JavaScript,再加一些 Node 模块和少量 native addon。
这篇文章的标题叫 Cracking Electron apps open。这里的 "crack open" 不是破解授权,也不是绕过付费,更像是"把核桃敲开看看里面是什么"。原文也特意说明,这里分析的 draw.io desktop 本身是开源项目,并没有试图隐藏内容。真正要讲的是:Electron 应用到底怎么打包?不同平台的安装包外壳分别是什么格式?怎样从这些外壳里找到真正的应用资源?
故事从一个很实际的需求开始:作者的网站里有很多 draw.io 图表。平时在 Windows 或 macOS 桌面上用 draw.io desktop 画图,但网站构建流水线跑在 Linux 上,需要把 .drawio 文件转换成 PDF,再转成 SVG,并做压缩优化。draw.io 的图形里包含富文本,而 SVG 本身对复杂富文本布局支持并不好,所以需要 Chromium 来渲染 HTML/CSS/JS,把图形按 draw.io 编辑器里的样子排版出来,再打印成 PDF。
问题是,draw.io desktop 会更新,自己的转换程序可能会被新版本改动弄坏。每当这种情况发生,就需要拿一个新的 draw.io desktop 包,把里面的 HTML、JS、CSS 找出来,看看到底变了什么。于是就有了这次"拆 Electron 应用"的旅程。
一、Electron 应用为什么通常能被拆开
Electron 的基本模式是:把 Chromium、Node.js 和应用代码打包到一起。你的应用界面本质上还是网页,只不过运行在一个桌面壳里。对于很多 Electron 应用来说,真正的业务逻辑和 UI 资源就在某个归档里,常见名字是:
text
resources/app.asar
asar 是 Electron 自己的归档格式。它有点像 tar 或 zip,但更贴近 Electron 的运行方式。Electron 可以把 .asar 当作一个虚拟目录来读取,应用代码仍然可以像访问普通文件一样访问里面的内容。
为什么要有 ASAR?一方面,旧版本 Windows 某些 API 有路径长度限制,安装大量层级很深的 node_modules 文件很容易出问题。另一方面,Windows 对"大量小文件"的处理速度通常不如 Linux/macOS,把许多文件合成一个归档,可以改善安装、启动和分发体验。
所以拆 Electron 应用时,经常是两层工作:
text
先拆平台安装包
再找 app.asar
最后从 app.asar 里列出或提取 HTML、JS、CSS、资源文件
这篇文章几乎就是围绕这条路径展开的。
二、Windows Installer:看起来是 exe,里面是 NSIS 和 7z
draw.io desktop 的 Windows Installer 是一个大约 100MB 的 .exe 文件。表面上它是 Windows 可执行文件,但很多 Windows 安装器本质上都是"可执行外壳 + 压缩归档"。这类东西不一定要在 Windows 上运行,也可以直接当归档拆。
用文件分析工具或归档工具查看后,可以发现它使用的是 NSIS,也就是 Nullsoft Scriptable Install System。NSIS 很常见,很多 Windows 软件都用它做安装器。这个安装器内部又包含一个更大的压缩文件,比如 app-64.7z,真正应用内容就在里面。
解开第一层后,会看到类似:
text
$PLUGINSDIR/
app-64.7z
nsis7z.dll
StdUtils.dll
System.dll
...
继续解开 app-64.7z,才会看到 Electron 应用真正的目录结构。此时如果直接找 HTML 文件,可能只看到 LICENSES.chromium.html,那只是 Chromium 的许可证页面,并不是我们要找的应用入口。
继续找 .asar,就会发现:
text
resources/app.asar
这才是关键文件。用 Electron 的 asar 工具列出内容,可以看到 draw.io 的页面资源:
text
/drawio/src/main/webapp/index.html
/drawio/src/main/webapp/export3.html
/drawio/src/main/webapp/styles/dark.css
/drawio/src/main/webapp/styles/grapheditor.css
/drawio/src/main/webapp/mxgraph/css/common.css
...
这就是作者要找的东西:HTML、CSS、JS 和 draw.io 的前端资源。把 app.asar 解出来后,整个应用代码都在本地目录里。对于 draw.io 这种开源应用来说,这并不是"黑客行为",只是换了一种方式查看已经公开分发的资源。
这一步也揭示了一个很重要的事实:Electron 应用的安装包往往只是套了很多层壳。最外层是安装器,里面是压缩归档,再里面是 Electron 目录结构,最后是 app.asar。
三、Windows No Installer:名字叫 no installer,但还是自解压包
draw.io 还提供 Windows "No Installer" 版本。按名字理解,它应该是一个真正的免安装压缩包,比如 .zip。但实际下载下来还是一个 .exe,大小也接近 100MB。
用 file 看它,会发现它仍然是一个 NSIS self-extracting archive,也就是 NSIS 自解压归档。区别只是安装流程更简单,不一定写注册表或安装到系统目录,但它并不是一个真正意义上的普通归档文件。
拆法也差不多:用归档工具直接解开 .exe,进入 $PLUGINSDIR,里面仍然有 app-64.7z。再解开这一层,继续找 resources/app.asar。
这部分有点好笑:既然叫 "No Installer",更自然的发布形式应该是 .zip 或 .7z。不过对 Electron 应用来说,各平台打包工具往往有自己的默认产物,最后出来的东西未必完全符合用户对文件名的直觉。
四、macOS Universal:DMG 也能在 Linux 上拆
macOS 版本是 .dmg,也就是磁盘镜像。正常情况下,在 macOS 上双击 DMG,把 .app 拖到 Applications 里即可。但如果你在 Linux 上,只想拿里面的资源,不想运行应用,也可以直接把 DMG 当归档处理。
解开 DMG 后,找到 .app 包。macOS 的 .app 不是一个普通单文件程序,而是一个目录结构,通常长这样:
text
draw.io.app/
Contents/
MacOS/
Resources/
app.asar
Info.plist
Frameworks/
对于 Electron 应用来说,核心资源依然在:
text
draw.io.app/Contents/Resources/app.asar
用 asar 工具列出它,就能看到同样的 index.html 等资源。这个时候模式已经非常明显了:不管外层是 Windows 安装器还是 macOS DMG,最后都会通向同一个 Electron 应用资源归档。
五、Linux deb:deb 本质上是 ar 归档
Linux 下 draw.io 提供 .deb。很多人平时只会用 dpkg -i 或包管理器安装,但 .deb 文件本质上其实很简单:它是一个 ar 归档,里面通常包含:
text
debian-binary
control.tar.gz
data.tar.xz
其中 control.tar.gz 是包元数据和安装脚本,data.tar.xz 才是真正会被安装到文件系统里的内容。
所以拆 .deb 可以分两步:先列出 ar 归档内容,再解出 data.tar.xz,然后在里面找 app.asar。draw.io 的路径类似:
text
./opt/drawio/resources/app.asar
这一步也能用归档工具完成。对很多包来说,7z、tar、ar 都能派上用场。你甚至可以只从 data.tar.xz 中提取 app.asar,不用完整解开整个包。
这说明 Linux 发行包并不神秘。.deb 只是把文件按将来要安装到系统里的路径打包好,再附带控制信息。Electron 应用放进去后,核心结构仍然没变。
六、Linux rpm:再拆一层 cpio
RPM 是另一个常见 Linux 包格式。用归档工具打开 .rpm 后,通常会得到一个 .cpio 文件。cpio 是一种老牌归档格式,rpm 里真正的文件内容就在这个归档中。
draw.io 的 rpm 解开后,可以在 cpio 里找到:
text
./opt/drawio/resources/app.asar
也就是说,.deb 和 .rpm 的外壳不同,但拆到里面后都差不多:把 Electron 应用放到 /opt/drawio,资源归档还是 resources/app.asar。
这也是整篇文章的一个核心观察:平台包格式差异很大,但 Electron 应用内部结构高度相似。
七、Linux AppImage:单文件应用镜像里也有 app.asar
AppImage 的目标是把 Linux 应用打包成一个可执行文件。用户下载后加执行权限,直接运行,不需要安装到系统目录。对普通用户来说,这像是 Linux 上的"绿色软件"。
但从拆包角度看,AppImage 仍然是一个可以分析的文件系统镜像。用归档工具列出内容,可以直接看到:
text
resources/app.asar
这次甚至更短。外层没有 .deb 的 data.tar.xz,也没有 .rpm 的 cpio。直接在 AppImage 中找 .asar 就行。
这再次说明:Electron 应用真正的"肉"通常不在外层格式里,而在 app.asar。
八、Linux snap:Snap 是 SquashFS
snap 版本稍微绕一点。draw.io 的 snap 页面会指向 snap store。snap store 有 API,返回包信息,其中包含匿名下载地址。下载后得到 .snap 文件。
用 file 看,它其实是:
text
Squashfs filesystem, little endian, version 4.0, xz compressed
SquashFS 是一种压缩只读文件系统,常用于嵌入式、Live CD、容器镜像、snap 等场景。既然它是文件系统镜像,也就可以列出内容。继续查找 .asar,还是能找到:
text
resources/app.asar
到这里,Windows、macOS、deb、rpm、AppImage、snap 都已经走了一遍。外层格式从 NSIS、DMG、ar、tar.xz、cpio、SquashFS 各不相同,但 Electron 应用内部的关键文件几乎都能落到同一个模式上。
九、Chrome OS / CRX:这次不是 Electron,而是浏览器扩展
draw.io 还提供 Chrome OS 版本,它指向 Chrome Web Store。Chrome 扩展包是 .crx 格式。
CRX 不是 Electron 应用,因为它不包含 Chromium 和 Node.js 运行时。它只是浏览器扩展,里面是 HTML、JS、CSS 和资源文件。因此文件体积小很多。draw.io 的 CRX 只有十几 MB,而 Electron 包往往上百 MB,因为 Electron 应用会把运行时一起带上。
CRX 格式本质上也很常见:很多格式都是"前面带一些额外头部的 zip"。比如 JAR、ODF、MSIX 等都有类似特征。用普通 unzip 可能会提示文件开头有额外字节,但仍然能列出内容;用归档工具也能直接解。
Chrome OS 版本没有 .asar,因为 ASAR 是 Electron 的东西。这里可以直接看到应用文件,例如 index.html。这反而更接近普通 Web 应用。
这一节顺带解释了 ASAR 的用途:它不是为了安全,不是为了防逆向,而是为了让 Electron 应用分发和运行时访问大量小文件更方便。
十、ASAR 不是安全边界
看到这里,很容易得出一个结论:把代码放进 ASAR 并不能保护源代码。
这不是 ASAR 的目标。ASAR 更像一种打包优化,而不是加密。Electron 可以透明读取 ASAR 里的文件,外部工具当然也可以列出和提取它。很多 Electron 应用甚至没有压缩、没有混淆,JavaScript 文件可以直接读。
如果一个应用把安全性建立在"用户看不到客户端 JS"这个假设上,那本身就有问题。客户端代码已经分发到用户机器上,就应该默认用户可以读取。真正需要保护的逻辑应该在服务端;真正敏感的密钥不应该打包进客户端;授权校验也不能只靠前端变量或本地 JavaScript 判断。
这篇文章不是安全教程,但它很自然地提醒了这个原则:桌面应用客户端并不是可信边界。Electron 应用尤其如此,因为它大量代码就是 Web 前端代码,只是被打进桌面包里。
十一、Figma:2MB 的 DMG 不是完整应用
看完 draw.io,文章又拿 Figma 做例子。
Figma 的 macOS DMG 只有大约 2MB。这对一个完整 Electron 应用来说太小了。解开后会看到一个 .app,但它不是完整 Figma,只是一个下载器或启动器。用归档工具解 DMG 时,还可能遇到权限问题:可执行文件没有保留执行位,导致直接运行 .app 报错。给可执行文件加上 chmod +x 后,又会提示必须放在 /Applications 中运行。这与 macOS 的 App Translocation 等机制有关。
如果不想运行这个下载器,只想知道它会下载什么,可以看 .app/Contents/Info.plist。Info.plist 是 macOS 应用的重要元数据文件。Figma 的 plist 里包含不同架构的下载地址:
text
aarch64 -> mac-arm/Figma.zip
x86_64 -> mac/Figma.zip
也就是说,这个 2MB DMG 只是根据架构下载真正应用包。这样做有好处:不用给所有人分发巨大 universal binary,也能节省带宽。
下载真正的 Figma zip 后,就能看到完整应用结构,其中包括:
text
Figma.app/Contents/Resources/app.asar
Figma.app/Contents/Resources/app.asar.unpacked/
Figma.app/Contents/Resources/app.asar.unpacked/bindings.node
Figma.app/Contents/Resources/app.asar.unpacked/desktop_rust.node
这里出现了 .node 文件。.node 是 Node.js native addon,也就是动态库。Electron 应用经常用它补齐 JavaScript 做不了或做不好的平台能力。
十二、Figma 里的 Rust、C++ 和平台绑定
从 Figma 的 app.asar 里提取 main.js,再用 JavaScript beautifier 格式化,可以看到它会加载两个 native addon:
text
bindings.node
desktop_rust.node
从名字看,desktop_rust.node 很可能包含 Rust 代码。继续看 JavaScript 调用点,可以看到它被用于字体预览、流处理等功能。另一个 bindings.node 则更多像是平台相关绑定,例如 macOS 窗口按钮、系统外观、键盘布局、拼写检查、窗口截图、面板操作等。
再看 Figma.app/Contents/Frameworks,能看到 Electron Framework.framework 和多个 Figma Helper 应用。这说明它确实仍然是 Electron 应用,只是里面混入了大量 native 能力。
用 nm -C 查看 desktop_rust.node 的符号,可以看到 HarfBuzz、FreeType 相关符号。这很合理,因为字体预览需要字体渲染、字形布局、变体字体等能力。还可以看到 cxxbridge 相关符号,说明这里可能使用了 Rust 和 C++ 的桥接。
这部分很有意思,因为它展示了现代 Electron 应用的真实状态:它们不一定只是"网页套壳"。很多大型 Electron 应用会把 UI 层放在 JavaScript/HTML/CSS 里,但性能敏感或平台相关部分用 Rust、C++、Objective-C、Swift、native addon 来补齐。
所以"Electron 应用就是一堆 JS"这句话只说对了一半。外层和很多业务逻辑可能是 JS,但底层能力往往是混合语言实现。
十三、Discord:看起来是应用,其实又是安装器/更新器
最后一个例子是 Discord。
macOS 的 Discord DMG 大约 158MB。解开后能看到 Discord.app/Contents/Resources/app.asar,看起来很有希望。但继续看,会发现这个 app 本身更像安装器或更新器。
在其中的代码里能找到 NEW_UPDATE_ENDPOINT,默认指向:
text
https://updates.discord.com/
继续搜索和格式化 JavaScript,可以看到它会根据 release channel、平台和格式构造下载地址。例如对 Linux,可以构造类似:
text
https://discord.com/api/download/stable?platform=linux&format=tar.gz
下载后发现,里面内容和 macOS app 里的内容类似。这说明 Discord 做了很多跨平台更新逻辑,特别是在 Linux 上,分发和自更新都很麻烦,它们只好自己维护一套机制。
除此之外,Discord 还有第二套模块更新系统。某个 manifest 里列出模块:
text
discord_desktop_core
discord_erlpack
discord_spellcheck
discord_utils
discord_voice
代码里会根据 endpoint、release channel、模块名和版本号下载对应模块。继续挖更新 manifest,可以找到某些模块的完整下载地址、hash 和版本信息。
其中 .distro 文件一开始被 file 识别成 OpenPGP Public Key,看起来很奇怪。进一步查找后发现,它其实是 Brotli 压缩过的 tar。解压后可以看到:
text
delta_manifest.json
files/core.asar
files/index.js
files/package.json
再解开里面,就能拿到真正的应用代码,里面有 2500 多个文件。继续搜 devtools、Window 等关键字,可以看到 Discord 的窗口创建、开发者工具开关、主窗口管理等逻辑。
这里的重点不是"怎么破解 Discord",而是说明大型 Electron 应用的分发链路可能不止一层:外层 app 可能只是 updater,真正的 core 模块通过自己的更新系统下载;模块包又可能是某种压缩格式;最后里面仍然是 asar、JS、native addon 和资源文件。
十四、为什么 Electron 应用通常不难"打开"
看完整篇文章,可以总结出一个规律:Electron 应用的难点不在"能不能打开",而在"外面套了多少层"。
Windows 可能是 NSIS,自解压包,里面再有 7z。macOS 可能是 DMG,里面是 .app bundle。deb 是 ar,里面是 tar.xz。rpm 是 cpio。AppImage 是文件系统镜像。snap 是 SquashFS。CRX 是带额外头部的 zip。Discord 模块是 Brotli 压缩的 tar。
这些外壳名字不同,但本质都属于归档、镜像或压缩格式。只要识别出文件类型,就能继续往里走。file、归档工具、tar、ar、nm、格式化工具、ripgrep、JSON 查看工具,都是这类分析中的常见工具。
而 Electron 应用内部,大部分时候仍然逃不开这些东西:
text
app.asar
package.json
main.js
node_modules
*.node native addon
HTML / CSS / JS
资源文件
更新配置
有时 JavaScript 被压缩或混淆,但很多应用并没有严格混淆。即使压缩了,用格式化工具也能大致恢复可读结构。native addon 则是另一类东西,需要用符号表、反汇编、平台 ABI 知识继续分析,但那已经不是普通 ASAR 层面的事情了。
十五、这对 Electron 开发者意味着什么
如果你是 Electron 开发者,这篇文章最大的提醒是:不要把客户端包当成秘密仓库。
用户拿到应用,就可以拿到里面的 JS、HTML、CSS、资源、配置、部分更新地址、模块名,甚至 native addon 的符号信息。ASAR 不是加密,安装器不是安全边界,DMG、deb、rpm、snap、AppImage 也都不是安全边界。
所以:
text
不要把服务端密钥放进客户端
不要把授权逻辑只放在前端
不要假设 API 地址、feature flag、内部模块名不可见
不要用"打进 asar"当作代码保护
不要把安全建立在混淆上
混淆可以增加阅读成本,但不能改变客户端可被分析的事实。真正敏感的东西应该放在服务端,客户端最多持有短期 token,并且服务端必须验证权限。对本地桌面功能来说,也要假设用户可以修改本地文件、替换 JS、观察请求、拦截更新流程。
换句话说,Electron 应用应该按照 Web 安全模型思考:浏览器端代码天然不可信。只是这次"浏览器端"被打包成桌面软件而已。
十六、这对逆向学习者意味着什么
如果你是为了学习软件打包、跨平台分发、Electron 架构,这篇文章是很好的入门材料。它不是从反汇编开始,而是从文件格式开始。很多时候,理解一个桌面应用,不需要立刻打开 IDA 或 Ghidra。先看安装包结构、资源归档、入口 JS、package.json、native addon、更新配置,就已经能学到很多。
这种分析适合以下合法场景:
text
分析开源应用的打包结构
调试自己应用的资源路径问题
研究 Electron 分发机制
排查安装包里缺失文件
学习 deb/rpm/AppImage/snap/DMG/CRX 等格式
检查自己应用是否误打包敏感文件
做安全审计或漏洞赏金前的静态分析
但边界也很清楚:不要用这些方法绕过付费、破解授权、盗取商业代码、修改别人客户端传播恶意版本,或者提取不该传播的专有资源。能打开不代表有权使用,能读取不代表能复制分发。
原文的 draw.io 例子之所以适合讲,是因为 draw.io desktop 是开源项目,资源本来就公开。Figma 和 Discord 的部分则更像观察大型 Electron 应用的结构,不是鼓励复制或修改它们的代码。
十七、工具链背后的几个关键概念
这篇文章虽然看起来像拆包流水账,但背后有几个很值得记住的概念。
第一个是 文件格式识别 。不要只看扩展名。.exe 可能是安装器,.dmg 是磁盘镜像,.deb 是 ar,.rpm 里面有 cpio,.snap 是 SquashFS,.crx 是带头部的 zip。先识别格式,再选择工具。
第二个是 分层归档。很多安装包不是一层压缩,而是多层。Windows installer 里面有 7z,deb 里面有 tar.xz,Discord 的 distro 是 Brotli 后的 tar。拆包时要有"继续往里看"的意识。
第三个是 Electron 资源位置 。很多 Electron app 的核心都在 resources/app.asar。macOS 上路径通常在 .app/Contents/Resources/;Linux 上可能在 /opt/<app>/resources/;Windows 上通常在应用安装目录的 resources/ 下。
第四个是 ASAR 不是加密。它只是归档格式,Electron 能读,外部工具也能读。
第五个是 native addon 是分界线 。JS/HTML/CSS 很容易阅读,.node 这种 native addon 则进入了二进制世界。它可能由 C++、Rust、Objective-C、Swift 等语言编译而来,需要用完全不同的方法分析。
第六个是 更新器经常比应用本体更复杂。Figma 的小 DMG 只是下载器,Discord 的外层 app 也像更新器。真正应用可能通过平台、架构、release channel、manifest 再下载。
十八、文章真正想表达什么
这篇文章表面上是在"拆 Electron 应用"。更深一层,它是在展示现代桌面应用分发的真实形态:外层包装越来越多,内部却越来越像 Web 应用和 native 模块的混合体。
一个 Electron 应用可能包含:
text
Chromium
Node.js
JavaScript 主进程
渲染进程页面
CSS 与资源
node_modules
native addon
自动更新器
平台特定桥接代码
压缩/归档/镜像外壳
这些东西分散在不同层里。用户看到的是一个 .exe 或 .dmg,开发者看到的是 Electron 项目,系统看到的是归档、二进制、文件系统镜像和动态库。拆开它,就是把这些层一层层还原出来。
文章的语气很轻松,但技术视角很扎实。它不是为了炫耀"我能打开别人的应用",而是为了说明:软件分发格式并不魔法,Electron 也不神秘。只要知道每一层是什么格式,就能理解它如何被安装、如何被启动、核心资源在哪里、平台能力如何补齐。
十九、总结
这篇文章从一个很实际的需求开始:作者需要从新版 draw.io desktop 中找到 HTML、JS、CSS 资源,用于自己的图表渲染流水线。因为 draw.io 图表里包含富文本,需要 Chromium 按浏览器方式布局,再打印成 PDF,最终转成 SVG。draw.io 更新后,转换程序可能失效,于是需要拆开新版桌面包,找到真正的前端资源。
从 Windows Installer 开始,文章展示了 Electron 应用常见的层层打包结构。Windows 安装包是 NSIS,里面有 app-64.7z,继续解开后找到 resources/app.asar。Windows "No Installer" 版本虽然名字像免安装包,但本质仍是 NSIS 自解压归档。macOS Universal 版本是 DMG,解开 .app 后仍然在 Contents/Resources/app.asar 找到应用资源。
Linux 下,不同发行格式外壳各不相同。.deb 是 ar 归档,真正文件在 data.tar.xz;.rpm 解开后进入 cpio;AppImage 可以直接列出内部文件;snap 下载后是 SquashFS 文件系统。它们最终都能找到 Electron 的 resources/app.asar。Chrome OS 版本则不同,它是 CRX 浏览器扩展,不包含 Electron 运行时,也没有 ASAR,本质更像带额外头部的 zip。
文章随后用 Figma 和 Discord 说明:这种方法并不只适用于 draw.io。Figma 的 2MB macOS DMG 只是下载器,真正应用地址写在 Info.plist 里;下载完整 zip 后,可以看到 app.asar 和多个 .node native addon,其中包括看起来由 Rust/C++ 参与构建的 desktop_rust.node。Discord 的 macOS 包也有 app.asar,但它更像安装器/更新器;进一步查看更新逻辑和 manifest,可以找到模块化下载系统,真正的 core 模块以 Brotli 压缩 tar 的形式分发,里面又包含 core.asar、index.js、package.json 等文件。
整篇文章最重要的结论是:Electron 应用通常很容易打开,至少可以看到大量客户端代码和资源。ASAR 不是安全机制,安装包格式也不是安全边界。对开发者来说,不能把密钥、授权逻辑、敏感配置放在客户端,并指望用户看不到。对学习者来说,拆开 Electron 应用是理解桌面分发、归档格式、更新机制、native addon 和前端资源组织方式的好方法,但必须限定在合法、合规、尊重许可证和用户权益的范围内。
最终,这篇文章不是教人"破解软件",而是教人识别软件外壳。Electron 应用的外层可能是 NSIS、DMG、deb、rpm、AppImage、snap、CRX、Brotli tar;内层则常常是 app.asar、JavaScript、HTML、CSS、node_modules 和 native addon。只要一层层看清楚,就会发现桌面应用并没有想象中那么神秘,它只是很多文件格式、运行时和打包约定叠在了一起。