PILLAR 03 · ENFORCEMENT
约束机制化:纪律不靠自觉,靠机制兜底
写进 prompt 的纪律有四个失效面:agent 忘了就没了、跑起来后失控、管不住并行会话、没有可查询的占用视图。 这里把纪律做成三层代码:协议层可读、工具层绕不过、会话层直接拦截。
一句话模型
动态分析是「写操作」:独占资源、改变进程行为、可能污染设备状态。静态分析是「读操作」:可并行、无副作用。给动态操作建立事务控制——租约(互斥)+ 网关(收口)+ 审计与污染登记牌(可回溯)。
Hook 语义投毒
[已验证推断] 证据入库—— 无声的数据污染,Reviewer 事后难以发现。IDB 并发写
风控不可逆
DEFENSE IN DEPTH
三层门禁:协议可读 → 工具绕不过 → 会话直接拦
租约协议此前主要靠提示词自觉,现在有三层机制兜底。协议仍然要读(分级、命名、纪律),但违规动作会在工具层与会话层被物理拦截。
mkdir)跨会话天然生效:同一台机器上的多个 Claude 会话、多个终端、人工手动操作共享同一文件系统视图,全部被约束——这是 prompt 级约束做不到的。SESSION HOOKS
四类拦截点,一条命令部署
hooks 挂进项目 .claude/settings.json,在工具调用前后与回合结束时逐条检查。拦截返回 exit 2(block),解析异常一律 fail-open 放行,不因守护脚本自身故障卡死会话。
bash install.sh --hooks --project /path/to/analysis-project
# 幂等部署进 .claude/settings.json,卸载 = 删除含 guard.sh hook- 的条目PreToolUse · Bash
frida / frida-trace / frida-ps / frida-kill / frida-inject CLI 直连(-U / -H 等场景)——绕过 frida_runner.py 的租约与审计门禁; 同时拦截 ssh 远程杀进程(须持排他租约经 runner 执行)。豁免frida_runner.py 与安装场景(pip install frida、frida-compile)。 拦截消息附正确入口指引。guard_lib/hook_pre_bash.shPreToolUse · MCP
rename / set_comments / patch / patch_asm / put_int / declare_type / set_type / type_apply_batch / enum_upsert / infer_types / declare_stack / delete_stack / define_code / define_func,及 py_eval 类任意代码执行)无有效idb-* 排他租约 → 拦截并打印 acquire 指引。decompile / xref 等读类直通不加锁,保证速度。guard_lib/hook_pre_mcp.shPostToolUse · Write/Edit
evidence.md 后立即校验 schema:编号连续、必填字段齐全、枚举值合法。 写 analysis/ 下报告后即查硬编码地址:非围栏内 0x ≥ 6 位的十六进制地址 直接报出(围栏与注释内豁免)——地址会随版本漂移,报告必须引用符号而非裸地址。guard_lib/check_evidence.shStop · sweep
guard_lib/sweep.shLEASE & LOCKS
S/X 分锁:保并行度,只串行化写行为
锁粒度按「动作改不改状态」分层。单设备上「若干静态分支 + 一个观察分支 + 若干 IDB 读分支」仍然并行,只有写行为串行——动态受控不以牺牲吞吐为代价。
| 粒度 | 资源命名 | 模式 | 覆盖操作 |
|---|---|---|---|
| 设备级 | device-<Name> | X 排他 | 重启设备、装卸 App、动 frida-server、改系统配置(代理/时间/hosts)、跨 App 操作 |
| 进程级 | device-<Name>.proc-<bundle 或 pid> | X 排他 | spawn / kill / 注入会改进程行为的 hook(反调试绕过、返回值篡改、方法 swizzle) |
| 观察级 | device-<Name> | S 共享 | frida-ps、读日志/crash 报告、纯 onEnter 读参数不改返回值的 hook、mitmproxy 被动抓包 |
| IDB | idb-<项目名> | X(写锁) | rename / set_type / patch / define_* / 批量 IDAPython 写操作;decompile / xref 等读操作不加锁 |
device-X 排他时不能拿 device-X.proc-* 排他(防细粒度锁绕过设备级占用),反之亦然;同一 owner 不与自己冲突,观察级共享不触发层级冲突。LEASE=scripts/orchestration/lease.sh
bash $LEASE acquire device-ChenLingHai --ttl 30m --purpose "H1 采集 ground truth"
bash $LEASE acquire device-ChenLingHai.proc-com.x.y --ttl 10m --purpose "spawn 注入 hook"
bash $LEASE renew device-ChenLingHai --ttl 15m # 长任务心跳续租
bash $LEASE release device-ChenLingHai
bash $LEASE check device-ChenLingHai --mode exclusive # 门禁原语:有效 exit 0 / 无效 exit 2
bash $LEASE list # 占用看板(+ 未恢复污染提示)
bash $LEASE steal device-X --reason "持有者已停止且 TTL 误设过长"租约目录 <项目>/analysis/leases/(加入 gitignore)。TTL 默认 30m,惰性回收: 任何 list / acquire 扫描前先清理过期项。steal 是逃生门不是常规操作,必须 --reason 登记到审计日志。
STATE HYGIENE
采样前必做 assert-clean
分支 1 测登录留下半登录态,分支 2 采集「未登录指纹」拿到失真样本,污染经共享 ground-truth/ 传染所有分支。device.sh assert-clean 在采样前把这道关变成脚本门槛,不干净 exit 4。
污染登记牌(权威)
POLLUTE 条目 → FAIL。机械检查有盲区 (代理扫描只是启发式),登记牌是唯一权威: 动了设备状态没恢复的立即登记,恢复后标记关闭,所有后续持有者可见。lease.sh pollute / board / recover时间偏差
device.sh assert-clean不可逆操作分级
lease.sh audit irrevocable --target device-X --detail "…"ESCAPE HATCH
机制可调试、可退出
守护机制本身不能成为不可调试的黑盒:hook 解析异常一律 fail-open(exit 0 放行);调试期有环境变量逃生阀;部署与卸载都是幂等的文件级操作。
GUARD_ALLOW_DIRECT_FRIDA=1
GUARD_ALLOW_IDB_WRITE=1
卸载与部署
guard.sh hook- 的条目; 重复执行 install.sh --hooks 不叠加。hooks 只管挂了配置的会话,是第三层兜底,协议 + 工具层门禁仍是主体。bash scripts/orchestration/guard.sh sweep # INDEX.md 登记 / 临时文件 / 硬编码地址 / 证据 schema
# 退出码 0 = 干净,2 = 有违规,供 CI 或 Coordinator 统一审计