Skip to content
Back to skills

Asm Analysis

BSecurity

深度汇编代码逆向分析技能,专注 Linux 环境动态调试与静态分析协同。自动协调 GDB/LLDB/r2/Frida/angr/strace/ltrace/perf/bpftrace 等工具完成完整分析链路。内置上下文记忆机制:每 10 轮自动生成分析快照 skill,保持长对话连续性并降低幻觉。触发词:汇编分析、逆向工程、GDB、r2、radare2、frida、动态调试、二进制分析、ELF 分析、加密算法识别、编译器优化、混淆脱壳、struct 恢复、调试、strace、ltrace、内存分析等。

  • 34 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 24, 2026
ai-agentspythongoshellbashtestingdebuggingsecuritydocumentation

Works with

  • mcp

Security analysis

B88/100
  • criticalAccesses sensitive system or user directories

Pro scans all 13 files and shows the line behind each finding

Scanned September 24, 2026

npx -y skills add alicewe1/alice_skill --skill asm-analysis --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Asm Analysis?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Asm Analysis
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/alicewe1-asm-analysis/badge)](https://www.skillsdirectory.com/skills/alicewe1-asm-analysis)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: asm-analysis
description: >
  深度汇编代码逆向分析技能,专注 Linux 环境动态调试与静态分析协同。自动协调 GDB/LLDB/r2/Frida/angr/strace/ltrace/perf/bpftrace 等工具完成完整分析链路。内置上下文记忆机制:每 10 轮自动生成分析快照 skill,保持长对话连续性并降低幻觉。触发词:汇编分析、逆向工程、GDB、r2、radare2、frida、动态调试、二进制分析、ELF 分析、加密算法识别、编译器优化、混淆脱壳、struct 恢复、调试、strace、ltrace、内存分析等。
x-alice-class: assist
---

# 汇编分析优化技能 (asm-analysis)

## 完整工作流

```
阶段 0   架构确认 + 白皮书加载
   ↓
阶段 T   工具协调(Linux 调试环境全量探测与任务分派)★ 核心强化
   ↓
阶段 O   混淆与加壳检测(UPX/OLLVM/VMProtect 识别与处置)
   ↓
阶段 1   算法特征识别(加密/哈希/压缩 宏观扫描)
   ↓
阶段 2   文件编译信息提取(编译器/优化级别/安全标志)
   ↓
阶段 D   数据结构恢复(vtable/struct 布局/类型重建)
   ↓
阶段 3   逐块分析(指令注释 + 伪代码生成)
   ↓
阶段 4   持续分析协议
   ↓
阶段 5   综合报告
   ↓
阶段 M   记忆机制(每 10 轮自动生成上下文快照 skill)★ 新增
```

**跳过规则**:
- 仅代码片段 → 跳过 T.1 环境探测,直接 T.3 生成命令
- 无可执行文件 → 跳过阶段 O(脱壳需运行)
- 无 OOP 特征 → 跳过阶段 D vtable 分析

---

## 阶段 0:启动协议

### 架构确认
```
请问要分析的代码属于哪种架构?
  [A] x86 / x86-64    [B] ARM64 / AArch64    [C] 其他
```
上下文有明显架构特征时可直接确认并等待认可。

### 白皮书加载(URL 索引见 references/whitepaper-urls.md)

- **x86**:Intel SDM Vol.2 → https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
- **ARM64**:ARM DDI 0487 → https://developer.arm.com/documentation/ddi0487/latest

**拒绝加载时必须输出(不可跳过):**
> ⚠️ 未加载权威指令手册:SIMD 指令语义误判风险高,内存序语义(rep movs/stlr/ldar)可能歧义,伪代码可能与实际行为偏差。继续,保留此风险提示。

---

## 阶段 T:Linux 动态调试协调(Tool Orchestration)★

> 详细命令手册见 `references/tool-commands.md`
> Linux 专项调试流程见 `references/linux-debug-workflows.md`
> Frida 脚本库见 `references/frida-scripts.md`
> angr 工作流见 `references/angr-workflows.md`

### T.1 — Linux 调试环境全量探测

```bash
# ── 调试器 ──
for t in gdb lldb; do
  which $t 2>/dev/null && $t --version 2>&1 | head -1 || echo "$t: not found"
done

# GDB 插件检测
python3 -c "
import subprocess, os
for plugin in ['pwndbg','gef','peda']:
    r = subprocess.run(['gdb','-batch','-ex',f'python import {plugin}'],
        capture_output=True, text=True)
    print(plugin, 'ok' if r.returncode==0 else 'not found')
" 2>/dev/null

# ── 静态分析 ──
for t in r2 objdump readelf nm strings file rabin2; do
  which $t 2>/dev/null && echo "$t: ok" || echo "$t: not found"
done
r2 -q -c 'pdg 1 @ 0' /dev/null 2>/dev/null | grep -q ghidra && echo "r2ghidra: ok" || echo "r2ghidra: not found"

# ── Linux 动态追踪工具 ──
for t in strace ltrace perf valgrind bpftrace systemtap addr2line eu-stack; do
  which $t 2>/dev/null && $t --version 2>&1 | head -1 || echo "$t: not found"
done

# ── 符号执行 / 动态插桩 ──
python3 -c "import frida; print('frida:', frida.__version__)" 2>/dev/null || echo "frida: not found"
python3 -c "import angr;  print('angr:',  angr.__version__)"  2>/dev/null || echo "angr: not found"

# ── 系统环境 ──
uname -a
cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null && echo "(ptrace_scope)" || true
cat /proc/sys/kernel/randomize_va_space 2>/dev/null && echo "(ASLR)" || true
cat /proc/sys/kernel/perf_event_paranoid 2>/dev/null && echo "(perf_paranoid)" || true

# ── core dump 配置 ──
ulimit -c
cat /proc/sys/kernel/core_pattern 2>/dev/null || true
```

输出格式:
```
🔧 Linux 调试环境
  调试器  : GDB 13.2 [pwndbg] / LLDB 15.0
  静态    : r2 5.8.8 [r2ghidra] / objdump / readelf / rabin2
  追踪    : strace 6.1 / ltrace 0.7.3 / perf 6.1 / bpftrace 0.18
  插桩    : Frida 16.2.1 / angr 9.2.90
  Valgrind: 3.21.0
  内核    : 6.1.0-amd64 | ASLR=2 | ptrace_scope=1 | perf_paranoid=2
  core    : ulimit=-1 | pattern=/tmp/core.%e.%p
```

### T.2 — 工具选择策略(Linux 优先级)

| 分析目标 | 首选 | 辅助 |
|---------|------|------|
| 通用动态调试 | GDB + pwndbg | r2(静态补充) |
| 系统调用追踪 | strace | ltrace(库函数) |
| 内存错误检测 | Valgrind (memcheck) | GDB watchpoint |
| 函数调用追踪 | ltrace / Frida | GDB breakpoints |
| 性能热点 | perf record + report | GDB profiling |
| 内核态追踪 | bpftrace / perf | systemtap |
| 符号执行 | angr | GDB + Python |
| 纯静态 stripped | r2 aaa | angr CFGFast |
| 多线程调试 | GDB thread cmds | Helgrind (Valgrind) |
| core dump 分析 | GDB + core | eu-stack |
| 动态库 Hook | LD_PRELOAD / Frida | GDB catch load |

**ptrace_scope 限制处理:**
```bash
# scope=1(默认):只能调试子进程,无法附加任意进程
# 临时降低(需 root):
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope

# 永久(不推荐):
# echo 'kernel.yama.ptrace_scope = 0' >> /etc/sysctl.d/10-ptrace.conf

# 非 root 替代方案:用 gdb -f ./target 直接启动
```

**ASLR 控制:**
```bash
# 关闭 ASLR(当前 shell 子进程)
setarch $(uname -m) -R gdb ./target

# 或 GDB 内
(gdb) set disable-randomization on   # GDB 默认已开启此项
```

### T.3 — 任务驱动命令生成

每次生成命令前说明意图,命令后说明预期输出。

#### 全工具命令速查表

| 任务 | GDB | r2 | strace/ltrace | Frida |
|------|-----|----|----------------|-------|
| 加载并分析 | `gdb -q ./bin` | `r2 -A ./bin` | `strace ./bin` | `frida -f ./bin -l s.js` |
| 函数列表 | `info functions` | `afl` | `ltrace ./bin 2>&1 \| grep -o "^[a-z_]*"` | `Module.enumerateExports()` |
| 反汇编函数 | `disas <fn>` | `pdf @ <fn>` | — | — |
| 断点(地址) | `b *0x<addr>` | `db 0x<addr>` | — | `Interceptor.attach(ptr(...))` |
| 内存查看 | `x/16xb 0x<a>` | `px 16 @ 0x<a>` | — | `hexdump(ptr('0x<a>').readByteArray(16))` |
| 系统调用追踪 | `catch syscall <name>` | — | `strace -e trace=<name>` | `Stalker` |
| 库函数追踪 | `b <func>` | `axt @ <func>` | `ltrace -e <func>` | `Interceptor.attach` |
| 内存 dump | `dump binary memory out.bin s e` | `wtf out.bin sz @ addr` | — | `Memory.readByteArray` |
| 搜索字节 | `find s,+len,bytes` | `/x <hex>` | — | `Memory.scan` |
| 动态库断点 | `b dlopen` | — | `ltrace -e dlopen` | `Module.load` event |
| 进程内存图 | pwndbg `vmmap` | `dm` | `/proc/<pid>/maps` | `Process.enumerateRanges` |
| 线程列表 | `info threads` | — | `strace -f` | `Process.enumerateThreads` |
| 调用栈 | `bt full` | `dbt` | — | `Thread.backtrace` |

#### pwndbg 优先命令(有插件时必用)

```gdb
vmmap                      # 内存映射全览(彩色,清晰)
telescope $rsp 20          # 栈递归指针解引用(20 层)
telescope $rdi 8           # 查看参数指向的数据链
hexdump $rdi 64            # 彩色 hex dump
context                    # 完整上下文(寄存器+栈+反汇编一屏显示)
nearpc 20                  # 当前 PC 前后 20 条指令
got                        # GOT 表当前内容
plt                        # PLT 表
checksec                   # 安全标志汇总
rop --grep "pop rdi; ret"  # ROP gadget 搜索
heap                       # 堆 chunk 状态
bins                       # tcache/fastbin/unsorted 状态
vis_heap_chunks            # 可视化堆布局
threads                    # 线程列表 + 当前状态
```

#### strace 专项命令模板

```bash
# 基础系统调用追踪(含时间戳)
strace -tt -T ./target 2>&1 | tee /tmp/strace.log

# 只追踪文件相关系统调用
strace -e trace=file ./target

# 只追踪网络相关
strace -e trace=network ./target

# 追踪内存操作(mmap/mprotect/brk)
strace -e trace=memory ./target

# 追踪信号
strace -e trace=signal ./target

# 跟踪子进程(-f)+ 附加到 pid
strace -f -p <pid>

# 统计系统调用次数和耗时
strace -c ./target

# 输出到文件(每个进程/线程独立文件)
strace -ff -o /tmp/strace_out ./target
# 生成 /tmp/strace_out.<pid> 文件

# 在特定系统调用时注入失败(fault injection)
strace --inject=open:error=ENOENT ./target

# 解码结构体(-v 详细,-s 字符串长度)
strace -v -s 256 ./target
```

#### ltrace 专项命令模板

```bash
# 追踪所有库函数调用
ltrace ./target

# 只追踪特定函数
ltrace -e strcmp -e memcmp -e strncmp ./target

# 追踪加密相关函数
ltrace -e EVP_* -e AES_* -e RSA_* -e MD5_* ./target

# 附加到运行中进程
ltrace -p <pid>

# 含时间戳 + 详细输出
ltrace -tt -T -n 2 ./target

# 跟踪子进程
ltrace -f ./target

# 统计调用次数
ltrace -c ./target

# 显示库函数的完整参数(含结构体)
ltrace -b -S ./target    # -b: 抑制信号,-S: 显示系统调用
```

#### perf 专项命令模板

```bash
# 记录函数调用图(频率采样)
perf record -g -F 999 ./target
perf report --stdio

# 追踪特定事件(cache miss / branch miss)
perf stat -e cache-references,cache-misses,branches,branch-misses ./target

# 追踪系统调用(perf trace = strace 加强版)
perf trace ./target
perf trace -e 'syscalls:sys_enter_*' ./target

# 动态探针(无需修改源码,类似 kprobe)
# 在函数入口处插入探针
perf probe -x ./target --add 'target_func'
perf record -e probe_target:target_func -g ./target
perf script

# 火焰图生成
perf record -F 99 -g -- ./target
perf script | stackcollapse-perf.pl | flamegraph.pl > flame.svg

# 内核函数追踪
sudo perf record -e 'syscalls:sys_enter_read' -ag sleep 5
```

#### bpftrace 专项命令(内核级追踪)

```bash
# 追踪某进程所有系统调用
sudo bpftrace -e '
  tracepoint:syscalls:sys_enter_* /pid == <PID>/ {
    printf("%s\n", probe);
  }
'

# 追踪 malloc/free(用户空间探针)
sudo bpftrace -e '
  uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc {
    printf("malloc(%d) pid=%d\n", arg0, pid);
  }
  uprobe:/lib/x86_64-linux-gnu/libc.so.6:free {
    printf("free(%p) pid=%d\n", arg0, pid);
  }
'

# 追踪特定函数的参数(字符串类型)
sudo bpftrace -e '
  uprobe:./target:strcmp {
    printf("strcmp(%s, %s)\n", str(arg0), str(arg1));
  }
'

# 统计系统调用频率(10 秒)
sudo bpftrace -e '
  tracepoint:syscalls:sys_enter_* { @[probe] = count(); }
  interval:s:10 { print(@); clear(@); }
'

# 追踪 mprotect(检测动态解码/脱壳)
sudo bpftrace -e '
  tracepoint:syscalls:sys_enter_mprotect /pid == <PID>/ {
    printf("mprotect addr=%lx len=%lu prot=%d\n", args->addr, args->len, args->prot);
  }
'
```

#### Valgrind 专项

```bash
# 内存错误检测(最常用)
valgrind --tool=memcheck --leak-check=full --track-origins=yes \
  --show-reachable=yes ./target 2>&1 | tee /tmp/valgrind.log

# 只报告明确泄漏(减少噪音)
valgrind --leak-check=full --show-leak-kinds=definite ./target

# 调用图分析(callgrind)
valgrind --tool=callgrind ./target
callgrind_annotate callgrind.out.<pid>

# 堆分析(massif)
valgrind --tool=massif --pages-as-heap=yes ./target
ms_print massif.out.<pid>

# 多线程竞态检测(helgrind)
valgrind --tool=helgrind ./target
```

#### /proc 文件系统集成

```bash
# 实时内存映射(比 vmmap 更原始,无需 debugger)
cat /proc/<pid>/maps

# 直接读取进程内存(需 root 或 ptrace 权限)
dd if=/proc/<pid>/mem bs=1 skip=$((0x401000)) count=256 2>/dev/null | xxd

# 文件描述符
ls -la /proc/<pid>/fd

# 命令行参数 + 环境变量
cat /proc/<pid>/cmdline | tr '\0' ' '
cat /proc/<pid>/environ | tr '\0' '\n'

# 信号状态(哪些信号被屏蔽/挂起)
cat /proc/<pid>/status | grep -E "Sig|Threads|VmRSS"

# 打开的文件 + 网络连接
cat /proc/<pid>/net/tcp
cat /proc/<pid>/net/tcp6
```

#### core dump 分析工作流

```bash
# 1. 开启 core dump(当前 shell)
ulimit -c unlimited
echo '/tmp/core.%e.%p' | sudo tee /proc/sys/kernel/core_pattern

# 2. 运行触发崩溃的程序(或复现已知崩溃)
./target <crashing_input>  # 生成 /tmp/core.target.<pid>

# 3. GDB 加载 core
gdb ./target /tmp/core.target.<pid>
(gdb) bt full              # 查看崩溃时的完整调用栈
(gdb) info registers       # 崩溃时寄存器状态
(gdb) x/32xb $rsp          # 崩溃时栈内容
(gdb) info frame           # 当前帧信息
(gdb) x/i $rip             # 崩溃指令

# 4. eu-stack(elfutils,更快的调用栈)
eu-stack -p <pid>         # 在线 backtrace
eu-stack -c core.<pid>    # 从 core 分析

# 5. 自动化 core 分析脚本
gdb -batch -ex "bt full" -ex "info registers" -ex "x/32xb \$rsp" \
    -ex quit ./target /tmp/core.target.<pid> 2>/dev/null
```

#### LD_PRELOAD 动态库注入

```bash
# 创建 hook 库:拦截 strcmp(密码验证绕过示例)
cat > /tmp/hook_strcmp.c << 'EOF'
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <string.h>

int strcmp(const char *s1, const char *s2) {
    typedef int (*orig_strcmp_t)(const char*, const char*);
    orig_strcmp_t orig = dlsym(RTLD_NEXT, "strcmp");
    int ret = orig(s1, s2);
    fprintf(stderr, "[strcmp] \"%s\" vs \"%s\" → %d\n", s1, s2, ret);
    return ret;
}
EOF
gcc -shared -fPIC -o /tmp/hook_strcmp.so /tmp/hook_strcmp.c -ldl

# 注入并运行
LD_PRELOAD=/tmp/hook_strcmp.so ./target <args>

# 追踪 malloc/free
cat > /tmp/hook_alloc.c << 'EOF'
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
void* malloc(size_t sz) {
    typedef void* (*fn_t)(size_t);
    fn_t orig = dlsym(RTLD_NEXT, "malloc");
    void* ret = orig(sz);
    fprintf(stderr, "[malloc] size=%zu → %p\n", sz, ret);
    return ret;
}
void free(void* p) {
    fprintf(stderr, "[free] %p\n", p);
    typedef void (*fn_t)(void*);
    fn_t orig = dlsym(RTLD_NEXT, "free");
    orig(p);
}
EOF
gcc -shared -fPIC -o /tmp/hook_alloc.so /tmp/hook_alloc.c -ldl
LD_PRELOAD=/tmp/hook_alloc.so ./target
```

#### GDB Python 自动化脚本

```python
# gdb_auto_trace.py — source 到 GDB 中
# 追踪所有已知函数,记录调用顺序和参数
import gdb, json

call_log = []
bp_map   = {}

class TraceBreakpoint(gdb.Breakpoint):
    def __init__(self, name, addr=None):
        if addr:
            super().__init__(f"*{hex(addr)}", internal=True)
        else:
            super().__init__(name, internal=True)
        self.func_name = name
        self.silent = True

    def stop(self):
        frame  = gdb.selected_frame()
        rdi = int(gdb.parse_and_eval("$rdi")) if gdb.parse_and_eval else 0
        rsi = int(gdb.parse_and_eval("$rsi")) if gdb.parse_and_eval else 0
        entry = {"fn": self.func_name, "rdi": hex(rdi), "rsi": hex(rsi)}
        call_log.append(entry)
        # 每 50 次调用打印一次摘要
        if len(call_log) % 50 == 0:
            print(f"[trace] {len(call_log)} calls logged so far")
        return False  # 不暂停

def install_traces():
    gdb.execute("set pagination off")
    # 对所有已知符号设置追踪断点
    raw = gdb.execute("info functions", to_string=True)
    for line in raw.split('\n'):
        if '0x' in line:
            parts = line.strip().split()
            if len(parts) >= 2:
                try:
                    addr = int(parts[0], 16)
                    name = parts[-1].rstrip(';')
                    bp = TraceBreakpoint(name, addr)
                    bp_map[addr] = bp
                except:
                    pass
    print(f"[trace] Installed {len(bp_map)} trace breakpoints")

def save_log():
    with open('/tmp/gdb_call_trace.json', 'w') as f:
        json.dump(call_log, f, indent=2)
    print(f"[trace] Saved {len(call_log)} calls to /tmp/gdb_call_trace.json")

# 注册退出时保存
class ExitBreak(gdb.Breakpoint):
    def __init__(self):
        super().__init__("exit", internal=True)
        self.silent = True
    def stop(self):
        save_log()
        return False

install_traces()
ExitBreak()
gdb.execute("run")
```

### T.4 — 输出解析与分析路由

```
工具输出类型路由:
 strace 日志      → 提取 open/read/write/mmap 系统调用序列
                   → 识别密钥文件读取 / 配置文件路径 / 网络连接
 ltrace 日志      → 提取库函数调用序列
                   → 识别 strcmp/memcmp(密码验证)/ EVP/AES(加密)
 perf report      → 找出热点函数(占用 CPU >5% 的函数是分析重点)
 bpftrace 输出    → 低噪音内核级事件,定位 mprotect/mmap 异常行为
 Valgrind 报告    → 内存错误定位(无效读写/泄漏 → 标注到对应代码位置)
 core dump 分析   → 崩溃点寄存器状态 → 结合反汇编定位根因
 GDB 断点输出     → 寄存器快照 → 标注指令执行上下文
 Frida 追踪日志   → 函数参数/返回值 → 辅助算法识别
```

**动态上下文标注格式(统一):**
```
[strace @ open] open("/etc/passwd", O_RDONLY) = 3
    分析     : 程序读取 /etc/passwd,疑似权限检查或用户验证
    关联指令 : 0x401234 call open@PLT → 返回 fd=3
    下一步   : ltrace 追踪后续的 read/strcmp,确认验证逻辑

[GDB @ 0x401260] mov rax, [rbp-0x8]
    寄存器   : rbp=0x7ffd1230, [rbp-0x8]=0x5 (十进制)
    类型推断 : 局部 int,值=5,疑似循环计数器
    下一步   : ni → 观察后续 cmp 指令

[ltrace] strcmp("admin", "root") = -1
    分析    : 硬编码字符串比较,疑似身份验证
    建议    : LD_PRELOAD hook 此 strcmp,伪造返回 0
```

### T.5 — Linux 调试错误诊断与自动修正

| 错误 | 原因 | 处理方案 |
|------|------|---------|
| `ptrace: Operation not permitted` | ptrace_scope=1 | `echo 0 \| sudo tee /proc/sys/kernel/yama/ptrace_scope` 或用 `-f` 启动 |
| `(no debugging symbols found)` | stripped | r2 `aaa`,GDB `b *0x<addr>`,angr CFGFast |
| `Cannot access memory at 0x<addr>` | PIE + ASLR | pwndbg `vmmap` 获取基址后重算,或 `set disable-randomization on` |
| strace `EPERM` | 权限不足 | `sudo strace` 或 `sudo setcap cap_sys_ptrace+ep /usr/bin/strace` |
| perf `Permission denied` | perf_paranoid>0 | `echo -1 \| sudo tee /proc/sys/kernel/perf_event_paranoid` |
| Valgrind `command not found` | 未安装 | `sudo apt install valgrind`,ARM64 改用 `asan` |
| `core file may not match` | 二进制不匹配 | 确认 core 对应的二进制路径,用 `file core.<pid>` 检查 |
| bpftrace `ERROR: No BTF` | 内核版本旧 | 降级用 `perf trace` 替代,或升级内核 |
| r2 分析超时 | 大文件 | `e anal.timeout=30`,改用 `aa` 或 `af @ <addr>` 单函数 |
| angr 路径爆炸 | 循环太多 | `LoopSeer(bound=5)` 或手动 `avoid` 地址 |

**反调试自动 patch(Linux 专项):**
```gdb
catch syscall ptrace
commands
  set $rax = 0
  continue
end
handle SIGTRAP nostop noprint pass

# /proc/self/status TracerPid 绕过(patch 读取结果)
b fgets
commands
  silent
  set $rax = 0   # 伪造读取失败
  return 0
end
```

### T.6 — 工具会话状态追踪

```
🔧 工具会话状态
  主调试器  : GDB 13.2 + pwndbg
  辅助追踪  : strace / ltrace / Frida
  目标文件  : ./target (x86-64 ELF, stripped, PIE, ASLR on)
  基址偏移  : 0x555555554000(本次运行)
  断点列表  : [0x401234 ×GDB, sym.rc4_init ×Frida]
  追踪日志  : strace.log(已收集 312 次系统调用) ltrace.log(已收集 47 次库调用)
  待执行    : [valgrind memcheck, perf record, bpftrace mprotect监控]
  异常标记  : [0x4018cc RDTSC反调试, open("/proc/self/status") 反调试读取]
  对话轮次  : 第 7 轮(距下次快照还有 3 轮)
```

---

## 阶段 O:混淆与加壳检测

> 详细特征库见 `references/obfuscation-patterns.md`

### 快速检测

```bash
python3 -c "
import math, collections, sys
data = open(sys.argv[1],'rb').read()
freq = collections.Counter(data)
h = -sum((c/len(data))*math.log2(c/len(data)) for c in freq.values())
print(f'entropy={h:.4f}', '⚠️ packed' if h > 7.0 else '✅ normal')
" ./target

strings ./target | grep -iE "upx|vmprotect|themida|ollvm"
r2 -q -c 'iS~entropy' ./target 2>/dev/null
```

| 特征 | 工具 | 处置 |
|------|------|------|
| `UPX!` 魔数 | strings | `upx -d` |
| 高熵代码段 + 小 stub | GDB + mprotect 断点 | 动态 dump OEP |
| OLLVM 平坦化:CFG 菊花状 | r2 `VV` | angr Veritesting |
| VMProtect `.vmp0/.vmp1` | r2 段分析 | Frida 追踪 VM loop |
| 字符串加密 decode stub | ltrace / Frida | Hook decode 函数出口 |

---

## 阶段 1:算法特征识别

> 详细特征库见 `references/algorithm-patterns.md`

| 类别 | 算法 | 关键特征 |
|------|------|---------|
| 流密码 | RC4 | 256B S 盒、KSA 双指针、PRGA XOR |
| 流密码 | ChaCha20 | 魔数 `0x61707865`、旋转 16/12/8/7 |
| 分组加密 | AES | S-box `0x63...` 或 `aesenc` 指令 |
| 哈希 | MD5 | 常数 `0xd76aa478`、4×16 步 |
| 哈希 | SHA-256 | `0x428a2f98`、`sha256rnds2` |
| 哈希 | CRC32 | `0xEDB88320` 或 `crc32` 指令 |
| 编码 | Base64 | 64 字符查表 |
| 混淆 | XOR | 固定密钥循环 + 可打印输出 |
| 反调试 | RDTSC | `0F 31` 双调用时间差 |

> 📌 发现特征后立即标注 `[疑似 XXX 算法]` + 置信度 + 依据 + 自动生成验证命令。

---

## 阶段 2:文件编译信息提取

> 详细编译器模式见 `references/compiler-patterns.md`

```bash
file ./target && readelf -h ./target 2>/dev/null
strings ./target | grep -E "(GCC|clang|MSVC): [0-9]"
rabin2 -I ./target 2>/dev/null
```

提取:文件格式 / 架构 / 编译器版本 / 优化级别 / 安全标志(PIE/NX/canary/RELRO/CFI)

> 📌 编译器确定后 web_search 该版本已知优化序列,增强伪代码可靠性。

---

## 阶段 D:数据结构恢复

> 详细方法见 `references/struct-recovery.md`

### vtable 识别
```bash
r2 -A -q -c 'avj' ./target 2>/dev/null  # JSON 输出所有 vtable
```
```asm
; 构造函数特征
lea  rax, [rip + vtable_offset]  ; 加载 vtable
mov  [rdi], rax                   ; this->vptr = vtable
; 虚函数调用
mov  rax, [rdi]                   ; rax = vptr
call [rax + N*8]                  ; 第 N 个虚函数
```

### 结构体字段恢复规则
- `[base + N]` 反复访问 → 字段 N
- 访问大小推断类型:b=uint8 / w=uint16 / d=uint32/float / q=uint64/ptr
- `malloc(M)` 后多字段初始化 → 结构体大小 M
- 相邻偏移间隙 → padding

输出格式(每个结构体):
```c
struct obj_X {
    /* 0x00 */ void*    vptr;
    /* 0x08 */ int32_t  state;
    /* 0x0c */ uint32_t flags;
    /* 0x10 */ void*    handler;  // 函数指针
};  // sizeof = 0x18
```

---

## 阶段 3:逐块分析

### 分析单元:函数边界 → 基本块 → 循环 → 调用图

### 每块输出格式
```
## 函数名(地址范围)[工具来源]

### 原始汇编(行号+注释)
### 动态执行上下文(strace/ltrace/GDB 快照)
### 算法识别(疑似 XXX,置信度,依据)
### 伪代码(C 风格,含类型标注)
### 分析注解(不确定点 [?? 待白皮书验证],建议下一步命令)
```

### 不确定指令处理
1. 初步判断
2. 标注 `[?? 待验证]`
3. web_fetch 查对应手册章节
4. 更新并标注文档来源

---

## 阶段 4:持续分析协议

**除非用户明确终止 / 目标达成 / 重定向,否则分析不停止。**

### 每轮状态报告
```
📊 分析进度
  ✅ 已完成 : [函数/块]     🔄 进行中 : [当前]
  📋 待分析 : [剩余]        ❓ 待解决 : [不确定点]
🔧 工具会话 [T.6 快照]
🧠 记忆机制 : 第 N 轮(距快照还有 X 轮)
```

---

## 阶段 5:综合报告

```
# 分析报告
## 基本信息:架构 / 编译器 / 优化级别 / 安全标志 / 混淆状态
## 识别算法:[名称 | 置信度 | 函数地址 | 动态验证状态]
## 恢复的数据结构:[struct 定义 / vtable 层级]
## 关键函数伪代码索引
## 动态分析汇总:[strace摘要 | ltrace摘要 | perf热点 | Frida追踪结论]
## 未解决的不确定点
## 文档引用
```

---

## 阶段 M:记忆机制(Context Memory)★

> **核心目标**:每 10 轮对话自动生成一份上下文快照,作为新的 skill 文件,下次对话加载后可无缝继续分析,不丢失上下文,降低长对话幻觉。
>
> 快照模板见 `references/context-snapshot-template.md`

### M.1 — 轮次计数

- 在 **T.6 工具会话状态** 中始终显示当前轮次:`对话轮次: 第 N 轮(距下次快照还有 X 轮)`
- **每一条用户消息 = +1 轮**
- 第 10 / 20 / 30 ... 轮:**自动触发 M.2 快照生成**

### M.2 — 快照生成(每 10 轮触发)

触发时,在当前回复末尾追加完整快照块:

````
---
🧠 **第 N 轮上下文快照已生成**

将以下内容保存为 `.skill` 文件(或文本文件),下次对话开始时粘贴,可无缝继续本次分析。

```yaml
# asm-analysis 上下文快照
# 生成于第 N 轮 | 目标: <target_name>
snapshot_version: 1
turn: N

target:
  file: "./target"
  arch: "x86-64"
  format: "ELF"
  compiler: "GCC 11.3 -O2"
  stripped: true
  pie: true
  aslr_base: "0x555555554000"
  security_flags: ["PIE", "NX", "Canary", "Full RELRO"]

tools_confirmed:
  gdb: "13.2 + pwndbg"
  r2: "5.8.8 + r2ghidra"
  strace: "6.1"
  ltrace: "0.7.3"
  frida: "16.2.1"
  angr: "9.2.90"

whitepaper_loaded:
  - "Intel SDM Vol.2 (x86-64指令集参考)"

obfuscation:
  status: "clean"   # clean / upx_stripped / ollvm / vmprotect
  notes: ""

algorithms_found:
  - name: "RC4"
    confidence: "high"
    function: "0x401234 (sym.encrypt_data)"
    validated: true
    notes: "S盒已确认256字节,PRGA XOR输出已Frida dump验证"
  - name: "MD5"
    confidence: "medium"
    function: "0x402000"
    validated: false
    notes: "发现常数0xd76aa478,待动态确认"

structures_recovered:
  - name: "SessionCtx"
    address: "0x602000 (堆分配)"
    size: 0x38
    fields:
      - "0x00: void* vptr"
      - "0x08: int32_t state"
      - "0x10: void* handler"
      - "0x18: char key[16]"
      - "0x28: uint32_t flags"

functions_analyzed:
  completed:
    - "0x401234 sym.encrypt_data (RC4 PRGA,伪代码已生成)"
    - "0x401100 sym.init_session (SessionCtx 构造)"
  pending:
    - "0x402000 sym.hash_password (疑似MD5,待验证)"
    - "0x403000 sym.verify_token"

dynamic_analysis:
  strace_findings:
    - "open('/etc/shadow') → EACCES (权限检查)"
    - "mprotect(0x555..., EXEC) 在 0x401900 处触发(疑似自解码)"
  ltrace_findings:
    - "strcmp('admin', user_input) @ 0x401500"
    - "EVP_EncryptInit_ex 未被调用(确认非OpenSSL)"
  frida_traces:
    - "sym.encrypt_data: arg0=key_ptr arg1=16 arg2=data_ptr arg3=256"

pending_tasks:
  - "验证 0x402000 MD5 常数(动态 dump 比对)"
  - "分析 0x403000 sym.verify_token 函数"
  - "追踪 mprotect(EXEC) 之后的 OEP(疑似内联解密)"

unresolved:
  - "0x401298 vpxor xmm0,xmm0,xmm1 — SIMD 宽度待白皮书确认"
  - "0x401900 mprotect EXEC 触发点 — 性质未定"

notes: |
  本次分析重点:RC4 算法已完整确认,S盒和PRGA均通过Frida动态验证。
  下一步重点:hash_password 函数 MD5 确认 + verify_token 逆向。
  注意:程序有 /proc/self/status 反调试,已通过GDB fgets patch绕过。
```

将以上 YAML 块保存后,下次对话直接粘贴,我会立即恢复此状态继续分析。
---
````

### M.3 — 快照加载(新对话开始时)

当用户粘贴快照时,执行以下恢复步骤:

```
1. 解析 YAML 结构
2. 输出恢复确认:
   "📂 已加载上下文快照(第 N 轮)
    目标: <file> | 架构: <arch> | 进度: X 个函数已分析
    待继续: <pending_tasks 列表>
    当前轮次重置为: N+1
    从哪里继续?[最后待分析函数 / 指定目标]"
3. 恢复 T.6 工具会话状态
4. 继续持续分析协议(阶段 4)
```

### M.4 — 手动触发快照

用户可随时说"生成快照"/"保存进度"/"snapshot" 手动触发 M.2。

### M.5 — 快照压缩策略(防止快照本身过长)

- 伪代码不写入快照(太长);只记录函数地址 + 一句话摘要
- 原始汇编不写入快照;只记录关键地址和发现
- 快照目标大小:< 100 行 YAML
- 超过 100 行时,优先保留 `pending_tasks` 和 `unresolved`,截断 `completed` 的详细 notes

---

## 参考文件索引

| 文件 | 内容 | 触发阶段 |
|------|------|---------|
| `references/linux-debug-workflows.md` | Linux 完整调试场景工作流(多线程/共享库/信号/coredump/ASLR) | 阶段 T |
| `references/tool-commands.md` | GDB/LLDB/r2 命令手册 + 反调试绕过 | 阶段 T |
| `references/frida-scripts.md` | Frida 插桩脚本库 | 阶段 T |
| `references/angr-workflows.md` | angr 符号执行工作流 | 阶段 T / D |
| `references/context-snapshot-template.md` | 记忆快照 YAML 模板(完整字段定义) | 阶段 M |
| `references/obfuscation-patterns.md` | UPX/OLLVM/VMProtect 识别与处置 | 阶段 O |
| `references/algorithm-patterns.md` | 加密/哈希/压缩算法汇编特征库 | 阶段 1 |
| `references/compiler-patterns.md` | 编译器优化模式映射 | 阶段 2 |
| `references/struct-recovery.md` | vtable/struct/类型重建 | 阶段 D |
| `references/whitepaper-urls.md` | Intel SDM / ARM DDI / 加密规范 URL | 阶段 0 |

---

## 附录 A:结构认知增强协议(Structure Inference Protocol)

> **核心原则**:结构体推断是多轮迭代过程,每一轮动态观察都应更新置信度。
> 详细方法见 `references/struct-recovery.md`

### A.1 — 多轮推断状态机

每个结构体实例维护一张推断卡片,跨轮次持续更新:

```
┌─────────────────────────────────────────────────┐
│ 结构体推断卡:struct_0x602000                      │
│ 状态:PARTIAL → SUSPECTED → CONFIRMED            │
│ 轮次:发现@T3 → 字段推断@T5 → 动态验证@T8         │
├─────────────────────────────────────────────────┤
│ 已确认字段(动态验证)                             │
│   0x00  void*    vptr       [GDB vtable读取验证]  │
│   0x08  int32_t  state      [strace观察值0/1/2]  │
│   0x18  char[16] key        [Frida dump内容]      │
├─────────────────────────────────────────────────┤
│ 疑似字段(静态推断,待验证)                        │
│   0x10  void*    handler    [访问后call [rax]]    │
│   0x28  uint32_t counter    [单调递增,疑似计数]   │
├─────────────────────────────────────────────────┤
│ 未知区域                                          │
│   0x0c  4字节   [读取但未追踪用途]                 │
│   0x2c  4字节   [疑似 padding]                    │
├─────────────────────────────────────────────────┤
│ 整体置信度:72%                                    │
│ 下一步:bpftrace 追踪 0x10 的函数指针实际指向       │
└─────────────────────────────────────────────────┘
```

### A.2 — 置信度评分规则

| 证据来源 | 加分 | 说明 |
|---------|------|------|
| 动态验证(GDB/Frida 实际读取) | +30 | 最强证据 |
| strace/ltrace 观察到字段被外部函数使用 | +20 | 行为证据 |
| 多函数中相同偏移有一致访问模式 | +15 | 跨函数一致性 |
| 访问指令大小与类型假设一致 | +10 | 静态类型推断 |
| 字段值范围符合类型语义(如 0/1/2 → enum) | +10 | 语义推断 |
| angr 约束求解确认字段边界 | +20 | 符号验证 |
| 仅在一处访问,无交叉引用 | −10 | 孤立证据 |
| 字段值无规律 | −5  | 弱语义 |

**阈值**:
- < 40%:`POSSIBLE`,标注 `[??]`,不写入伪代码类型
- 40–70%:`SUSPECTED`,标注 `[~type]`,写入伪代码但加注释
- 70–90%:`LIKELY`,标注 `[type?]`,写入伪代码
- ≥ 90%:`CONFIRMED`,直接使用类型名

### A.3 — 跨函数类型传播

发现结构体后,向全局扩散类型信息:

```
步骤 1:在所有函数中搜索持有相同地址的寄存器
  r2: axt @ <struct_alloc_point>    → 找所有引用分配点的函数
  GDB: rwatch *(void**)&struct_ptr  → 监控指针赋值

步骤 2:对每个使用该结构体的函数更新签名
  void process(SessionCtx* ctx, ...)  ← 从 void* 升级为具体类型

步骤 3:用类型信息重新解读已分析的函数
  原伪代码: mov rax, [rdi+0x8]      → 现在: ctx->state
  原伪代码: call [rax]              → 现在: ctx->handler()

步骤 4:发现新字段(类型传播可能暴露之前忽略的访问)
  在新函数中看到 [rdi+0x2c]        → 更新结构体推断卡
```

### A.4 — 动态调试协同验证工序

每个结构体字段的验证遵循以下流程:

```
静态推断(r2 pdf 观察访问模式)
      ↓
GDB 条件断点(在字段访问指令处)
  commands: printf "field[0x%x]=%lx\n", offset, value; continue
      ↓
Frida 连续采样(追踪字段值变化轨迹)
  Interceptor.attach 函数入口 → 每次记录字段当前值
      ↓
bpftrace 统计字段访问频率
  uprobe 在访问指令 → 统计访问次数与值分布
      ↓
angr 约束分析(字段值对程序行为的影响)
  修改字段的符号值 → 观察哪些路径被激活
      ↓
生成最终置信度 + 更新推断卡
```

---

## 附录 B:混淆类型系统化猜测与验证工序

> 详细特征见 `references/obfuscation-patterns.md`

### B.1 — 混淆类型猜测决策树

**第一层:是否加壳?**
```
熵值 > 7.0?
  是 → 进入"加壳识别"流程
  否 → 进入"代码混淆识别"流程

加壳识别:
  strings 找到 "UPX!" → UPX(最简单)
  段名含 .vmp/.themida → 商业保护
  只有2-3个段 → 通用压缩壳
  高熵段 + 小解压 stub → 自定义压缩壳

代码混淆识别:
  CFG 呈菊花状(所有块收束于一点) → OLLVM 平坦化
  大量 switch(state_var) + 状态更新 → OLLVM 平坦化
  间接调用 call [reg + offset] 大量出现 → 间接调用混淆
  出现 VM 解释器主循环(取字节码→跳 handler 表)→ 虚拟机保护
  大量不可能为真的条件分支 → 虚假控制流
  运行时才有可打印字符串(静态 strings 为空)→ 字符串加密
```

### B.2 — 每种混淆类型的专属验证工序

**[UPX] 验证 → 脱壳工序**
```
猜测触发:strings 找到 "UPX!" 字样
验证步骤:
  1. readelf -S ./target | grep UPX    → 找到 UPX0/UPX1 段
  2. upx -t ./target                   → UPX 自检
  3. upx -d ./target -o ./unpacked     → 脱壳
  4. file ./unpacked                   → 确认为正常 ELF
  5. r2 -A ./unpacked                  → 重新分析
置信度:strings 命中即 100%,无需进一步验证
```

**[OLLVM 平坦化] 验证 → 去混淆工序**
```
猜测触发:r2 VV 显示 CFG 收束到单一 dispatcher 块
验证步骤:
  1. r2 agf @ <suspect_fn>             → ASCII CFG 确认菊花形态
  2. 计算 dispatcher 块的入度
     r2: agfj @ fn | python3 -c "import json,sys; g=json.load(sys.stdin);
         print(max(g, key=lambda n:n['indegree']))"
     → 入度 > 函数基本块总数的 50% = 确认 dispatcher
  3. 找 state 变量(dispatcher 块的 switch 条件)
     GDB: b <dispatcher_addr>; run; 观察 cmp 指令的操作数
  4. Frida Stalker 追踪真实执行路径(过滤 dispatcher 地址)
  5. 用 deflat/D810/angr Veritesting 去平坦化
确认标准:入度比 > 50% + state 变量可识别
```

**[VMProtect 字节码虚拟化] 验证工序**
```
猜测触发:高熵段(.vmp0/.vmp1) + 大量 pushfd/popfd
验证步骤:
  1. r2 iS → 确认 .vmp 段存在且熵值 > 7.5
  2. 找 VM 主循环:
     r2: afl~vm | afl~interp        → 按名字搜索
     寻找模式:movzx eax, byte [rsi]; jmp [rax*8 + handler_table]
  3. 确认 handler 表:
     handler_table 通常是一个连续的函数指针数组
     r2: pxq 256 @ <handler_table>  → 应全是有效代码地址
  4. Frida Stalker 追踪 VM 主循环的每次迭代
     记录 [rsi] 的值序列 = 字节码序列
  5. 统计字节码频率分布(高频 = 基本指令,低频 = 复杂指令)
确认标准:找到 handler 表 + 字节码取指模式
```

**[字符串加密] 验证 → 提取工序**
```
猜测触发:静态 strings 几乎为空,但运行时有可打印输出
验证步骤:
  1. strace ./target 2>&1 | grep write → 确认有字符串输出
  2. r2 iz → 静态字符串极少(< 5 个)= 确认加密
  3. 找解密函数:
     r2: axt @ <first_string_ref>   → 找到引用加密串的代码
     向上追踪:该地址通常在 call <decrypt_fn> 之后使用
  4. 确认解密函数签名(通常是 decrypt(encrypted_ptr) → char*)
     GDB: b <decrypt_fn>; run; x/s $rax (返回值是明文指针)
  5. Frida hook 解密函数出口,收集所有解密结果
     LD_PRELOAD 方案:hook malloc 后的 memcpy(解密结果经常 memcpy)
确认标准:解密函数出口 rax 指向可打印字符串
```

**[虚假控制流] 验证 → 清理工序**
```
猜测触发:大量短小的条件分支 + CFG 有孤立小块
验证步骤:
  1. Frida Stalker 记录实际执行块(跑 100 次,收集覆盖率)
  2. 将"从未执行"的块标记为 dead code
     r2: afb- <dead_block_addr>     → 从 CFG 移除
  3. 检查 opaque predicate 模式(永真/永假的数学表达式)
     常见:X² & 3 ≠ 3(平方数模4不等于3)
     angr: 符号执行确认分支可达性
  4. 对永假分支所在地址执行 patch
     r2 -w: wa nop @ <false_branch>
确认标准:Stalker 覆盖率显示某些块从未执行
```

### B.3 — 混淆层叠处理顺序

当多种混淆同时存在时,按以下顺序处理(外层到内层):

```
优先级 1:加壳 → 先脱壳,获得原始代码
优先级 2:反调试 → 绕过所有反调试措施
优先级 3:字符串加密 → 提取所有字符串(利于后续理解逻辑)
优先级 4:虚假控制流 → 清理 CFG(减少分析噪声)
优先级 5:OLLVM 平坦化 → 恢复真实控制流
优先级 6:间接调用混淆 → 解析调用目标
优先级 7:VM 保护 → 最后处理(成本最高)
```

---

## 附录 C:动态调试协同重要性与分析重点

### C.1 — 为何动态调试必须协同

**单一工具的盲点**:

| 工具 | 擅长 | 盲点 |
|------|------|------|
| GDB | 精确控制执行流,寄存器/内存快照 | 不看系统调用全貌,容易遗漏文件/网络操作 |
| strace | 完整系统调用记录 | 不看库函数调用,无法追踪用户态加密逻辑 |
| ltrace | 库函数参数完整 | 不看内联代码,自实现的算法完全不可见 |
| r2/静态 | 不受反调试影响,全量代码 | 无法观察运行时值,动态解密/JIT不可见 |
| Frida | 灵活 hook 任意地址 | 注入本身可被检测,高频 hook 性能开销大 |
| angr | 路径完整性,约束求解 | 路径爆炸,无法分析加壳/高混淆代码 |

**协同原则**:每个关键发现必须至少两个工具交叉确认,才能标注为 P1 及以上。

### C.2 — 分析重点排序

**高价值目标识别**(优先分析以下特征的函数):

```
优先级排序:
  1. ltrace/strace 发现的热点(被多次调用的加密/比较函数)
  2. perf 热点(CPU 占用 > 5%,通常是核心算法)
  3. 带算法特征常数的函数(AES/MD5/SHA 魔数)
  4. malloc 参数固定的函数(暗示固定大小结构体)
  5. 有 vtable 调用的函数(多态,逻辑复杂)
  6. 在 strace 的 mprotect(EXEC) 之后首次调用的函数
  7. 反调试检测函数(逆向绕过后分析其保护的真实逻辑)
```

### C.3 — 动态调试与静态分析交替节奏

```
[静态] r2 aaa → 获得函数列表和 CFG 骨架
    ↓
[动态-宽] strace + ltrace 全量运行 → 找到热点和关键行为
    ↓
[静态] 对热点函数做详细反汇编,推断算法和结构体
    ↓
[动态-精] GDB 精确断点 + Frida hook → 验证静态推断
    ↓
[自动化] angr/bpftrace → 覆盖 GDB 不易追踪的部分(路径、内核事件)
    ↓
[更新] 将动态结果更新到结构体推断卡 + 算法置信度
    ↓
[循环] 进入下一个目标函数
```

---

## 附录 D:记忆优先级系统(P0–P3)

> 这套系统贯穿整个分析过程,决定每条信息在快照中的保留策略。

### D.1 — 优先级定义与判定标准

**P0 — 突破性发现(最高,永不丢弃)**

判定标准(满足任意一条即为 P0):
- 发现了实际的密钥材料、密码、token 或加密参数
- 确认了核心算法的完整实现(动态验证通过)
- 找到了程序的主要隐藏功能或逻辑分支
- 绕过了关键的验证/授权检查
- 发现了程序与外部系统交互的完整协议格式

存储要求:
- **快照中必须写入 `breakthroughs_p0`**
- **detail 字段必须包含完整证据**(具体值、工具输出原文摘录)
- 跨对话永久保留,不随轮次增加而截断

**P1 — 重要进展(高,优先保留)**

判定标准:
- 结构体字段达到 CONFIRMED 状态(置信度 ≥ 90%)
- 函数签名和主要逻辑已完整分析
- 反调试/混淆绕过成功
- 确认了某个算法候选(即使未完整验证)
- vtable 或类层级完整恢复

存储要求:
- 写入 `important_findings_p1`
- 包含函数地址、关键证据来源、置信度
- 快照空间不足时可压缩 detail 但不可删除条目

**P2 — 有价值的中间结论**

判定标准:
- 疑似某算法但未动态验证
- 结构体字段处于 SUSPECTED 状态(40–70%)
- 初步识别了某个代码模式
- 发现了未来值得追踪的地址或行为

存储要求:
- 写入 `intermediate_p2` 列表(单行摘要)
- 快照空间不足时可省略,但需在 `unresolved` 中保留 action

**P3 — 常规记录(低,可截断)**

判定标准:
- 已完成分析但无特殊价值的函数
- 工具运行记录(strace 行数、断点触发次数)
- 编译器信息、段信息等元数据

存储要求:
- 只在 `functions.completed` 中保留一行摘要
- 快照空间不足时首先省略

### D.2 — 实时优先级标注

在分析过程中,每条重要输出旁边实时标注优先级:

```
[strace] open("/etc/app/key.bin") = 3         ← ⭐ P0候选
  → 立即追踪后续 read,确认读取内容

[GDB] 0x401234: cmp [rbp-0x4], 0xd76aa478    ← 🔵 P2(MD5常数)
  → 需动态验证升级为P1

[ltrace] fopen("/tmp/log.txt", "w")            ← ⚪ P3(日志文件)

[Frida] rc4_init arg0=key_ptr, dump=61 62...  ← ⭐ P0(密钥内容)
  → 立即写入 breakthroughs_p0,标注 confirmed
```

### D.3 — 快照触发时的优先级处理流程

```
第 10/20/30... 轮触发快照生成:

1. 扫描本轮所有分析记录
   → 识别 P0/P1 新发现(按判定标准)
   → 计算各结构体推断卡的置信度变化

2. 合并到现有快照:
   P0: append to breakthroughs_p0(追加,不覆盖)
   P1: append to important_findings_p1
   P2: update intermediate_p2(去重后追加)
   P3: 更新 functions.completed 列表

3. 压缩检查(目标 < 120 行):
   超出时:先截断 P3 的 notes,再截断 P2 的部分条目
   绝不截断:P0 的 detail,P1 的 struct/vtable 定义

4. 更新 next_session_plan(基于当前 unresolved 和 pending)

5. 输出快照 + 提示用户保存
```

---

## 参考文件索引(完整)

| 文件 | 内容 | 触发阶段 |
|------|------|---------|
| `references/linux-debug-workflows.md` | Linux 完整调试场景工作流 | 阶段 T |
| `references/tool-commands.md` | GDB/LLDB/r2 命令手册 | 阶段 T |
| `references/frida-scripts.md` | Frida 插桩脚本库 | 阶段 T |
| `references/angr-workflows.md` | angr 符号执行工作流 | 阶段 T / D |
| `references/context-snapshot-template.md` | P0–P3 快照 YAML 模板 | 阶段 M |
| `references/obfuscation-patterns.md` | 混淆识别特征与处置 | 阶段 O / 附录 B |
| `references/algorithm-patterns.md` | 算法汇编特征库 | 阶段 1 |
| `references/compiler-patterns.md` | 编译器优化模式 | 阶段 2 |
| `references/struct-recovery.md` | 结构体/vtable 恢复 | 阶段 D / 附录 A |
| `references/whitepaper-urls.md` | 权威文档 URL | 阶段 0 |

---

## 阶段 I:对话内自我迭代协议(In-conversation Skill Evolution)★

> **核心目标**:在当前对话中,将分析过程中发现并验证的新规律
> 持续写回 skill 自身,使后续分析受益于本轮已学到的知识。
> 迭代内容仅在验证为真后才正式写入,避免幻觉传播。

### I.1 — 迭代生命周期

```
[CANDIDATE]  发现新规律/模式(单工具证据)
     ↓ 第二工具独立确认
[VERIFIED]   验证通过(两个独立工具都支持)
     ↓ 无冲突证据
[COMMITTED]  写入对话内 skill 缓存
     ↓ 快照触发时(每10轮)
[PERSISTED]  写入快照,下轮对话可加载
```

**规则:**
- `CANDIDATE` → 只在当前分析注释中使用,不影响其他函数推断
- `VERIFIED` → 可在后续同类分析中直接引用
- `COMMITTED` → 写入对话内 skill 补丁块(`## SKILL-PATCH` 格式)
- 任何阶段发现反驳证据 → 立即降回 `CANDIDATE` 并注明冲突

### I.2 — 迭代内容类型

| 类型 | 示例 | 最低验证要求 |
|------|------|------------|
| 新算法特征 | "本目标的 RC4 S-box 偏移为 +0x10 而非 +0x0" | GDB + Frida 双重确认 |
| 编译器优化模式 | "该二进制用 Clang -O2 的 SLP 向量化,SIMD 块均含 vpxor xmm" | 至少 3 个函数中重复出现 |
| 结构体布局 | "SessionCtx.handler 字段实为虚函数指针而非回调" | vtable 追踪确认 |
| 混淆变体 | "此 OLLVM 版本 dispatcher 使用 imul 哈希而非直接 cmp" | Stalker 追踪 + angr 验证 |
| 反调试方式 | "程序检查 /proc/self/fdinfo 下的 fd 数量" | strace 观察 + 源码对照 |

### I.3 — SKILL-PATCH 格式

每次有内容晋升到 `COMMITTED`,在当前回复末尾输出:

```
┌─────────────────────────────────────────────────────────┐
│  SKILL-PATCH  [本轮第 N 个补丁]                           │
│  目标文件: ./target  |  来源: 第 M 轮验证                  │
│  类型: <algorithm_pattern | struct_field | obfuscation>  │
├─────────────────────────────────────────────────────────┤
│  补丁内容(追加到 references/<对应文件>.md):             │
│                                                         │
│  ### [目标特定] RC4 变体:S-box 位于 ctx+0x10            │
│  本目标的 rc4_init 将 S-box 放在结构体偏移 0x10 处,      │
│  而非直接作为首个参数传入的裸数组。                        │
│  验证:GDB `x/256xb ($rdi+0x10)` 确认256字节S-box。     │
│  Frida dump 第一次 rc4_crypt 调用确认S[0]=0,S[1]=1...   │
├─────────────────────────────────────────────────────────┤
│  置信度: 95%  |  工具: GDB + Frida  |  轮次: 7, 9       │
└─────────────────────────────────────────────────────────┘
```

### I.4 — 幻觉防护门控

**任何内容进入 `VERIFIED` 之前,必须通过以下检查:**

```
检查 1:两工具独立性
  同一工具的两次测量不算"两个独立工具"
  GDB + GDB ≠ 独立  /  GDB + Frida = 独立  /  strace + ltrace = 独立

检查 2:具体证据锚点
  每个 VERIFIED 条目必须包含:
    - 至少一条具体的工具输出行(含地址/值)
    - 发现该结论的具体轮次
  没有具体证据 = 不得晋升

检查 3:反例扫描
  在提升前搜索是否存在与结论矛盾的观测
  存在未解释的矛盾 = 降回 CANDIDATE,标注冲突

检查 4:可重复性
  结论是否在多次运行/多个输入下均成立?
  单次观测 = CANDIDATE  /  多次重复 = 允许晋升
```

---

## 阶段 F:控制流与平坦化分析(Control Flow Analysis)★

> 详细算法见 `references/cfg-analysis.md`

### F.1 — CFG 健康度快速评估

每个函数分析前先运行健康度检测:

```bash
# r2 一行命令:输出块数、最大入度、平坦化可能性
r2 -A -q -c "
agfj @ <func_addr> | python3 -c \"
import json,sys
b=json.load(sys.stdin)
if not b: exit()
ind={x['offset']:0 for x in b}
[ind.__setitem__(s, ind.get(s,0)+1) for x in b for s in x.get('successors',[])]
mx=max(ind.values()) if ind else 0
n=len(b)
ratio=mx/n if n else 0
flag='⚠️ FLAT' if ratio>0.35 and n>8 else ('⚠️ LARGE' if n>30 else '✅')
print(f'blocks={n} max_indeg={mx} ratio={ratio:.2f} {flag}')
\"
" ./target
```

健康度结论映射:

| 指标 | 正常 | 可疑 | 高度混淆 |
|------|------|------|---------|
| 块数量 | < 20 | 20–50 | > 50 |
| 最大入度/总块数 | < 0.2 | 0.2–0.35 | > 0.35 |
| 平均块大小(字节) | > 30 | 15–30 | < 15 |
| 函数大小(字节) | 正常 | — | 单函数 > 5000 |

### F.2 — 平坦化分析流水线

```
步骤 1: CFG 健康度评估
   ratio > 0.35 → 进入平坦化分析
   ratio ≤ 0.35 → 跳过,进入普通逐块分析

步骤 2: 识别变体类型(见 references/cfg-analysis.md §6)
   cmp 链 → 标准 OLLVM
   switch 跳转表 → OLLVM 或自定义状态机
   imul 常数 → 哈希 dispatcher 变体
   全局变量 → 非 OLLVM 自定义状态机

步骤 3: 定位 dispatcher(references/cfg-analysis.md §3)
   最高入度块 = dispatcher 候选
   汇编确认:连续 cmp+je 或 jmp [table]

步骤 4: 追踪 state 变量(references/cfg-analysis.md §4)
   静态:dispatcher 块中 cmp 的操作数
   动态:GDB watchpoint / Frida Stalker

步骤 5: 真实块恢复(references/cfg-analysis.md §5)
   Frida Stalker 追踪(过滤 dispatcher 地址)
   多输入运行 → 合并覆盖率
   angr Veritesting → 枚举路径

步骤 6: 生成去平坦化伪代码
   按块执行顺序重排
   去除 state 赋值语句
   去除 dispatcher 跳转
   输出线性化控制流
```

### F.3 — 各阶段工具协同

```
静态(r2)确认 dispatcher 地址
      ↓
GDB watchpoint 追踪 state 变量值
      ↓
Frida Stalker 记录真实块序列(单输入)
      ↓
多输入重复 → 合并块集合(提升覆盖率)
      ↓
angr 枚举剩余未覆盖路径
      ↓
综合输出线性化控制流 + 伪代码
```

### F.4 — 去平坦化伪代码输出格式

```c
// ── 去平坦化结果:sym.target_func ──
// 原始: 47 个基本块(含 dispatcher @ 0x401100)
// 恢复: 12 个真实内容块
// 工具: Frida Stalker (3次运行,覆盖率 87%) + angr (补全13%)

void target_func(SessionCtx* ctx, uint8_t* data, size_t len) {
    // [Block 0x401234] 初始化
    ctx->state = STATE_INIT;
    ctx->counter = 0;

    // [Block 0x401280] 验证长度
    if (len == 0 || len > 4096) {
        ctx->state = STATE_ERROR;
        return;         // [Block 0x4013a0] 错误路径
    }

    // [Block 0x4012b0] 主循环(已去除 state 变量赋值)
    for (size_t i = 0; i < len; i++) {
        data[i] ^= ctx->key[i % 16];  // [Block 0x4012e0] XOR 核心
        ctx->counter++;
    }

    ctx->state = STATE_DONE;  // [Block 0x401350]
}
// [注] 3 个块未覆盖(angr 无法到达),标注 [UNVERIFIED_PATH]
```

---

## 阶段 T(增强):动态实时协调协议

> **本节补充阶段 T 的动态附加能力。**
> 详细脚本见 `references/dynamic-coordination.md`

### T-DYN.1 — 进程感知与自动附加

目标进程启动时,自动触发工具协调序列:

```
检测进程启动(pgrep / inotify-exec)
      ↓ PID 确认
并行附加:
  ├─ strace -p PID (系统调用层,-e trace=file,network,memory)
  ├─ ltrace -p PID (库函数层)
  ├─ bpftrace uprobe (内核事件层,mprotect/mmap 监控)
  └─ GDB -p PID --non-stop (精确控制层)
      ↓ 所有工具就绪(< 200ms)
事件路由启动(aggregator.py)
      ↓ 实时分类 P0/P1/P2/P3
分析流程继续,动态补充静态分析结论
```

### T-DYN.2 — 事件路由规则

| 来源事件 | 触发动作 | 优先级 |
|---------|---------|-------|
| strace: open(密钥/配置文件) | GDB 断在 read 返回,dump 内容 | P0候选 |
| strace: mprotect(EXEC) | bpftrace 追踪后续首条指令 | P1候选 |
| ltrace: strcmp/memcmp | Frida hook 同函数,获取完整参数 | P0候选 |
| ltrace: 加密函数(EVP_*等) | 记录调用序列,推断算法 | P1 |
| GDB 断点触发 | 自动启动 Frida 深度 dump(见 T.3) | 视内容 |
| Frida: mmap EXEC | 触发 bpftrace uprobe 追踪 | P1候选 |

### T-DYN.3 — Non-stop 调试会话

GDB 附加后使用 non-stop 模式,目标进程不中断,按需检查:

```gdb
set non-stop on
set target-async on
# 断点触发只暂停当前线程,其他线程继续
b sym.target_func
commands
  printf "[hit] rdi=%p rsi=%p\n", $rdi, $rsi
  x/32xb $rdi
  continue &    # 异步继续
end
attach <pid>
```

---

## 阶段 M(增强):记忆可靠性门控(STAGED → COMMITTED)

> **核心问题**:未经验证的结论写入快照后,会在下次对话中被当作事实使用,
> 形成幻觉传播链。本节在原有 P0–P3 优先级之上,增加两阶段门控。

### M-R.1 — 两阶段提交

```
每条分析结论的状态:

STAGED(暂存)
  条件:仅一个工具的单次观测
  行为:在当前轮次注释中标注 [STAGED]
  快照:不写入 breakthroughs_p0 / important_findings_p1
        只写入 staged_pending(独立区块,明确标注"未验证")

        ↓ 第二工具独立确认 + 无矛盾证据

COMMITTED(已提交)
  条件:两个独立工具均支持,无反例
  行为:正式写入对应优先级区块
  快照:写入 breakthroughs_p0 / important_findings_p1
        detail 字段必须包含两个工具的具体输出行
```

### M-R.2 — STAGED 标注格式

在分析过程中,STAGED 结论的标注方式:

```
[strace] open("/etc/app/key.bin") = 3
  → [STAGED-P0候选] 密钥文件读取
     证据1: strace 第23行原文
     等待验证: GDB 在 read(3,...) 返回时 dump 内容
               或 Frida hook read 系列函数确认读取内容

[ltrace] strcmp("S3cr3t", input)
  → [STAGED-P0候选] 硬编码密码候选
     证据1: ltrace 第47行原文:strcmp("S3cr3t", "test_input")
     注意: ltrace 可能误判(内联函数看不到),需 GDB 在 strcmp 符号处断点验证
     等待验证: GDB b strcmp; run; x/s $rdi; x/s $rsi
```

### M-R.3 — 快照中的 staged_pending 区块

```yaml
# 快照中的暂存区(未验证,仅供参考)
staged_pending:
  - id: "STG-001"
    priority_candidate: "P0"
    first_tool: "ltrace"
    first_evidence: "strcmp(\"S3cr3t\", input) line 47"
    needed_verification: "GDB b strcmp 验证参数真实性"
    status: "awaiting_second_tool"
    turn_staged: 9

# 注意:staged_pending 中的内容不得作为事实引用
# 加载快照时,Claude 必须将这些条目标注为 [待验证]
```

### M-R.4 — 快照加载时的可靠性恢复话术

```
📂 已加载快照(第 10 轮)

✅ 已验证发现(COMMITTED):
  ⭐ P0: RC4 密钥 = /etc/app/key.bin 读取(GDB+Frida 双重验证)
  🔵 P1: SessionCtx 结构体布局(r2+GDB 双重验证)

⚠️  暂存区(STAGED,需本轮验证后才可用作事实):
  [ ] STG-001: strcmp 硬编码密码候选 → 需 GDB 验证参数
  [ ] STG-002: mprotect EXEC OEP → 需 bpftrace 追踪首条指令

📋 本轮首要任务:将 STAGED 条目升级为 COMMITTED 或排除
```

---

## 参考文件索引(最终完整版)

| 文件 | 内容 | 触发阶段 |
|------|------|---------|
| `references/dynamic-coordination.md` | 进程自动发现/附加、事件驱动多工具联动、聚合器 | 阶段 T-DYN |
| `references/cfg-analysis.md` | CFG 健康度评估、平坦化识别算法、dispatcher 定位、真实块恢复 | 阶段 F |
| `references/linux-debug-workflows.md` | Linux 调试场景全集(多线程/共享库/信号/coredump/ASLR) | 阶段 T |
| `references/tool-commands.md` | GDB/LLDB/r2 命令手册 + 反调试绕过 | 阶段 T |
| `references/frida-scripts.md` | Frida 插桩脚本库 | 阶段 T |
| `references/angr-workflows.md` | angr 符号执行工作流 | 阶段 T / D / F |
| `references/context-snapshot-template.md` | P0–P3 + STAGED/COMMITTED 快照 YAML 模板 | 阶段 M |
| `references/obfuscation-patterns.md` | 混淆识别特征与处置(配合附录 B) | 阶段 O |
| `references/algorithm-patterns.md` | 加密/哈希/压缩算法汇编特征库 | 阶段 1 |
| `references/compiler-patterns.md` | 编译器优化模式映射 | 阶段 2 |
| `references/struct-recovery.md` | 结构体/vtable 恢复(配合附录 A) | 阶段 D |
| `references/whitepaper-urls.md` | 权威文档 URL 索引 | 阶段 0 |

Files in this skill

  • SKILL.md57.4 KB
  • references/algorithm-patterns.md4.9 KB
  • references/angr-workflows.md11.2 KB
  • references/cfg-analysis.md17.1 KB
  • references/compiler-patterns.md6.4 KB
  • references/context-snapshot-template.md10.9 KB
  • references/dynamic-coordination.md16.3 KB
  • references/frida-scripts.md16.5 KB
  • references/linux-debug-workflows.md17.6 KB
  • references/obfuscation-patterns.md10.6 KB
  • references/struct-recovery.md15 KB
  • references/tool-commands.md26 KB
  • references/whitepaper-urls.md3.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…