Files
dsh-purge2/lib/bin-preflight.js
叫我小杨同学 335ddee90f fix: 全仓审计加固与死代码清理,版本 1.1.87
- 回滚/备份:空 bak 改名 .bad 跳过;升级刷新 bak 补上单数 marker 补丁;统一原子写
- 补丁命中:optional 命中不符记软失败;#42 插入型替换加探针防重复插入
- Windows:进程枚举改用 | 分隔 + UTF-8,修复中文路径换包不杀旧进程;换包失败拉起原版
- 安全:asar 解包防越界;红队路径校验 realpath 防空 symlink;更新仅 https;报告回放去换行注入
- 提示词钩子:停用后 rewriteFn 返回原装配文本并清理 assemble guard;缓存签名纳入红队/策略/override
- 红队:listEngagements 默认不算统计;listVulns/报告支持 evidenceLimit
- 子代理名额占位即时生效并回退;--apply 有失败项退出码 1
- 清理:删除 lib/mnemon-settings.js 及 13 处死代码/未使用 import;移除 test 目录与 test 脚本
2026-11-01 21:47:03 +08:00

86 lines
2.9 KiB
JavaScript

// #197:把「启动前回收残留 web server」的钩子挂到宿主 bin.js 顶部。
// 必须在 Cordis 激活之前跑:webserver 插件绑端口失败在 0.2.x 是 fatal,等插件层再处理就晚了。
// 注入形态与 hide-console 一致:宿主 lib 下放一个 sidecar + bin.js 顶部加一行 import。
// 与 hide-console 的区别:这里跨平台生效(detached 重启在 macOS/Linux 同样会留下孤儿)。
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { isAsarSealedPath } from "./desktop.js";
import { looksLikeSourceCliRoot, resolveDshBinRoot, writeHostFileAtomic } from "./hide-console.js";
const MARK = "dsh-purge-web-preflight";
const IMPORT_LINE = `import "./${MARK}.js"; // [dsh-purge] web preflight`;
const ENTRY = fileURLToPath(new URL("./web-preflight-entry.js", import.meta.url));
export function installBinPreflight(aiBase) {
const root = resolveDshBinRoot(aiBase);
if (!root) return "missing_bin";
// 源码部署的 apps/cli/lib 是 tsdown 产物:只准读、不准改(#41)。
if (looksLikeSourceCliRoot(root)) return "skipped_source_cli";
const binJs = path.join(root, "lib", "bin.js");
const side = path.join(root, "lib", `${MARK}.js`);
if (isAsarSealedPath(root) || isAsarSealedPath(binJs)) return "sealed_asar";
let source;
try {
source = fs.readFileSync(ENTRY, "utf8");
writeHostFileAtomic(fs, side, source);
} catch (e) {
return `error:${e && e.message ? e.message : e}`;
}
let text;
try {
text = fs.readFileSync(binJs, "utf8");
} catch (e) {
return `error:${e && e.message ? e.message : e}`;
}
if (text.includes(IMPORT_LINE)) return "already_injected";
text = text.replace(/^import "\.\/dsh-purge-web-preflight\.js";.*\r?\n/gm, "");
if (/^#!/.test(text)) {
const nl = text.indexOf("\n");
text =
nl >= 0
? text.slice(0, nl + 1) + `${IMPORT_LINE}\n` + text.slice(nl + 1)
: `${text}\n${IMPORT_LINE}\n`;
} else {
text = `${IMPORT_LINE}\n${text}`;
}
try {
writeHostFileAtomic(fs, binJs, text);
} catch (e) {
return `error:${e && e.message ? e.message : e}`;
}
return "injected";
}
export function revertBinPreflight(aiBase) {
const root = resolveDshBinRoot(aiBase);
if (!root) return "missing_bin";
const binJs = path.join(root, "lib", "bin.js");
const side = path.join(root, "lib", `${MARK}.js`);
let changed = false;
if (!looksLikeSourceCliRoot(root)) {
try {
const text = fs.readFileSync(binJs, "utf8");
const next = text.replace(/^import "\.\/dsh-purge-web-preflight\.js";.*\r?\n/gm, "");
if (next !== text) {
writeHostFileAtomic(fs, binJs, next);
changed = true;
}
} catch (e) {
return `error:${e && e.message ? e.message : e}`;
}
}
try {
if (fs.existsSync(side)) {
fs.unlinkSync(side);
changed = true;
}
} catch {
/* 重启后再删 */
}
return changed ? "reverted" : "absent";
}