# Defender 冒烟与离线安装包完整性校验 > round-43 并行 sub agent 方向 CC(矩阵 99 / 118 本地可测部分)。 > 执行日期:2026-08-02;环境:Windows(PowerShell),Node v22.13.0。 ## 1. 验收矩阵与本方向范围 | 矩阵行 | 条目 | 本地可测部分 | 剩余(外部项) | |--------|------|--------------|----------------| | 99 | Defender 和真实 APS 求解通过 | Defender 静态扫描冒烟(本机 MpCmdRun.exe,见 §3);真实 APS 求解通过由四引擎黄金测试覆盖(既有测试体系,非本方向交付) | Defender for Endpoint 门户/API 入 CI 门禁;实时防护真实拦截演练 | | 118 | 干净离线机安装冒烟 | 离线安装包完整性校验:安装包存在/体积/SHA-256 校验和清单 + dry-run 安装路径(见 §4) | 干净离线机(无 Python、无网络)实机安装 + 冷启动 + 升级/回滚验收,需外部验证机 | 硬性纪律遵守情况:未修改 server/**、apps/desktop/**、packaging/**(仅只读读取 apps/desktop/package.json 与 packaging 配置推导产物路径);未 commit/push/merge;未重启 8003/5173。 ## 2. 涉及文件 新增(本方向写范围): - scripts/defender-scan.mjs — Defender 静态扫描冒烟 - scripts/offline-install-check.mjs — 离线安装包完整性校验 - tests/node/packaging-smoke.test.mjs — 两个脚本可测逻辑的 node 单测 - docs/development/packaging-smoke.md — 本文档 运行时产物(build/ 已被 .gitignore 忽略,不入库): - build/offline-check/offline-install-manifest.json — 校验和清单(机器可读) - build/offline-check/checksums.sha256 — sha256sum 格式校验和(可随安装包转移) - build/offline-check/aps-agent-desktop-0.1.0.exe — portable 模式拷贝的安装包 只读引用的既有产物(构建于 2026-07-31,来源见下): - dist/sidecar/aps-sidecar/aps-sidecar.exe — PyInstaller Sidecar(scripts/build-sidecar.mjs 产出) - apps/desktop/release/win-unpacked/工业智核 APS.exe — electron-builder win-unpacked 冻结桌面包 - apps/desktop/release/win-unpacked/resources/sidecar/aps-sidecar.exe — 桌面包内置 Sidecar - apps/desktop/release/aps-agent-desktop-0.1.0.exe — NSIS 安装包(electron-builder,artifactName aps-agent-desktop-0.1.0.exe) ## 3. Defender 静态扫描冒烟(scripts/defender-scan.mjs) 原理:调用本机 Windows Defender 命令行工具做按需静态扫描: MpCmdRun.exe -Scan -ScanType 3 -File -DisableRemediation - -ScanType 3 = 自定义文件/目录扫描(目录递归)。 - -DisableRemediation = 只检出不清理,构建产物不会被删除/隔离(本脚本默认开启;如确有威胁,只报告不处理)。 - 退出码按任务约定区分:0 = 通过/无威胁;2 = MpCmdRun 不可用(跳过);非 0(1)= 检出威胁或扫描失败;另定义 3 = 无产物可扫。 用法: node scripts/defender-scan.mjs # 自动发现并扫描 4 个产物 node scripts/defender-scan.mjs ... # 显式指定目标(支持目录递归) node scripts/defender-scan.mjs --timeout 900000 # 单文件超时(默认 600000 ms,已覆盖百 MB 级安装包) node scripts/defender-scan.mjs --mpcmdrun # 严格指定 MpCmdRun 路径(不存在则 exit 2) node scripts/defender-scan.mjs --json # 输出机器可读摘要 node scripts/defender-scan.mjs --no-copy-fallback # 关闭非 ASCII 路径的临时拷贝回退 node scripts/defender-scan.mjs --self-test # 解析器/产物发现自检(不调用真实扫描) 自动发现目标(由 apps/desktop/package.json 只读推导):sidecar-exe、desktop-frozen-exe、 bundled-sidecar-exe、nsis-installer。缺失目标打印 [MISSING] 并跳过。 已知行为(实测确认): - MpCmdRun 无法解析非 ASCII 路径:对 D:\ItemSpace\14.工业智核\... 下的文件原路径扫描会失败 (node spawn 场景报 CmdTool: Failed with hr = 0x80508023,exit 2;PowerShell 调用场景报 "was skipped",exit 0)。本脚本默认将含非 ASCII 字符的文件拷贝到 ASCII 临时目录后扫描 拷贝(字节相同,结论等价),输出标记 [temp-copy];目录不拷贝、原位递归扫描。 - 威胁检出文本是权威信号(MpCmdRun 在 -DisableRemediation 模式下威胁时 exit 2 且打印 LIST OF DETECTED THREATS;默认清理模式威胁时 exit 0 但打印 found N threats),解析器两种 模式都覆盖,并以输出文本为准判定 clean/threat/skipped/error。 - 扫描结果只输出摘要(状态/威胁名/耗时/策略),不输出大段日志(--json 附 outputTail 便于排查)。 威胁输出解析的正确性已用真实 EICAR 测试文件验证(开发期探测): - 默认模式:exit 0,输出 Scanning ... found 1 threats.,随后 Cleaning started/finished,文件被清除(约 21.5s)。 - -DisableRemediation 模式:exit 2,输出 LIST OF DETECTED THREATS + Threat : Virus:DOS/EICAR_Test_File,文件保留(约 79ms)。 - 脚本内不自带 EICAR 生成(避免污染本机 Defender 事件),解析用例固化在 --self-test 与单测中。 ## 4. 离线安装包完整性校验(scripts/offline-install-check.mjs) 职责:NSIS 安装包(以及相关产物)SHA-256 校验和清单的生成与校验 + dry-run 安装路径检查。 用法: node scripts/offline-install-check.mjs # 生成清单并立即校验 + dry-run node scripts/offline-install-check.mjs --verify # 只校验既有清单 node scripts/offline-install-check.mjs --portable # 便携包:拷贝安装包到输出目录并生成相对路径清单 node scripts/offline-install-check.mjs --out-dir # 默认 build/offline-check node scripts/offline-install-check.mjs --root # 解析清单路径的基准目录(默认仓库根) node scripts/offline-install-check.mjs --localappdata

# dry-run 时覆盖 %LOCALAPPDATA% node scripts/offline-install-check.mjs --json # 机器可读报告 node scripts/offline-install-check.mjs --self-test # 内部冒烟(临时文件,不依赖真实产物) 校验规则: - 安装包存在性:缺失即 FAIL。 - 体积门禁:安装包 >= 50 MB,其余产物 >= 5 MB(PyInstaller/Electron 产物异常偏小视为失败)。 - 校验和:逐文件流式 SHA-256 与清单比对(存在/大小/哈希全匹配才 PASS;篡改文件会检出 mismatch)。 - dry-run 安装路径:由 apps/desktop/package.json(只读)的 productName 推导 NSIS per-user 默认安装目录 %LOCALAPPDATA%\Programs\,即 C:\Users\\AppData\Local\Programs\工业智核 APS; 当前目录不存在时报告 dry-run 通过但注明需外部干净离线机实装;若已存在则校验 app 主程序与 resources/sidecar/aps-sidecar.exe 布局是否完整。 离线转移流程(便携包): 1. 构建机执行 node scripts/offline-install-check.mjs --portable → build/offline-check/ 内含安装包 + checksums.sha256 + offline-install-manifest.json(路径相对该目录)。 2. 将整个目录拷入 U 盘等介质,在目标离线机执行: node scripts/offline-install-check.mjs --verify --root <介质目录> 3. 实装后用 dry-run 输出的预期路径核对安装落点。 说明:checksums.sha256 为 UTF-8 编码;中文 Windows 下 PowerShell Get-Content 可能按 GBK 显示乱码 (文件本身正确,可用 node 或 UTF-8 工具读取);机器可读校验以 JSON 清单为准。 ## 5. 测试 - 脚本内自检:node scripts/defender-scan.mjs --self-test(8/8 PASS)、 node scripts/offline-install-check.mjs --self-test(7/7 PASS)。 - node 单测:node --test tests/node/packaging-smoke.test.mjs(12/12 PASS)。 覆盖:MpCmdRun 输出解析(clean/threat/skipped/计数/威胁名)、verdict 分类、安装包名模板解析、 产物发现、sha256 确定性、checksums 往返解析、预期安装目录、dry-run 布局检测、体积门禁、篡改检出。 ## 6. 本地实测记录(2026-08-02) Defender 扫描(MpCmdRun: C:\Program Files\Windows Defender\MpCmdRun.exe,签名 1.455.456.0): [PASS] sidecar-exe dist/sidecar/aps-sidecar/aps-sidecar.exe (17.5 MB) clean 0.2s [temp-copy] [PASS] desktop-frozen-exe apps/desktop/release/win-unpacked/工业智核 APS.exe (215.2 MB) clean 0.1s [temp-copy] [PASS] bundled-sidecar-exe apps/desktop/release/win-unpacked/resources/sidecar/aps-sidecar.exe (17.5 MB) clean 0.2s [temp-copy] [PASS] nsis-installer apps/desktop/release/aps-agent-desktop-0.1.0.exe (163.1 MB) clean 1.0s [temp-copy] Verdict: PASS(exit 0,无威胁,skippedCount 0) 副产品验证:--no-copy-fallback 对非 ASCII 路径原位扫描 → 正确报失败(hr 0x80508023,exit 1), 佐证 temp-copy 回退是必要且正确的。 离线安装包校验: generate(4 条目): PASS — nsis-installer / sidecar-exe / desktop-frozen-exe / bundled-sidecar-exe verify(复用清单): PASS portable 便携包 : PASS(build/offline-check/ 内含 aps-agent-desktop-0.1.0.exe 171,025,378 B) verify --root build/offline-check(模拟介质目录): PASS dry-run 安装路径 : C:\Users\andy_\AppData\Local\Programs\工业智核 APS — 当前机器未安装(存在性 false), 实机安装需外部干净离线机 SHA-256 清单(与 build/offline-check/offline-install-manifest.json 一致): nsis-installer 044c4a83aaf28476a1e2405a7a08185b5aff0dfab27f0299b8bcf16c8d32bf21 sidecar-exe 88abc8b1ae0d4bbd715ee9a263cf107198c183b040728711c28c1ae65a8e8f39 desktop-frozen-exe f5b4b22b3c7bd0dbb5708d90238b744f7b51f8ef682081b2458732954cf6cef4 bundled-sidecar-exe 88abc8b1ae0d4bbd715ee9a263cf107198c183b040728711c28c1ae65a8e8f39 产物来源说明:全部产物为 2026-07-31 既有构建(scripts/build-sidecar.mjs 产出 Sidecar; electron-builder 产出 win-unpacked 与 NSIS 安装包,apps/desktop/release/),本次未重建、未修改。 ## 7. 矩阵达成情况与剩余风险 矩阵 99(Defender + 真实 APS 求解): - 本地部分达成:Defender 静态扫描冒烟 4/4 产物 clean;解析器经真实 EICAR 输出格式验证。 - 真实 APS 求解通过:由四引擎黄金测试覆盖(既有体系,本方向不重复交付)。 - 剩余(外部):Defender for Endpoint 门户/API 入 CI 门禁;实时防护真实拦截演练(本机实时防护已开启, 但真实拦截需受控样本与策略配合)。 矩阵 118(干净离线机安装冒烟): - 本地部分达成:安装包存在/体积/校验和/清单生成与校验/dry-run 路径全部通过。 - 剩余(外部):干净离线机(无 Python、无网络)实机安装 + 冷启动 + 升级/回滚验收;需外部验证机, 可用 §4 portable 流程随 U 盘执行。 已知限制: - 本机非管理员,无法读取 MpPreference 排除项;若存在路径排除,Defender 会 skipped(exit 0 + WARNING), 需在门禁前人工复核排除策略。 - 扫描为静态按需扫描(-ScanType 3),不等价于实时防护全链路;安装包未签名(既有事实,需签名证书)。