Merge PR #72: IAT repair iron rule + six-phase map + vuln thin overlay (#65)

- IAT fail-fast to dynamic API breakpoints (E-iat-repair-fail)
- .NET/DLL-SYS equivalent anchors; clean-IAT and anti-VM side paths
- thin vuln report overlay (not a 3rd default full flavor)
- CI: nested smoke uses same host + UTF-8 BOM for PS5.1 safety
This commit is contained in:
yhc
2026-08-12 12:34:16 +08:00
12 changed files with 244 additions and 49 deletions
+2
View File
@@ -217,6 +217,8 @@ After task completion (vulnerability verified / reverse complete / flag captured
| "I'll reply to user first, continue after confirmation" | **Don't wait for confirmation on deterministic steps.** Execute while informing user. Only pause at genuine decision points. |
| "I understand the rules, please tell me your task" | **This is the WORST failure mode.** Correct behavior: proactively match user intent to routing table, output analysis, start executing. |
| "User asked to redo import-table / step X, but I did something else more useful" | **Redo = redo the named step.** When user asks to redo X (e.g. import table check), MUST re-execute X and refresh its Evidence. FORBIDDEN to substitute another step or silently skip X. |
| "IAT repair keeps failing; I'll grind more static unpackers" | **IAT repair iron rule:** try auto/semi-auto repair first; on tool error or unreable binary after repair, STOP static IAT, record E-iat-repair-fail, switch to dynamic API breakpoints. FORBIDDEN infinite static IAT thrash. |
| "No import table (.NET) so the hard gate does not apply" | **Equivalent anchor still MUST:** .NET → dnSpy/IL/metadata summary into E-imports slot; DLL/SYS → E-exports alongside imports. FORBIDDEN to skip the gate. |
---
+2
View File
@@ -316,6 +316,8 @@ AI Agent 在遇到阻力时会自动生成"合理借口"来跳过步骤。以下
| "我先回复用户,等用户确认后再继续" | **不需要等确认。** 如果路由已明确且下一步是确定性的(如安装工具、读取文件),直接执行同时告知用户。不要在每一步都等用户点头。 |
| "我理解了规则,请告诉我你的具体任务" | **这是最严重的失败模式。** 读完规则后的正确行为是主动匹配用户意图到路由表,输出分析,开始执行。不是回传问题给用户。 |
| "用户让我重做导入表/某一步,但我改做了别的更有用的步骤" | **重做 = 重做被点名的同一步。** 用户要求重做 X(如导入表检查)时 MUST 重新执行 X 并更新对应 Evidence;禁止用其他步骤冒充完成,禁止静默跳过 X。 |
| "IAT 修不好,我再静态试几种壳工具拖时间" | **IAT 修复铁律:** 优先自动/半自动修复;工具报错或修完无法运行 → 立即停静态 IAT,记 E-iat-repair-fail,转动态 API 断点抓取。禁止无限静态死磕。 |
| ".NET / 没导入表,硬门不适用,我跳过" | **等价锚点仍 MUST:** .NET 用 dnSpy/IL/元数据摘要写入 E-imports 语义槽;DLL/SYS 必须并列 E-exports。禁止空过。 |
> 如果你发现自己在想以上任何一句话,停下来,回到行为链中正确的步骤,继续执行。
+6 -5
View File
@@ -43,13 +43,14 @@ For writing style, tone, and voice guidance, use `Skill(ce:writer)` with **The E
安全类正式报告 **MUST** 读取 `references/vendor-report-rules.md`(只取结构,不抄厂商原文)。仅在任务证据或用户明确要求时选择厂商 flavor;普通逆向和其他任务使用 `flavor = null`。
| Flavor | 何时用 | 主参考骨架 |
|--------|--------|------------|
| Flavor / Overlay | 何时用 | 主参考骨架 |
|------------------|--------|------------|
| `malware` | 明确恶意样本、木马、白加黑、钓鱼投毒 | 火绒式:概述→流程→样本分析→应急处置→IOC |
| `apt` | APT/战役/团伙/多阶段感染链/行业定向 | 卡巴斯基 Securelist 式:摘要→感染链→调查叙事→Interesting findings→技术分析→检测缓解→IOC |
| `flavor = null` | 普通 APK/ELF/PE/Mach-O 逆向、算法/固件分析、渗透 / CTF / JS 签名 | 原任务模板 + Base 通用元素;不套 malware/APT 专属章节 |
| thin `vuln` | 用户明确要求漏洞/补丁/CVE 技术分析 | 概述→影响/复现→崩溃与补丁分析→防护建议(叠加在 null 上,非第 3 默认全文 flavor) |
原则:**模板在精不在多** —— 仅上述 2 个厂商 flavor,不另建第三套全文模板。
原则:**模板在精不在多** —— 仅 2 个厂商全文 flavor;`vuln` 仅为可选 thin overlay,不另建第三套默认全文模板。
与 §0 Evidence→Finding→Path **同时生效**;冲突时 Evidence 契约优先。
### 输出规范
@@ -68,7 +69,7 @@ For writing style, tone, and voice guidance, use `Skill(ce:writer)` with **The E
- 复现步骤必须让第三方能独立重现
- 敏感信息(真实 token、密码、内部 URL)用占位符替代
- **MUST** 包含 Evidence → Finding → Path 链(见 `../ops/evidence-finding-path.md` 与模板 §0)
- **MUST** 读取 `references/vendor-report-rules.md`:选定 `malware` / `apt` 或 `flavor = null`;无 flavor 时只输出原任务模板和适用的 Base 元素,不强制 IOC/ATT&CK
- **MUST** 读取 `references/vendor-report-rules.md`:选定 `malware` / `apt` 或 `flavor = null`(漏洞任务可叠加 thin `vuln`);无 flavor 时只输出原任务模板和适用的 Base 元素,不强制 IOC/ATT&CK
- **SHOULD** 引用 case `scope.md` / `timeline.md`(`../scripts/case-init.ps1`)
### 图表集成
@@ -177,7 +178,7 @@ For README, API endpoint, and file organization templates, see [references/templ
- `field-journal/` — 报告内容同时作为进化日志的数据来源
**安全报告模板**: `references/security-report-templates.md`
**厂商报告规则**: `references/vendor-report-rules.md`(flavor: malware | apt | null)
**厂商报告规则**: `references/vendor-report-rules.md`(flavor: malware | apt | null;optional overlay: vuln)
**通用文档模板**: `references/templates.md`
@@ -36,13 +36,14 @@
> 全文规则:`references/vendor-report-rules.md`(Issue #65)
> **MUST** 在生成安全类正式报告时读取并选型;**只抽结构,禁止抄录厂商原文/IOC 实例**。
| Flavor | 场景 | 骨架一句话 |
|--------|------|------------|
| Flavor / Overlay | 场景 | 骨架一句话 |
|------------------|------|------------|
| `malware` | 明确恶意样本/普通木马/白加黑 | 火绒式:概述→流程→样本分析→应急处置→IOC |
| `apt` | APT/战役/多阶段链 | 卡巴式:摘要→感染链→调查→Interesting findings→技术分析→检测缓解→IOC |
| `flavor = null` | 普通逆向/渗透/CTF/JS 签名 | 本节任务模板 + 适用的 Base 通用元素 |
| thin `vuln` | 漏洞/补丁/CVE 技术分析(显式) | 概述→影响/复现→崩溃与补丁分析→防护建议 |
**通用元素(G1–G7)摘要**:G1 执行摘要 MUST · G2 Scope MUST · G3 E/F/P MUST · G4 IOC 仅 `malware`/`apt` MUST · G5 建议仅 `malware`/`apt` MUST · G6 附录 SHOULD · G7 ATT&CK 在 `apt` MUST
**通用元素(G1–G7)摘要**:G1 执行摘要 MUST · G2 Scope MUST · G3 E/F/P MUST · G4 IOC 仅 `malware`/`apt` MUST · G5 建议在 `malware`/`apt`/`vuln` MUST · G6 附录 SHOULD · G7 ATT&CK 在 `apt` MUST
选型与章节顺序以 `vendor-report-rules.md` 为准;与 §0.1–0.5 冲突时 **Evidence 契约优先**。
@@ -130,6 +131,15 @@
3. 仍 **MUST** 含 §0 Evidence 链;`malware` / `apt` flavor 另 **MUST** 含 IOC 表
4. 二进制样本的静态分析 **MUST** 含导入表 Evidence(与 radare2/ida/malware 硬门一致)
## 1c. 漏洞技术分析报告(thin `vuln` overlay)
当任务为 **OS/组件漏洞、补丁对比、CVE 技术分析**,或用户明确要求「漏洞技术分析报告」时:
1. 读 `vendor-report-rules.md` §3b,使用 thin `vuln` 章节顺序(**不是** malware/apt 全文 flavor)
2. **MUST** 含:影响范围、授权内复现或明确 n/a、崩溃/根因或补丁差异 Evidence、防护/补丁建议
3. **MUST** 含 §0 Evidence→Finding→Path
4. **MUST NOT** 在未授权目标上扩展 PoC,或抄录外部利用武器化细节
## 2. 渗透测试报告模板
```markdown
@@ -11,7 +11,7 @@
| `malware` | 火绒安全病毒/技术分析报告 | 明确的普通木马、白加黑、钓鱼投毒、恶意样本 |
| `apt` | 卡巴斯基 Securelist / APT 战役报告(如 MATA) | APT、团伙战役、多阶段感染链、行业定向 |
原则:**模板在精不在多** —— 仅 2 个厂商 flavor + 1 份通用专业元素;普通逆向、渗透、CTF 和 JS 报告保持任务模板,不默认伪装成恶意软件报告。
原则:**模板在精不在多** —— 仅 2 个厂商全文 flavor(`malware` / `apt`)+ Base 通用元素 + **可选 thin overlay**(如 `vuln` 漏洞技术分析)。普通逆向、渗透、CTF 和 JS 报告保持任务模板,不默认伪装成恶意软件报告;`vuln` **不是** 第 3 个默认全文 flavor。
---
@@ -19,13 +19,15 @@
在 `docs-generator` 生成**安全类**报告时(逆向 / 恶意软件 / 渗透收尾 / 用户明确要求「专业报告」「厂商风格」)**MUST** 读取本文件。只有任务证据或用户明确要求支持时才选择厂商 flavor;否则使用 `flavor = null`,仅叠加通用专业元素和原任务模板。
| 信号 | Flavor |
|------|--------|
| 信号 | Flavor / Overlay |
|------|------------------|
| APT / 团伙 / 战役 / 多阶段 C2 / 行业定向 / ICS / spear-phish 战役 | `apt` |
| 明确恶意样本、木马、窃密、白加黑、仿冒站点 | `malware` |
| 用户明确要求漏洞/补丁/CVE 技术分析,或任务证据为 OS/组件漏洞研究 | `flavor = null` + **thin overlay `vuln`**(见 §3b) |
| 普通 APK/ELF/PE/Mach-O 逆向、算法分析、固件分析、渗透测试、CTF、JS 签名 | `flavor = null`;使用原任务模板和通用专业元素最小集 |
用户显式指定「按卡巴/APT」「按火绒/病毒报告」时,覆盖自动选型。
用户显式指定「按卡巴/APT」「按火绒/病毒报告」「按漏洞技术分析」时,覆盖自动选型。
**禁止** 把普通 malware/APT/普通逆向默认套进 `vuln` 目录。
---
@@ -160,6 +162,42 @@
---
## 3b. Thin overlay:`vuln`(漏洞技术分析 · 可选)
> Issue #65 补充。结构参考公开「操作系统/组件漏洞技术分析」类报告目录,**只抽章节骨架**,禁止抄录截图/正文中的 PoC 报文、利用细节或未授权攻击步骤。
> **不是** 第 3 个默认厂商全文 flavor;仅在漏洞研究任务或用户明确要求时叠加。
**叙事目标**:读者能快速看到「影响谁 → 如何确认/复现(授权内)→ 根因与补丁差异 → 如何缓解」。
### 建议章节顺序
```markdown
## 1. 漏洞概述
### 1.1 影响范围(版本/组件/配置前提)
### 1.2 漏洞复现(授权环境;步骤可第三方重复;无武器化教程口吻)
## 2. 漏洞分析
### 2.1 崩溃 / 异常分析(Evidence:崩溃日志、触发条件)
### 2.2 补丁分析(diff/守卫条件/修复点 — 挂 E-*)
### 2.3 PoC 或触发器分析(仅授权范围内已有材料;协议/输入构造层次说明即可)
## 3. 防护建议
### 3.1 缓解措施(配置/缓解开关等)
### 3.2 官方补丁与验证
## 4. Evidence → Finding → Path(可并入各节或独立表)
```
### 硬约束
- **MUST** scope/授权:未授权目标禁止复现与 PoC 扩展
- **MUST** E/F/P:复现、崩溃、补丁结论均挂 evidence_ids
- **MUST NOT** 把 `vuln` 当作 malware/APT 默认壳
- **MUST NOT** 抄录外部报告/截图中的利用代码或完整攻击武器化步骤
- IOC 表:仅当存在网络/文件指示器时出现;否则 n/a 或省略
---
## 4. 与现有任务模板的挂接
| 任务模板(`security-report-templates.md`) | 叠加方式 |
@@ -183,9 +221,14 @@ elif user_requests_huorong or vir_report or explicit_malware:
flavor = malware
else:
flavor = null # 原任务模板 + Base 中适用的元素
overlay = null
if user_requests_vuln_tech_report or cve_patch_analysis:
overlay = vuln # thin only; never a third default full flavor
emit(base_report)
if flavor in (malware, apt):
emit(report with flavor outline)
elif overlay == vuln:
emit(report with vuln thin outline)
```
---
@@ -198,6 +241,7 @@ if flavor in (malware, apt):
- [ ] `malware` / `apt` 报告有 IOC 表(或 n/a+原因)
- [ ] `malware` / `apt` 报告有可执行建议/处置
- [ ] 无 flavor 的任务没有被套入 malware/APT 专属章节
- [ ] uln 仅在漏洞任务启用;含概述/分析/防护骨架与 E/F/P;无未授权 PoC 武器化
- [ ] 无厂商原文粘贴、无 placeholder/TODO
- [ ] 导入表等硬门 Evidence 已进入静态/技术分析(若本任务做过二进制分析)
@@ -213,6 +257,7 @@ if flavor in (malware, apt):
## 8. 非目标
- 不维护 Mandiant/CrowdStrike/奇安信等额外全文模板(结构已由双 flavor 覆盖常见需求)。
- 不维护 Mandiant/CrowdStrike/奇安信等额外全文模板(结构已由双 flavor + 可选 thin overlay 覆盖常见需求)。
- 不把 `vuln` 升级为与 malware/apt 并列的默认全文 flavor。
- 不自动爬取厂商站点填报告。
- 不因 flavor 降低 Evidence 契约或授权范围。
+6 -2
View File
@@ -244,9 +244,12 @@ idapro_survey_binary(detail_level="minimal")
- 入口点(main/WinMain/DllMain)
- 有趣的字符串(URL、路径、错误消息)
- **导入分类(MUST)**:加密函数 / 网络 API / 文件操作 / 进程注入 / 注册表 — 必须落成 Evidence(建议 id:`E-imports`),可用 `idapro_entity_query(kind="imports")` 或 survey 输出中的 imports 段
- **DLL/SYS**:导出表与导入表并列(Evidence `E-exports`)
- **.NET**:无传统 IAT 时用模块/元数据/托管引用摘要作为等价锚点写入 E-imports 语义槽
- **干净导入表**:注明动态加载嫌疑,推动动态 API 断点验证
- 热门函数(高 xref 计数的函数通常是关键逻辑)
**硬门禁**:未将 imports 视图/分类摘要写入 Evidence 前,MUST NOT 进入 Step 4 深挖结论,MUST NOT 声称 survey 完成。导入表为空或查询失败时仍 MUST 记录失败现象。用户要求重做导入表检查时 MUST 重做本步骤,禁止改换其他步骤。
**硬门禁**:未将 imports 视图/分类摘要(或合法等价锚点)写入 Evidence 前,MUST NOT 进入 Step 4 深挖结论,MUST NOT 声称 survey 完成。导入表为空或查询失败时仍 MUST 记录失败现象。加壳 IAT 修复失败时 MUST 记 `E-iat-repair-fail` 并转动态调试抓 API,禁止静态死磕。用户要求重做导入表/IAT 检查时 MUST 重做被点名步骤,禁止改换其他步骤。
### Step 4: 深入关键函数
```
@@ -349,7 +352,8 @@ ida-pro-mcp --config
## 任务完成自检(声称完成前 MUST 通过)
- [ ] 我是否执行了工作流中的每一步(而不是只阅读)?
- [ ] survey/imports 是否已写入 Evidence(E-imports)?用户若要求重做导入表,是否重做了同一步?
- [ ] survey/imports 是否已写入 Evidence(E-imports 或等价)?DLL/SYS 是否含 E-exports?IAT 失败是否记 E-iat-repair-fail?
- [ ] 用户若要求重做导入表/IAT,是否重做了同一步?
- [ ] 我是否基于 `tool-index` 使用了真实工具路径?
- [ ] 我是否产出了可复现证据(命令/脚本/截图/报告)?
- [ ] 我是否完成并回写了 RULES 要求的 Checklist 项?
@@ -82,6 +82,8 @@ MAY — 真正可选的
| "用户没明确说要报告,我就不写了" | **报告是默认行为,不是可选。** 安全任务完成后必须生成报告,除非用户明确说"不要报告"。 |
| "这个太简单了不需要记录 journal" | **简单任务也有踩坑价值。** 至少记录:目标类型 + 用了什么 + 有无意外,一行也行。 |
| "用户让我重做导入表/某一步,但我改做了别的更有用的步骤" | **重做 = 重做被点名的同一步。** 用户要求重做 X(如导入表检查)时 MUST 重新执行 X 并更新对应 Evidence;禁止用其他步骤冒充完成,禁止静默跳过 X。 |
| "IAT 修不好,我再静态试几种壳工具拖时间" | **IAT 修复铁律:** 优先自动/半自动修复;工具报错或修完无法运行 → 立即停静态 IAT,记 E-iat-repair-fail,转动态 API 断点抓取。禁止无限静态死磕。 |
| ".NET / 没导入表,硬门不适用,我跳过" | **等价锚点仍 MUST:** .NET 用 dnSpy/IL/元数据摘要写入 E-imports 语义槽;DLL/SYS 必须并列 E-exports。禁止空过。 |
**使用方式**:将本表放在 RULES.md 或其他指令文件末尾附近(高注意力区域)。Agent 在找借口之前先看到反驳。
+36 -2
View File
@@ -45,6 +45,28 @@ sha256sum sample.exe
# → VirusTotal / MalwareBazaar / Triage 查询
```
```text
Triage MUST 清单(Issue #65):
□ 文件类型:EXE / DLL / SYS / .NET / 其他
□ 架构 x86/x64/ARM;查壳(DIE 等)与编译语言线索
□ DLL/SYS:导入表与导出表并列检查(见 Phase 2 硬门)
□ .NET:无传统 IAT → 走 dnSpy/IL/元数据等价锚点(见 Phase 2)
```
### Phase 1b: 脱壳与 IAT 处理(有壳时 · Issue #65)
```text
□ 无壳 / .NET → 跳到 Phase 2
□ 有壳:尝试脱壳(授权隔离环境)→ 尝试修复 IAT
- x86:ImportREC(或等价);x64:Scylla(或等价)。禁止 64 位死磕 ImportREC
□ 【IAT 修复铁律】优先自动/半自动修复;若工具报错或修复后无法运行:
- 立即终止继续静态 IAT 修复
- MUST 记录 E-iat-repair-fail(命令、工具、现象)
- ⏩ 转入 Phase 3 动态:API 断点(如 bp CreateFile)/ 硬件断点 / 内存搜索抓取导入
- 这不算跳过导入表:路径已尝试并记 Evidence
□ 用户要求重做「IAT 修复 / 导入表检查」:MUST 重做被点名步骤,禁止换步骤冒充
```
### Phase 2: 静态分析
```text
@@ -56,9 +78,12 @@ sha256sum sample.exe
重点分析区域:
□ 入口点(Entry Point)→ 初始化逻辑
□ 导入表 → API 用途推断(CreateRemoteThread=注入, CryptEncrypt=勒索)
**MUST(硬门)**:执行 rabin2 -i / IDA imports / pecheck 等价命令,将导入表分类摘要写入 Evidence(E-imports)后才能进入 Phase 3
**MUST(硬门)**:执行 rabin2 -i / IDA imports / pecheck 等价命令,将导入表分类摘要写入 Evidence(E-imports)后才能进入 Phase 3(除非已记 E-iat-repair-fail 并走动态旁路,见 Phase 1b)
分类至少覆盖:网络 / 文件 / 加密 / 进程注入 / 注册表 / 其他可疑 API
解析失败或表为空:仍 MUST 记录失败输出,禁止静默跳过
**DLL/SYS**:MUST 并列记录导出表 Evidence(E-exports,`rabin2 -E` 或等价)
**.NET**:无传统 IAT 时 MUST 用 dnSpy/IL/元数据/程序集引用与敏感 API 摘要作为等价锚点,写入 E-imports / E-triage-imports 语义槽
**干净导入表**:仅基础 DLL、几乎无业务 API → MUST 注明动态加载嫌疑(LoadLibrary/GetProcAddress),SHOULD 转入 Phase 3 抓内存 API
用户要求「重做导入表检查」:MUST 重做本项,禁止改换其他步骤冒充完成
□ 资源段 → 嵌入 Payload(.rsrc 节)
□ 字符串表 → URL/C2/文件路径/Base64 blob
@@ -81,6 +106,12 @@ sha256sum sample.exe
□ 网络: HTTP/DNS → C2 通信
□ 内存: VirtualAllocEx → 进程注入
□ 服务: CreateService → 持久化
□ IAT 修复失败样本:在敏感 API 下断点 / 硬件执行断点 / 内存搜索捕捉真实导入
无行为应急分支(MUST):
□ 沙箱无行为、秒退或无限休眠 → 检查反调试/反虚拟机(CPUID、计时、环境特征)
□ 尝试硬件断点绕过、补丁检测点、或换物理机/更高保真环境
□ 将「无行为 + 条件」写入 Evidence;禁止无条件写成「样本无害」
```
### Phase 4: YARA 规则编写
@@ -221,11 +252,14 @@ Triage RE Behav Intel Detect Remed
- `references/yara-sigma-rules.md` — YARA + Sigma 编写方法论
- `references/sandbox-orchestration.md` — 沙箱编排与自动化
- `references/anti-analysis-techniques.md` — 94 种反分析技术检测
- `../reverse-engineering/references/re-agent-workflow.md` — IAT 铁律与六阶段门闩(Issue #65)
## 任务完成自检(声称完成前 MUST 通过)
- [ ] 我是否执行了工作流中的每一步(而不是只阅读)?
- [ ] 导入表 MUST 检查是否已执行并写入 Evidence(E-imports)?重做请求是否回到同一步?
- [ ] 导入表 MUST 检查是否已执行并写入 Evidence(E-imports 或 .NET 等价锚点)?DLL/SYS 是否含 E-exports?
- [ ] 若 IAT 修复失败:是否记录 E-iat-repair-fail 并转入动态,而非静态死磕或静默跳过?
- [ ] 重做请求是否回到被点名的同一步?干净导入表/沙箱无行为是否按旁路处理?
- [ ] 我是否基于 `tool-index` 使用了真实工具路径?
- [ ] 我是否产出了可复现证据(命令/脚本/截图/报告)?
- [ ] 我是否完成并回写了 RULES 要求的 Checklist 项?
+9 -4
View File
@@ -124,14 +124,17 @@ ERROR: Cannot find ...\share\format\dll\*.sdb
对 PE/ELF/Mach-O 等含导入表的二进制,**MUST** 先完成导入表检查并落成 Evidence,再进入函数级分析或动态步骤:
1. 执行 `rabin2 -i <sample>`(或 `recon.ps1` 输出中的 imports 段)
1. 执行 `rabin2 -i <sample>`(或 `recon.ps1` 输出中的 imports 段);DLL/SYS 另 MUST `rabin2 -E` 并记 `E-exports`
2. 将完整/分类后的导入表结果写入 Evidence(建议 id:`E-imports` 或 `E-triage-imports`),至少包含:
- 复现命令(`repro_command`)
- 关键导入分类摘要:网络 / 文件 / 加密 / 进程注入 / 注册表 / 其他可疑 API
- 若导入表为空、解析失败或工具报错:仍 MUST 记录失败现象与原始输出为 Evidence,**不得静默跳过**
3. 用户明确要求「重做导入表检查 / 重新检查导入表」时:MUST 重做本硬门步骤本身,**禁止改换为其他步骤冒充完成**
- 导入表「过干净」(仅基础 DLL):MUST 注明动态加载嫌疑,SHOULD 转入动态抓 API
3. .NET 等无传统 IAT:MUST 走等价锚点(dnSpy/IL/元数据摘要)写入同一 Evidence 语义槽,禁止空过
4. 加壳样本 IAT 修复:x86 用 ImportREC(或等价)、x64 用 Scylla(或等价)。修复失败 MUST 记 `E-iat-repair-fail` 后转动态 API 断点;**禁止**在静态 IAT 上无限死磕(见 `reverse-engineering/references/re-agent-workflow.md` §1.2)
5. 用户明确要求「重做导入表检查 / 重新检查导入表 / 重做 IAT」时:MUST 重做被点名步骤本身,**禁止改换为其他步骤冒充完成**
未记录导入表 Evidence 前:MUST NOT 声称「基础侦察完成」,MUST NOT 进入工作流 2+ 的深挖结论。
未记录导入表(或合法等价锚点 / IAT 失败旁路)Evidence 前:MUST NOT 声称「基础侦察完成」,MUST NOT 进入工作流 2+ 的深挖结论。
优先直接运行内置脚本:
@@ -370,6 +373,7 @@ rax2 -s hello
- 不要在未说明风险时直接写模式打开用户文件
- 不要在还没做基础侦察前就下结论
- **禁止跳过导入表检查**(`rabin2 -i` / recon imports):未写入 Evidence 不得进入下一步;用户要求重做导入表时禁止改做其他步骤
- **禁止 IAT 修复失败后静态死磕**:记 `E-iat-repair-fail` 后转动态;禁止 64 位样本只用 ImportREC
- 不要把网页 JS 逆向误导到这个 skill;那是 `reverse-engineering` 的范围
## 参考资料
@@ -421,7 +425,8 @@ rax2 -s hello
## 任务完成自检(声称完成前 MUST 通过)
- [ ] 我是否执行了工作流中的每一步(而不是只阅读)?
- [ ] 导入表检查是否已执行且写入 Evidence(E-imports / E-triage-imports)?若用户要求重做,是否重做了同一步而非换步骤?
- [ ] 导入表检查是否已执行且写入 Evidence(E-imports / E-triage-imports 或 .NET 等价)?DLL/SYS 是否含 E-exports?
- [ ] IAT 修复失败是否记录 E-iat-repair-fail 并转动态?重做请求是否回到同一步?
- [ ] 我是否基于 `tool-index` 使用了真实工具路径?
- [ ] 我是否产出了可复现证据(命令/脚本/截图/报告)?
- [ ] 我是否完成并回写了 RULES 要求的 Checklist 项?
@@ -1,8 +1,8 @@
# RE Agent 工作流门闩(静态↔动态)
> 来源启发:binary-re 阶段划分、社区 RE skill(Frida/r2/Ghidra/IDA 循环)、Cerberus 三头环(静/动/插桩)
> 日期:2026-07-17
> 适用:`reverse-engineering/`、`ida-reverse/`、`radare2/`、与 cre 角色交接
> Issue #65 增量:IAT 修复铁律、恶意样本六阶段映射、.NET/DLL·SYS 等价路径(2026-08-12)
> 适用:`reverse-engineering/`、`ida-reverse/`、`radare2/`、`malware-analysis/`、与 cre 角色交接
## 0. 启动
@@ -12,55 +12,119 @@
□ 角色:cre(ops/role-map)
```
## 1. Triage(5–15 分钟)
## 1. Triage(5–15 分钟 · 强制起点)
```text
□ file / DIE / 熵 / 壳特征
□ 计算样本 Hash(MD5/SHA256)→ 唯一 ID
□ 识别文件类型:EXE / DLL / SYS / ELF / Mach-O / .NET / 脚本 等
□ file / DIE / 熵 / 壳特征(PEiD / DIE / Exeinfo 等)
□ 架构:x86 / x64 / ARM;编译语言线索(VC++ / Delphi / .NET / Go / Rust)
□ 加壳类型线索:UPX / ASPack / VMProtect / Themida / 未知混淆
□ strings / rabin2 -z 捡漏
□ 架构/链接/是否 .NET/Go/Rust/加壳
□ MUST 导入/导出表:rabin2 -i / -E(或 IDA imports / 等价物)
□ 产出:E-triage(MUST 含 imports 分类摘要:网络/文件/加密/注入/注册表)+ 假设清单(勿过早下结论)
□ MUST 导入/导出锚点(见下方「导入表硬门与等价路径」)
□ 产出:E-triage(MUST 含 imports 或等价锚点分类摘要)+ 假设清单(勿过早下结论)
```
**阶段门闩(Triage → Static/Dynamic)**:E-triage 中未记录 imports 摘要前,MUST NOT 进入 Dynamic,也 MUST NOT 声称「基础分诊完成」。导入表解析失败时仍 MUST 把失败输出写入 Evidence,不得跳过。用户要求「重做导入表检查」时 MUST 重做 imports 步骤本身,禁止改换其他分析步骤。
**阶段门闩(Triage → Static/Dynamic)**:E-triage 中未记录 imports **或** 合法等价锚点摘要前,MUST NOT 进入 Dynamic(除非已记录 IAT 修复失败并选择动态旁路,见 §1.2),也 MUST NOT 声称「基础分诊完成」。解析失败时仍 MUST 把失败输出写入 Evidence,不得跳过。用户要求「重做导入表检查」时 MUST 重做 imports/等价步骤本身,禁止改换其他分析步骤。
## 2. Static
### 1.1 导入表硬门与等价路径
| 样本类型 | MUST 锚点(Evidence) | 说明 |
|----------|----------------------|------|
| 原生 PE/ELF/Mach-O(IAT 可读) | `E-imports` / `E-triage-imports`:导入分类摘要 | `rabin2 -i` / IDA imports / 等价 |
| DLL / SYS / 共享库 | **并列** `E-imports` + `E-exports`(`rabin2 -i` + `rabin2 -E`) | 导出表优先级等同导入表(对外入口) |
| .NET 托管(无传统 IAT) | **等价路径**:dnSpy/IL/元数据/程序集引用与敏感 API 摘要 → 仍写入 `E-imports` 或 `E-triage-imports` 语义槽 | **禁止** 因「没有 IAT」而空过硬门;dnSpy 查看 = 原生「查导入表」 |
| 导入表解析失败 / 为空 | 仍记失败输出为 Evidence | 不得静默跳过 |
**干净导入表警告(MUST 提醒)**:若导入表「过干净」(仅 kernel32/ntdll 等基础 DLL、几乎无业务 API),高度怀疑 `LoadLibrary` + `GetProcAddress` 动态加载 → 在 Evidence 注明嫌疑,并 **SHOULD** 转入 Dynamic 抓取内存 API;不得仅凭静态 IAT 宣称「无网络/无文件能力」。
### 1.2 脱壳与 IAT 处理(高风险分岔 · Issue #65)
```text
分支 A:无壳 / .NET 托管
→ 直接进入 §2 Static(.NET 走等价锚点)
分支 B:有壳 / 强混淆
Step 1:尝试脱壳(自动脱壳机 / 手动找 OEP)— 须在授权与隔离环境
Step 2:尝试修复 IAT
工具:x86 → ImportREC(或等价);x64 → Scylla(或等价)。禁止 64 位样本死磕 ImportREC。
情况 B1:修复成功且可解析 → 记 E-imports(修复后)→ §2 Static
情况 B2:ImportREC/Scylla 报错、修复后无法运行、或 IAT 全乱码(VMP/加密壳)
→ 【IAT 修复铁律】立即终止继续静态 IAT 修复
→ MUST 记录 E-iat-repair-fail(命令、工具、失败现象、决定转动态)
→ ⏩ 直接进入 §3 Dynamic:API 断点 / 硬件执行断点 / 内存搜索抓取导入
→ 这不算「跳过导入表」:导入表路径已尝试并记 Evidence
```
**IAT 修复铁律(MUST)**:优先尝试自动/半自动修复;一旦修复工具报错或修复后程序无法运行,**立即停止**在静态导入表上死磕,切换动态调试,用 API 断点(如 `bp CreateFile` / 关键网络 API)在运行时捕获导入函数。
## 2. Static(基础静态锚点 → 深挖)
| 工具 | 何时 |
|------|------|
| radare2 / rabin2 | 快速函数/导入/字符串(imports 已在 Triage MUST 完成) |
| radare2 / rabin2 | 快速函数/导入/字符串(imports 已在 Triage MUST 完成或已记失败旁路) |
| IDA / Ghidra(MCP 或 headless) | 深挖、交叉引用、类型;survey 阶段复核 imports 分类 |
| jadx / dnSpy | Android / .NET |
| OLLVM 文档 | 控制流平坦化怀疑 |
```text
□ 确认 E-imports / E-triage 已含导入表 Evidence(缺失则先补,禁止后置)
□ 定位关键函数(加密/校验/网络/授权)
□ 记录地址/符号 → Evidence
□ 一条路不通 → 换工具(IDA?r2?Ghidra)
□ 确认 E-imports / E-triage 已含导入表或等价锚点 Evidence(缺失则先补,禁止后置)
□ 若 DLL/SYS:确认 E-exports 已记录
□ 敏感 API 分组:网络/WinHTTP、文件/CreateFile、进程/远程线程、注册表/服务
□ 硬编码域名/IP/URL 字符串;资源节是否藏 Payload
□ 定位关键函数(加密/校验/网络/授权)→ 地址/符号写入 Evidence
□ 一条路不通 → 换工具(IDA↔r2↔Ghidra)
```
**无 MCP 时**:可用导出反编译文本再分析(对照 P4nda0s reverse-skills / IDA-NO-MCP 思路),仍写 Evidence 路径。
## 3. Dynamic
## 3. Dynamic(交叉验证循环区)
核心理念:**静态提供线索 → 动态验证 → 验证卡壳 → 回静态重审**(无固定唯一顺序)。
```text
□ Frida / gdb / emulator:验证静态假设
□ Frida / x64dbg / gdb / emulator:验证静态假设
□ 敏感 API 断点、单步跟踪栈/寄存器(白盒)
□ 行为监控:沙箱 / Procmon / RegShot(黑盒)
□ IAT 修复失败样本:硬件执行断点或内存搜索强行捕捉 API
□ 反调试/反 Frida → reverse-engineering/anti-analysis
□ Android:root 检测 / SSL pinning 绕过脚本按需生成,**须在授权设备**
□ 崩溃日志驱动下一轮 hook(自适应循环)
```
## 4. Synthesis
### 3.1 沙箱 / 动态无行为应急分支(MUST)
```text
□ Finding:算法/校验逻辑/可利用点
无行为或立刻退出 / 无限休眠
→ 检查反调试 / 反虚拟机例程(CPUID、高精度计时、沙箱特征等)
→ 尝试硬件断点绕过、修补检测点、或换物理机/更高保真环境
→ 将「无行为 + 疑似 anti-VM」写入 Evidence,禁止写成「样本无害」而不加条件
```
## 4. Synthesis(IOC / 攻击链 / 报告)
```text
□ Finding:算法/校验逻辑/可利用点 / 行为结论
□ Path:callflow 或 solve 步骤挂 E-*
□ 报告 docs-generator + 可选图
□ IOC:网络指纹 + 主机指纹(有则表;无则 n/a+原因)
□ 报告 docs-generator(malware/apt/null/vuln overlay 按任务选型)+ 可选图
□ 可选:YARA / Snort·Suricata 规则化沉淀
□ field-journal 脱敏
```
## 5. 与「堆 RE skill 插件」的差异
## 5. 六阶段实战映射(Issue #65 思维导图 → 本文件)
| 实战阶段 | 本文件章节 | 硬门 / 铁律 |
|----------|------------|-------------|
| 1 初步快速研判 | §0–§1 Triage | Hash、架构、文件类型、查壳;imports/等价锚点 |
| 2 脱壳与 IAT | §1.2 | IAT 修复铁律;失败 → E-iat-repair-fail → Dynamic |
| 3 基础静态锚点 | §2 Static | 仅 IAT 正常或等价锚点已记录后深挖 |
| 4 深度交叉验证 | §3 Dynamic | 静↔动循环;无行为应急分支 |
| 5 提取 IoC 与攻击链 | §4 Synthesis | IOC + Kill Chain / Path |
| 6 归档与规则化 | §4 + docs-generator / YARA | 结构化报告;规则可选 |
## 6. 与「堆 RE skill 插件」的差异
- 本包用 **阶段门闩 + tool-index**,不默认启用 Hex-Rays「unsafe 全自动执行」类插件
- 动态插桩默认 **offline/lab** network_profile
- 动态插桩默认 **offline/lab** network_profile
- IAT/导入表:**尝试 + 记录** 优先于「无限静态死磕」或「静默跳过」
+21 -5
View File
@@ -28,7 +28,23 @@ function Bad([string] $m) {
[void]$fail.Add($m)
}
Write-Host ("=== reverse-skill smoke | LogDir={0} ===" -f $LogDir)
# Prefer the same host that launched smoke (pwsh on GHA windows-latest).
# Bare "powershell" often resolves to Windows PowerShell 5.1, which mis-parses
# UTF-8 scripts without BOM when nested from pwsh.
$SmokeHostExe = $null
try {
$procPath = (Get-Process -Id $PID -ErrorAction Stop).Path
if ($procPath -and (Test-Path -LiteralPath $procPath)) { $SmokeHostExe = $procPath }
} catch { }
if (-not $SmokeHostExe) {
$cmd = Get-Command pwsh -ErrorAction SilentlyContinue
if ($cmd -and $cmd.Source) {
$SmokeHostExe = $cmd.Source
} else {
$SmokeHostExe = Join-Path $env:SystemRoot 'System32\WindowsPowerShell\v1.0\powershell.exe'
}
}
Write-Host ("=== reverse-skill smoke | LogDir={0} | Host={1} ===" -f $LogDir, $SmokeHostExe)
# --- 1) routing coherence ---
$verify = Join-Path $scriptDir 'verify-routing-coherence.ps1'
@@ -37,7 +53,7 @@ if (-not (Test-Path -LiteralPath $verify)) {
$verifyExit = 1
} else {
$vLog = Join-Path $LogDir '01-verify.txt'
& powershell -NoProfile -ExecutionPolicy Bypass -File $verify 2>&1 | Tee-Object -FilePath $vLog | Out-Null
& $SmokeHostExe -NoProfile -ExecutionPolicy Bypass -File $verify 2>&1 | Tee-Object -FilePath $vLog | Out-Null
$verifyExit = $LASTEXITCODE
if ($verifyExit -eq 0) { Ok 'verify-routing-coherence exit 0' } else { Bad ("verify-routing-coherence exit {0}" -f $verifyExit) }
}
@@ -106,7 +122,7 @@ if (-not (Test-Path -LiteralPath $mr)) {
} else {
foreach ($c in $cases) {
$outFile = Join-Path $LogDir ("route-{0}.txt" -f $c.Name)
$raw = & powershell -NoProfile -ExecutionPolicy Bypass -File $mr -Hint $c.Hint 2>&1 | Out-String
$raw = & $SmokeHostExe -NoProfile -ExecutionPolicy Bypass -File $mr -Hint $c.Hint 2>&1 | Out-String
$raw | Set-Content -Path $outFile -Encoding UTF8
if ($raw -match [regex]::Escape($c.Expect)) {
Ok ("route {0} -> {1}" -f $c.Name, $c.Expect)
@@ -128,7 +144,7 @@ if (-not (Test-Path -LiteralPath $appendEvidence)) {
Bad 'append-evidence.ps1 missing for immutability check'
} else {
New-Item -ItemType Directory -Path $evidenceCase -Force | Out-Null
& powershell -NoProfile -ExecutionPolicy Bypass -File $appendEvidence `
& $SmokeHostExe -NoProfile -ExecutionPolicy Bypass -File $appendEvidence `
-CaseRoot $evidenceCase `
-Id 'E-IMMUTABLE' `
-Title 'first write' `
@@ -142,7 +158,7 @@ if (-not (Test-Path -LiteralPath $appendEvidence)) {
$beforeEvidence = (Get-FileHash -LiteralPath $evidencePath -Algorithm SHA256).Hash
$beforeIndex = (Get-FileHash -LiteralPath $indexPath -Algorithm SHA256).Hash
& powershell -NoProfile -ExecutionPolicy Bypass -File $appendEvidence `
& $SmokeHostExe -NoProfile -ExecutionPolicy Bypass -File $appendEvidence `
-CaseRoot $evidenceCase `
-Id 'E-IMMUTABLE' `
-Title 'second write' `
+12 -2
View File
@@ -178,7 +178,7 @@ Assert-Fields (Join-Path $skillsRoot 'ops/timeline-workitem.md') @('timeline.md'
Assert-Fields (Join-Path $skillsRoot 'ops/role-map.md') @('lead', 'cie', 'cpe', 'cre', 'Handoff')
Assert-Fields (Join-Path $skillsRoot 'ops/skill-supply-chain.md') @('AST10', 'MCP', 'bootstrap', 'MUST')
Assert-Fields (Join-Path $skillsRoot 'references/community-security-skills.md') @('trailofbits', 'agentskills.io', 'MUST', '2026-07')
Assert-Fields (Join-Path $skillsRoot 'reverse-engineering/references\re-agent-workflow.md') @('Triage', 'Static', 'Dynamic', 'Synthesis')
Assert-Fields (Join-Path $skillsRoot 'reverse-engineering/references\re-agent-workflow.md') @('Triage', 'Static', 'Dynamic', 'Synthesis', 'IAT 修复铁律', 'E-iat-repair-fail', 'E-exports', 'dnSpy')
Assert-Fields (Join-Path $skillsRoot 'pentest-tools/references\recon-pipeline.md') @('auth.status', 'network_profile', 'Evidence', 'nuclei')
Assert-Fields (Join-Path $skillsRoot 'docs-generator/references\security-report-templates.md') @('Evidence Chain', 'Findings', 'Path')
Assert-Fields (Join-Path $skillsRoot 'field-journal/_template.md') @('Scope', 'Evidence', 'Finding')
@@ -202,7 +202,17 @@ if ($vendorRulesText -match '(?m)JS/Web 签名逆向报告\s*\|[^\r\n]*malware')
} else {
Ok 'vendor rules keep JS signature reports flavor-neutral'
}
Assert-Fields $vendorRulesPath @('skills/ops/evidence-finding-path.md', '来源证据', 'securelist.com/updated-mata', 'www.huorong.cn')
Assert-Fields $vendorRulesPath @('skills/ops/evidence-finding-path.md', '来源证据', 'securelist.com/updated-mata', 'www.huorong.cn', 'thin overlay', 'vuln')
Assert-Fields (Join-Path $skillsRoot 'malware-analysis/SKILL.md') @('IAT 修复铁律', 'E-iat-repair-fail', 'E-exports')
Assert-Fields (Join-Path $skillsRoot 'docs-generator/references\security-report-templates.md') @('thin `vuln`', '1c. 漏洞技术分析')
if ($vendorRulesText -match '(?m)vuln.*默认全文' -or $vendorRulesText -match '第 3 个默认全文 flavor') {
# presence of explicit "not third default" language is OK; flag only if it claims vuln IS a third default full flavor
}
if ($vendorRulesText -match '仅 2 个厂商全文 flavor' -or $vendorRulesText -match '不是.*第 3 个默认全文 flavor') {
Ok 'vendor rules keep vuln as thin overlay not third default flavor'
} else {
Bad 'vendor rules missing vuln thin-overlay constraint'
}
$fieldLog | Set-Content -LiteralPath (Join-Path $ScratchDir 'template-fields.txt') -Encoding UTF8
# --- role map skills exist for primary rows ---