破解Electron桌面补丁:dsh-purge如何处理app.asar解包与Windows无闪窗控制台隐藏
【免费下载链接】dsh-purgeDeepSeek Harness 破甲:让所有模型都能破甲,不同模型可换不同提示词;默认提示词面向国模「小码酱」。Jailbreak for every model — swap prompts per model. 求 Star 收藏 ⭐项目地址: https://gitcode.com/gh_mirrors/ds/dsh-purge
Electron 桌面应用打本地补丁,最难的两件事是「解包 app.asar」和「Windows 无闪窗控制台隐藏」。dsh-purge(DeepSeek Harness 红队评测插件)在这两个痛点上给出了完整方案:自研 asar 解包器、自动归档改名换载、子进程 windowsHide 强制注入。本文带你从零看懂这套 Electron 补丁技术是怎么落地的,新手也能照图索骥找到对应源码。
为什么 Electron 桌面补丁要先搞懂 asar?
官方 DeepSeek Harness 桌面客户端(DeepSeek Harness.exe)把整个前端打包进了resources/app.asar这一个文件里。Electron 启动时会把app.asar伪装成一个虚拟目录:程序里看到的resources/app/...路径,实际都落在归档文件内部。
这带来三个补丁难题:
- 写不进去:往映射出来的
resources/app里新建文件会直接ENOENT,因为底层根本没有真实目录; - 判不准:用普通
fs.statSync(...).isFile()判断app.asar永远是假的(它被映射成了目录); - 动不了:应用运行期间归档文件被 Electron 占用,直接改名可能遇到
EBUSY。
dsh-purge 在 lib/extract-asar.js 里把这三件事全部封装好,整个流程只发生在「官方 EXE」这条安装路径上,Web 端和社区桌面端完全不受影响。
解包四步走:detect、header、extract、overlay
第一步:判断路径是否被 asar「影子覆盖」
asarShadowsPath 会沿路径向上最多回溯 12 层,检查任何一级目录里是否真实存在app.asar文件。只有用original-fs(Electron 未劫持的原始磁盘模块)才能把归档看成文件。这一步是整个补丁的"哨兵":归档还在 → 说明没解开;归档挪走了 → 可以按普通目录处理。
第二步:手工解析 asar 头,不依赖任何第三方库
asar 格式其实很朴素:16 字节定长头(魔数 4 + 头部长度 + JSON 大小),后面跟着一份描述全部文件树和偏移量的 JSON。readHeader 读出头后做三重校验(魔数、长度上限 256MB、JSON 完整性),防止把非 asar 文件误当归档解包。
第三步:分块提取,1MB 缓冲拷贝
extractAsar 按 JSON 里的文件树逐个落盘:
- 普通文件:用 copyRange 以1MB 缓冲从归档内按偏移量拷贝,短读立即报错,不会留下半截文件;
- 符号链接:重建 symlink,建不了就跳过(主程序文件仍在归档里,不影响运行);
- 标记
unpacked的原生模块(.node二进制等):归档正文里没有它们,交给第四步补齐。
第四步:回贴 unpacked 原生文件
overlayAsarUnpacked 会把旁边app.asar.unpacked目录下的原生文件只补缺、不覆盖,逐个复制进resources/app。这样解出来的目录才是一个能直接启动的完整应用树。
归档改名:先备份、忙了再等
解包完成后必须让 Electron 不再走归档,否则虚拟目录会盖住真实文件。renameAsarAside 把app.asar改名为app.asar.bak(相当于备份 + 卸载虚拟映射一步完成):
| 情况 | 处理方式 |
|---|---|
| 改名成功 | 归档即备份,随时可移回去恢复 |
| 文件被占用(EBUSY/EPERM/EACCES) | 返回busy,由 desktop.js 的scheduleAsarRenameWhenIdle在进程空闲时补改 |
整个「点应用」时发生的桌面端闭环,可以这样理解:
检测到官方 DeepSeek Harness.exe ↓ 校验 resources/app.asar 真实存在 ↓ extractAsar → 解包到 resources/app ↓ overlayAsarUnpacked → 回贴原生 .node 模块 ↓ renameAsarAside → 归档改名为 .bak(备份) ↓ 写入补丁 → 提示重启 → 重启后直接读真实目录调用入口在 lib/core.js 的openSealedDesktopHost与scheduleSealedDesktopRestart——用户不需要跑任何脚本,在插件侧栏点「应用」即可,自动重启。
双 fs 路由:补丁全程不会写错地方
解包前后的世界切换是补丁类工具最容易翻车的地方。dsh-purge 的做法是一个统一的门面 hostFs:每个文件操作(读写、改名、删除……)都先问一句「这个路径被 asar 影子覆盖了吗?」——
- 归档还在 → 走
original-fs,操作真实磁盘; - 归档已挪走或根本不是 Electron 环境 → 走标准
node:fs。
补丁写入、状态探测、备份还原全部走这一条通道,不会出现"补丁打进了虚拟目录里"这种灵异问题。
Windows 无闪窗:给所有子进程强制 windowsHide
在 Windows 上跑 CLI 型宿主时,每弹一个黑框闪一下极其掉体验。dsh-purge 的无闪窗方案在 lib/hide-console.js,分三层,且只对win32生效:
- 包裹内置模块:installHideConsole 通过
process.getBuiltinModule("child_process")拿到内置模块本体(Node 24 的 ESM 具名导入拿到的是副本,改了没用),把spawn / spawnSync / exec / execSync / execFile / execFileSync / fork全部包一层,强制在参数里塞windowsHide: true; - 拦截 import 路径:Node ≥22 环境下用
registerHooks注册解析钩子,把import "node:child_process"直接短路到门面文件 lib/child-process-hide.mjs,保证任何新代码 import 到的都是已包裹版本; - 持久化注入入口:installHideConsoleIntoBin 往宿主
lib/bin.js顶部插入一行 import(保留 shebang 行位置),并落盘两个 sidecar 文件。重启后子进程照样无闪窗。
几个工程细节值得学习:
- 幂等:模块上打了
__dshPurgeHideConsole标记位,重复安装直接返回already;注入前先清除旧行,不会越注越多; - 可还原:
revertHideConsoleFromBin精确删掉注入行、清理 sidecar,一行不多删; - 保护源码树:
looksLikeSourceCliRoot识别出这是开发者源码工作区(如apps/cli构建产物)时坚决不写,只读探测,避免污染构建输出; - Electron 宿主降级:Electron 环境里 ESM namespace 是冻结的,注册 resolve 钩子会抛错,于是只做 builtin 包裹、跳过 import 钩子,同样生效。
小结
dsh-purge 处理 Electron 桌面补丁的思路可以浓缩成三句话:
- 认清虚拟目录:凡是
app.asar还在的路径,一律用original-fs看、用真实磁盘写; - 解包要闭环:手工解析 asar 头 + 分块提取 + 回贴 unpacked + 归档改名为 .bak,备份和卸载映射一次完成;
- 闪窗是子进程问题:包裹
child_process本体 + import 钩子兜底 + 入口持久化注入,三层叠加、可一键还原。
想深入阅读的话,核心文件就两个:解包侧看 lib/extract-asar.js 和 lib/core.js,无闪窗侧看 lib/hide-console.js 和 lib/child-process-hide.mjs。这套「影子路径判断 → 双 fs 路由 → 空闲重试」的组合拳,放在任何给 Electron 应用打本地补丁的场景里都值得一抄。
【免费下载链接】dsh-purgeDeepSeek Harness 破甲:让所有模型都能破甲,不同模型可换不同提示词;默认提示词面向国模「小码酱」。Jailbreak for every model — swap prompts per model. 求 Star 收藏 ⭐项目地址: https://gitcode.com/gh_mirrors/ds/dsh-purge
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考