mcpField
R
reverse-engineering-deep-analysis

reverse-engineering-deep-analysis

github.com/dnyoussef安全3296 次安装15 周前更新
代码仓库

关于 reverse-engineering-deep-analysis

面向安全研究人员的深度逆向分析 skill,覆盖隔离环境中的动态分析与符号执行。它要求先检查项目库和既有模式,并以多种方法验证分析结果。

主要功能

  1. 01先检查库目录与既有模式
  2. 02在隔离沙箱中执行动态分析
  3. 03使用 GDB 跟踪运行状态与系统调用
  4. 04通过 Angr 和 Z3 进行符号执行
  5. 05采集内存、栈和网络活动证据
  6. 06交叉验证并记录分析结果

适用场景

  1. 01在授权范围内分析可疑二进制文件
  2. 02提取运行时行为和恶意指标
  3. 03评估漏洞并探索未覆盖的执行路径
  4. 04通过符号执行为 CTF 挑战寻找输入

MCP 相关

指南提及使用 sandbox-validator 安全执行二进制文件、memory-mcp 存储运行时发现,并借助 sequential-thinking 与 graph-analyst 支持路径判断和可视化。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dnyoussef/context-cascade --skill reverse-engineering-deep-analysis

安装后在 Claude Code 中输入/reverse-engineering-deep-analysis确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

SKILL-meta.yaml
resources/
README.md
resources/scripts/
angr-symbolic-exec.py
gdb-automation.py

详细介绍


库优先协议(强制)

在编写任何代码之前,必须先检查:

步骤 1:库目录
  • 位置:.claude/library/catalog.json
  • 如果匹配度 >70%:复用或调整
步骤 2:模式指南
  • 位置:.claude/docs/inventories/LIBRARY-PATTERNS-GUIDE.md
  • 如果存在相应模式:遵循文档中说明的方法
步骤 3:现有项目
  • 位置:D:\Projects\*
  • 如果找到:提取并调整
决策矩阵
匹配度操作
库 >90%直接复用
库 70-90%尽量少做调整
存在模式遵循模式
存在于项目中提取
无匹配项构建(之后添加到库中)

何时使用此技能

在分析恶意软件样本、为安全研究对二进制文件进行逆向工程、开展漏洞评估、从可疑文件中提取 IOC、验证软件的供应链安全,或进行 CTF 挑战和二进制利用研究时,使用此技能。

何时不使用此技能

请勿将此技能用于未经授权的商业软件逆向工程、分析生产系统上的二进制文件、在未获法律授权的情况下对软件进行逆向工程、违反服务条款或 EULA,或在隔离环境之外分析恶意软件。简单的字符串提取也不适用(请改用基础工具)。

成功标准

  • 识别所有与安全相关的行为(网络、文件、注册表、进程活动)
  • 提取恶意指标并附上置信度评分(IOC、C2 域名、加密密钥)
  • 在适用情况下,使用 CVE 映射记录漏洞
  • 在沙箱环境(带快照的 VM/容器)中完成分析
  • 通过多种分析方法(静态分析 + 动态分析 + 符号执行)验证发现
  • 生成完整的 IOC 报告(采用 STIX/MISP 格式,以便共享威胁情报)
  • 漏洞评估中零误报
  • 创建漏洞利用概念验证(如进行漏洞研究)

边缘情况与挑战

  • 反分析技术(调试器检测、VM 检测、计时检查)
  • 需要解包的混淆或加壳二进制文件
  • 带有加密载荷的多阶段恶意软件
  • 需要专门分析的内核模式 Rootkit
  • 符号执行状态爆炸(>10,000 条路径)
  • 复杂程序的二进制分析超时(>24 小时)
  • 合法软件行为导致的误报
  • 需要 SSL 拦截的加密网络流量

防护措施(关键安全规则)

  • 绝不在主机系统上执行未知二进制文件(只能在隔离的 VM/沙箱中执行)
  • 绝不在缺乏适当遏制措施的情况下分析恶意软件(最好使用物理隔离实验室)
  • 绝不在未获法律授权的情况下对软件进行逆向工程
  • 绝不公开分享提取出的凭据或加密密钥
  • 绝不为未经授权的用途绕过许可机制
  • 始终使用带网络监控的沙箱环境
  • 始终在执行可疑二进制文件之前创建 VM 快照
  • 始终通过多种分析方法验证发现
  • 始终记录分析方法并注明时间戳
  • 始终假设二进制文件具有恶意,直至证明其安全
  • 始终使用网络隔离,防止恶意软件通信
  • 始终在分享 IOC 前进行净化处理(隐藏内部 IP 地址)

基于证据的验证

所有逆向工程发现都必须通过以下方式验证:

  1. 多方法分析——通过静态分析 + 动态分析 + 符号执行确认相同行为
  2. 沙箱验证——在隔离环境中执行,并捕获所有活动
  3. 网络监控——通过数据包捕获验证基于网络的发现
  4. 内存取证——通过内存转储验证运行时机密信息
  5. 行为关联——与已知恶意软件特征(YARA、ClamAV)交叉比对
  6. 可复现性——第二位分析人员能够根据分析产物复现发现

逆向工程:深度分析

此技能的功能

通过运行时执行和符号探索进行深度逆向工程:

  • 第 3 级(≤1 小时):动态分析——在沙箱中执行,使用 GDB 捕获内存和机密信息,并跟踪系统调用
  • 第 4 级(2-6 小时):符号执行——使用 Angr/Z3 合成可到达目标状态的输入

决策关卡:第 3 级结束后,评估是否需要符号执行来抵达尚未探索的路径。

时间安排:总计 3-7 小时


前提条件

第 3 级工具
  • GDB,搭配 GEF 或 Pwndbg 扩展
  • strace/ltrace——系统调用/库调用跟踪
  • 沙箱环境——隔离执行环境(firejail、Docker 或自定义环境)
第 4 级工具
  • Angr——符号执行框架(Python)
  • Z3——SMT 求解器
  • Python 3.9+——用于 Angr 脚本
MCP 服务
  • sandbox-validator——安全执行二进制文件
  • memory-mcp——存储运行时发现
  • sequential-thinking——路径探索决策
  • graph-analyst——可视化执行路径

⚠️ 严重安全警告

切勿在主机系统上执行未知二进制文件!

所有动态分析、调试和符号执行都必须在以下环境中进行:

  • 隔离的 VM(VMware/VirtualBox,带快照以便回滚)
  • Docker 容器,并设置安全策略(--security-opt、--cap-drop=ALL)
  • E2B 沙箱,通过 sandbox-configurator 技能配置网络监控
  • 专用恶意软件分析实验室(处理 APT 时应采用气隙隔离)

不安全执行的后果:

  • 感染带有内核级 rootkit 的恶意软件
  • 内存损坏和系统不稳定
  • 通过隐蔽通道窃取数据
  • 通过植入木马的构建产物发动供应链攻击
  • 系统被彻底攻陷

安全实践:

  • 始终使用带快照的沙箱环境
  • 在执行期间监控系统调用和网络活动
  • 仅在隔离容器中使用 GDB/Angr
  • 切勿在生产系统上将调试器附加到二进制文件
  • 符号执行前验证所有输入
  • 在静态分析证明二进制文件安全之前,始终假定其具有恶意性

快速开始

# 1. Full deep analysis (Levels 3+4)
/re:deep crackme.exe

# 2. Dynamic analysis only (Level 3)
/re:dynamic server.bin --args "--port 8080"

# 3. Symbolic execution only (Level 4)
/re:symbolic challenge.exe --target-addr 0x401337

第 3 级:动态分析(≤1 小时)

步骤 1:在沙箱中安全执行
/re:dynamic binary.exe --args "test input" --sandbox true

沙箱隔离:

  • 文件系统隔离(/usr、/bin 只读)
  • 禁用或监控网络
  • 进程限制(CPU、内存、时间)
  • 防止恶意软件逃逸
步骤 2:获取静态分析上下文

执行前,技能会自动获取第 2 级的发现:

// Check memory-mcp for static analysis results
const staticFindings = await mcp__memory-mcp__vector_search({
  query: binary_hash,
  filter: {category: "reverse-engineering", re_level: 2}
})

// Extract critical functions and suggested breakpoints
const breakpoints = staticFindings.critical_functions.map(f => f.address)
// Example: ["0x401234", "0x401567", "0x4018ab"]
步骤 3:加载自动设置断点的 GDB 会话

自动加载第 2 级静态分析中的断点:

# Auto-generated from static analysis
break *0x401234  # check_password function
break *0x401567  # validate_license function
break *0x4018ab  # decrypt_config function

# Run with test input
run --flag "test_input_from_user"

GDB 会话命令(自动执行):

# At each breakpoint:

# 1. Dump all registers
info registers

# 2. Dump stack (100 bytes)
x/100x $rsp

# 3. Dump heap allocations (if applicable)
info proc mappings
x/100x [heap_address]

# 4. Search for secrets in memory
find 0x600000, 0x700000, "password"
find 0x600000, 0x700000, "admin"

# 5. Dump interesting strings from registers
x/s $rdi  # First argument (often string pointer)
x/s $rsi  # Second argument
步骤 4:捕获运行时状态

在每个断点处,技能都会捕获:

寄存器状态:

RAX: 0x0000000000401337
RBX: 0x0000000000000000
RCX: 0x00007fffffffe010  → "user_input_here"
RDX: 0x0000000000000010
RSI: 0x00007fffffffe020  → "expected_password"
RDI: 0x00007fffffffe030  → buffer
RBP: 0x00007fffffffe100
RSP: 0x00007fffffffe0e0
RIP: 0x0000000000401234  → check_password

栈转储(保存到 re-project/dbg/0x401234-stack.bin):

0x7fffffffe0e0: 0x0000000000401337  0x0000000000000000
0x7fffffffe0f0: 0x00007fffffffe200  0x0000000000000001

内存中的机密信息(自动提取):

Found at 0x601000: "admin:SecretP@ss123"
Found at 0x601020: "license_key=ABC-DEF-GHI-JKL"
Found at 0x601040: "api_token=eyJhbGciOiJIUzI1NiIs..."

系统调用跟踪(通过 strace):

# Automatically executed in parallel
strace -o re-project/dbg/syscalls.log ./binary.exe --flag test

输出:

open("/etc/config.ini", O_RDONLY) = 3
read(3, "password=admin123\n", 1024) = 18
socket(AF_INET, SOCK_STREAM, 0) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr("192.168.1.100")}, 16) = 0
send(4, "POST /api/login HTTP/1.1\r\n...", 256, 0) = 256
步骤 5:输出结构
re-project/dbg/
├── gdb-session.log          # Full GDB transcript
├── breakpoints.txt          # List of breakpoints set
├── memory-dumps/
│   ├── 0x401234-registers.txt
│   ├── 0x401234-stack.bin
│   ├── 0x401567-registers.txt
│   ├── 0x401567-stack.bin
│   └── 0x4018ab-heap.bin
├── syscalls.log             # strace output
├── libcalls.log             # ltrace output
└── runtime-secrets.txt      # Extracted passwords, keys, tokens
步骤 6:决策关卡——升级到第 4 级?
// Automatically evaluated via sequential-thinking MCP
const decision = await mcp__sequential-thinking__evaluate({
  question: "Should we proceed to symbolic execution (Level 4)?",
  factors: [
    `Branches explored: ${explored_branches}/${total_branches}`,
    `Unreachable code found: ${unreachable_functions.length > 0}`,
    `User's question answered: ${findings_sufficient}`,
    `Input-dependent paths: ${symbolic_paths_needed}`
  ]
})

// Example evaluation:
// - Explored 12/20 branches (60% coverage)
// - Found 3 unreachable functions (possible anti-debug)
// - User wants to reach "win" function at 0x401337 (NOT YET REACHED)
// - Input-dependent path detected (password check with strcmp)
// DECISION: ESCALATE TO LEVEL 4

第 4 级:符号执行(2-6 小时)

步骤 1:根据动态分析定义目标状态
# From Level 3: Couldn't reach "win" function at 0x401337 with manual inputs
target_addr = 0x401337  # Goal: Find input that reaches this

# From Level 3: These functions lead to failure/exit
avoid_addrs = [
  0x401400,  # fail_message function
  0x401500,  # bad_password function
  0x401600   # exit_program function
]
步骤 2:启动符号探索
/re:symbolic binary.exe \
  --target-addr 0x401337 \
  --avoid-addrs 0x401400,0x401500,0x401600 \
  --max-states 1000 \
  --timeout 7200

底层执行过程:

import angr
import claripy

# Step 2.1: Load binary into Angr project
project = angr.Project('./binary.exe', auto_load_libs=False)

# Step 2.2: Create symbolic input
# Assume input is 32-byte flag
flag_length = 32
flag = claripy.BVS('flag', flag_length * 8)

# Step 2.3: Create entry state with symbolic stdin
state = project.factory.entry_state(
    stdin=flag,
    add_options={angr.options.LAZY_SOLVES}
)

# Step 2.4: Add constraints - printable ASCII only
for byte in flag.chop(8):
    state.add_constraints(byte >= 0x20)  # Printable ASCII start
    state.add_constraints(byte <= 0x7e)  # Printable ASCII end

# Step 2.5: Create simulation manager
simgr = project.factory.simulation_manager(state)

# Step 2.6: Explore paths (DFS strategy)
simgr.explore(
    find=0x401337,      # Target address
    avoid=[0x401400, 0x401500, 0x401600],  # Avoid addresses
    num_find=1,         # Stop after finding first solution
    max_states=1000     # Prevent state explosion
)

# Step 2.7: Check if solution found
if simgr.found:
    # Extract concrete input
    solution_state = simgr.found[0]
    solution = solution_state.solver.eval(flag, cast_to=bytes)
    print(f"Solution: {solution.decode()}")

    # Save solution
    with open('re-project/sym/solutions/solution-1.txt', 'wb') as f:
        f.write(solution)
else:
    print("No solution found within constraints")
步骤 3:高级符号执行技术
技术 1:Hook 库函数
# Replace complex library functions with symbolic summaries
import angr

# Hook strcmp to return symbolic value
class StrCmpHook(angr.SimProcedure):
    def run(self, s1, s2):
        # Return symbolic comparison result
        s1_str = self.state.memory.load(s1, 32)
        s2_str = self.state.memory.load(s2, 32)
        return s1_str == s2_str

project.hook_symbol('strcmp', StrCmpHook())
技术 2:合并复杂路径的状态
# Merge states at loop entry to prevent explosion
simgr.use_technique(angr.exploration_techniques.Veritesting())

# Alternative: Manual state merging
while simgr.active:
    simgr.step()
    if len(simgr.active) > 50:
        # Merge similar states
        simgr.merge()
技术 3:简化约束
# Add intermediate constraints to guide exploration
state.add_constraints(
    flag[0:4] == b'FLAG'  # Known prefix from hints
)

# This reduces search space dramatically
# Without: 256^32 possibilities
# With: 256^28 possibilities (4 bytes fixed)
步骤 4:验证解
# Test synthesized input
echo "FLAG_synthesized_solution_here" | ./binary.exe

# Expected output:
# "Success! You reached the target state."
# "Congratulations! Flag: CTF{...}"

验证步骤:

  1. 使用合成的输入运行二进制文件
  2. 验证执行是否到达目标地址(0x401337)
  3. 检查输出是否与预期的成功消息相符
  4. 将经过验证的解存储在 memory-mcp 中
步骤 5:输出结构
re-project/sym/
├── angr-script.py           # Reproducible Angr script
├── solutions/
│   ├── solution-1.txt       # First valid solution
│   ├── solution-2.txt       # Alternative solution (if --find-all)
│   └── solution-3.txt
├── constraints/
│   ├── path-1.smt2          # Z3 constraints for path 1
│   ├── path-2.smt2
│   └── simplified.smt2      # Simplified constraint set
├── validation.log           # Validation test results
└── exploration-metrics.json # States explored, time taken, coverage

exploration-metrics.json:

{
  "total_states": 847,
  "found_states": 3,
  "avoided_states": 124,
  "deadended_states": 720,
  "execution_time_sec": 3245,
  "coverage_percent": 78.5,
  "memory_usage_mb": 2847,
  "solutions_found": 3
}

高级选项

自定义断点(动态分析)
# Set breakpoints at crypto functions
/re:dynamic binary.exe --breakpoints AES_encrypt,RSA_sign,MD5_update

# Set breakpoints at specific addresses
/re:dynamic binary.exe --breakpoints 0x401000,0x402000,0x403000

# Conditional breakpoints (GDB syntax)
/re:dynamic binary.exe --breakpoints "0x401234 if $rdi == 0x601000"

高级 GDB 脚本:

# Custom GDB Python script (auto-loaded if found)
# re-project/gdb-script.py

import gdb

class PasswordBreakpoint(gdb.Breakpoint):
    def __init__(self, location):
        super().__init__(location)

    def stop(self):
        # Extract password from RDI register
        rdi = gdb.parse_and_eval('$rdi')
        password = gdb.execute(f'x/s {rdi}', to_string=True)

        # Log to file
        with open('passwords.log', 'a') as f:
            f.write(f"{password}\n")

        # Continue execution
        return False

# Set custom breakpoint
PasswordBreakpoint("check_password")
符号探索策略
策略 1:查找所有解
# Exhaustive search (may take hours)
/re:symbolic binary.exe \
  --target-addr 0x401337 \
  --find-all true \
  --max-solutions 10 \
  --timeout 14400
# In Angr script
simgr.explore(
    find=0x401337,
    avoid=avoid_addrs,
    num_find=10  # Find up to 10 solutions
)

# Process all found solutions
for idx, state in enumerate(simgr.found):
    solution = state.solver.eval(flag, cast_to=bytes)
    with open(f'solution-{idx+1}.txt', 'wb') as f:
        f.write(solution)
策略 2:限制状态爆炸
# Aggressive pruning
/re:symbolic binary.exe \
  --max-states 100 \
  --avoid-addrs 0x401400,0x401500,0x401600 \
  --strategy dfs  # Depth-first search (memory efficient)
# Use Veritesting to merge paths
simgr.use_technique(angr.exploration_techniques.Veritesting())

# Drop states if too many active
simgr.use_technique(angr.exploration_techniques.LengthLimiter(max_length=100))

# Prioritize states closer to target
simgr.use_technique(angr.exploration_techniques.Explorer(
    find=0x401337,
    avoid=avoid_addrs,
    num_find=1
))
策略 3:约束不足的符号执行
# Start from target address and work backwards
project = angr.Project('./binary.exe')

# Create state at target address (not entry point)
state = project.factory.blank_state(addr=0x401337)

# Make all memory symbolic
state.options.add(angr.options.SYMBION_SYNC_CLE)

# Explore backwards to find required input
simgr = project.factory.simulation_manager(state)
simgr.explore(find=project.entry)

# This finds inputs that MUST lead to target
内存转储分析
# Dump specific memory regions
/re:dynamic binary.exe \
  --dump-regions heap,stack,data \
  --dump-at-breakpoints 0x401234,0x401567

自定义内存分析:

# GDB Python script for heap analysis
import gdb

def analyze_heap():
    # Get heap boundaries
    mappings = gdb.execute('info proc mappings', to_string=True)
    heap_start = extract_heap_start(mappings)
    heap_end = extract_heap_end(mappings)

    # Scan for interesting patterns
    for addr in range(heap_start, heap_end, 8):
        value = gdb.execute(f'x/g {addr}', to_string=True)

        # Check if value looks like a pointer
        if is_valid_pointer(value):
            gdb.execute(f'x/s {value}')  # Dereference as string

analyze_heap()

综合工作流示例

工作流 1:使用运行时机密信息进行恶意软件分析

场景:分析恶意软件样本,提取 C2 服务 URL 和加密密钥

阶段 1:动态分析(级别 3)

# Step 1: Safe sandbox execution
/re:dynamic malware.exe --sandbox true --network-monitor true

# Step 2: GDB session auto-starts with breakpoints from static analysis
# Breakpoints at: decrypt_config, connect_to_c2, send_beacon

# Step 3: At decrypt_config breakpoint (0x401234)
(gdb) info registers
RAX: 0x0000000000601000  → encrypted_buffer
RDI: 0x0000000000601100  → decryption_key

(gdb) x/s 0x601100
0x601100: "hardcoded_AES_key_12345"

# Step 4: Continue to connect_to_c2 breakpoint (0x401567)
(gdb) continue

(gdb) x/s $rdi
0x601200: "http://malicious-c2.tk:8443/beacon"

# Step 5: Extract all findings
Runtime Secrets Found:
- AES Key: "hardcoded_AES_key_12345"
- C2 URL: "http://malicious-c2.tk:8443/beacon"
- User-Agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"

阶段 2:决策关卡

// Automatically evaluated
QUESTION: "Proceed to symbolic execution?"
FACTORS:
- All critical functions reached ✅
- Secrets extracted (AES key, C2 URL) ✅
- User's question answered (extract IOCs) ✅
- No unreachable paths requiring symbolic execution ❌
DECISION: STOP AT LEVEL 3 (sufficient findings)

输出:在 45 分钟内完成恶意软件分析,并完整提取 IOC。


工作流 2:CTF 挑战——逆向分析许可证检查

场景:查找有效许可证密钥,以解锁二进制文件中的“高级功能”

阶段 1:动态分析(级别 3)

# Step 1: Test with invalid key
/re:dynamic challenge.exe --args "--license AAAA-BBBB-CCCC-DDDD"

# Output: "Invalid license key"

# Step 2: GDB reveals license check at 0x401234
(gdb) break *0x401234
(gdb) run --license AAAA-BBBB-CCCC-DDDD

# Step 3: Examine comparison
(gdb) x/s $rdi
0x7fffffffe010: "AAAA-BBBB-CCCC-DDDD"  # User input

(gdb) x/s $rsi
0x601000: [encrypted data, not readable]

# Observation: License key is compared against encrypted/hashed value
# Cannot extract valid key directly from memory

阶段 2:决策关卡

QUESTION: "Proceed to symbolic execution?"
FACTORS:
- License check function found ✅
- Valid key NOT extractable from memory ✅
- Comparison is complex (encryption/hashing) ✅
- User wants valid license key ✅
DECISION: ESCALATE TO LEVEL 4 (symbolic execution required)

阶段 3:符号执行(级别 4)

# Launch Angr symbolic execution
/re:symbolic challenge.exe \
  --target-addr 0x401337 \  # "Premium features unlocked" message
  --avoid-addrs 0x401400 \  # "Invalid license" path
  --input-format "FLAG-XXXX-XXXX-XXXX" \
  --max-states 500

Angr 脚本(自动生成):

import angr
import claripy

project = angr.Project('./challenge.exe', auto_load_libs=False)

# License key format: FLAG-XXXX-XXXX-XXXX (19 chars)
license_key = claripy.BVS('license', 19 * 8)

# Create entry state with symbolic license as argv[2]
state = project.factory.entry_state(args=['./challenge.exe', '--license', license_key])

# Constrain to valid format: FLAG-XXXX-XXXX-XXXX
for i in range(19):
    if i in [0, 1, 2, 3]:  # "FLAG"
        state.add_constraints(license_key.get_byte(i) == ord("FLAG"[i]))
    elif i in [4, 9, 14]:  # Dashes
        state.add_constraints(license_key.get_byte(i) == ord('-'))
    else:  # X = uppercase letters or digits
        byte = license_key.get_byte(i)
        state.add_constraints(
            claripy.Or(
                claripy.And(byte >= ord('A'), byte <= ord('Z')),
                claripy.And(byte >= ord('0'), byte <= ord('9'))
            )
        )

# Explore
simgr = project.factory.simulation_manager(state)
simgr.explore(find=0x401337, avoid=0x401400)

if simgr.found:
    solution = simgr.found[0].solver.eval(license_key, cast_to=bytes)
    print(f"Valid License: {solution.decode()}")
    # Output: "FLAG-A7B2-C9D4-E1F6"

验证:

$ ./challenge.exe --license FLAG-A7B2-C9D4-E1F6
Premium features unlocked!
Congratulations! Here is your flag: CTF{symbolic_execution_wins}

输出:总计用时 3.5 小时解决挑战(45 分钟动态分析 + 3 小时符号执行)。


工作流 3:漏洞研究——缓冲区溢出

场景:在服务端二进制文件中查找可利用的缓冲区溢出漏洞

阶段 1:动态分析(级别 3)

# Step 1: Launch server in sandbox
/re:dynamic server.bin --args "--port 8080" --sandbox true

# Step 2: Fuzz with large inputs
echo "A"*1000 | nc localhost 8080

# GDB catches segfault
Program received signal SIGSEGV, Segmentation fault.
0x4141414141414141 in ?? ()

# Step 3: Analyze crash
(gdb) info registers
RIP: 0x4141414141414141  # Overwritten return address
RSP: 0x7fffffffe100
RBP: 0x4141414141414141

(gdb) x/100x $rsp
# Shows stack completely overwritten with 'A' (0x41)

# Step 4: Find offset to return address
# Use pattern_create and pattern_offset from GEF/Pwndbg
(gdb) pattern create 1000
(gdb) run
# Crash at offset 512

# Confirmed: Buffer overflow at offset 512, control of RIP

阶段 2:决策关卡

QUESTION: "Proceed to symbolic execution?"
FACTORS:
- Buffer overflow confirmed ✅
- Offset to RIP known (512 bytes) ✅
- Exploitation demonstrated ✅
- User's goal: find vulnerability ✅ (COMPLETE)
DECISION: STOP AT LEVEL 3 (vulnerability found)

输出:在 30 分钟内完成漏洞研究。


故障排除

问题 1:沙箱阻止执行

症状:二进制文件无法运行,并显示“权限被拒绝”或系统调用被阻止错误

原因:沙箱限制过严,阻止了必要的系统调用

解决方案 1:将必要的系统调用加入白名单

# Check which syscalls are blocked
strace ./binary.exe 2>&1 | grep "Operation not permitted"

# Create custom seccomp profile
cat > sandbox-profile.json <<EOF
{
  "defaultAction": "SCMP_ACT_ERRNO",
  "syscalls": [
    {"names": ["read", "write", "open", "close"], "action": "SCMP_ACT_ALLOW"},
    {"names": ["socket", "connect"], "action": "SCMP_ACT_ALLOW"}
  ]
}
EOF

# Use custom profile
/re:dynamic binary.exe --sandbox-profile sandbox-profile.json

解决方案 2:使用限制较少的沙箱

# Disable network isolation only (allow file access)
/re:dynamic server.bin --sandbox true --allow-network true

# Or use Docker instead of seccomp
docker run --rm -v $(pwd):/work -it ubuntu:20.04 /work/binary.exe

问题 2:GDB 无法附加

症状:出现“ptrace:不允许操作”错误,或 GDB 无法启动

原因:系统安全设置阻止了 ptrace

解决方案 1:临时允许 ptrace(Linux)

# Check current setting
cat /proc/sys/kernel/yama/ptrace_scope
# 1 = restricted, 0 = unrestricted

# Temporarily allow (requires sudo)
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope

# Rerun analysis
/re:dynamic binary.exe

解决方案 2:使用 sudo 运行 GDB

sudo /re:dynamic binary.exe

解决方案 3:使用容器(绕过主机限制)

docker run --cap-add=SYS_PTRACE --rm -it ubuntu:20.04 bash
# Inside container:
apt update && apt install gdb
gdb ./binary.exe

问题 3:Angr 状态爆炸

症状:符号执行耗尽内存,或因有数千个活动状态而超时

原因:二进制文件包含过多分支,导致状态呈指数级爆炸

解决方案 1:添加更多要避开的状态

# Find all "failure" functions from static analysis
/re:static binary.exe --list-functions | grep -i "fail\|error\|exit"

# Add all failure addresses to avoid list
/re:symbolic binary.exe \
  --target-addr 0x401337 \
  --avoid-addrs 0x401400,0x401500,0x401600,0x401700,0x401800 \
  --max-states 100

解决方案 2:使用 Veritesting(自动合并状态)

# In custom Angr script
simgr.use_technique(angr.exploration_techniques.Veritesting())

# This merges similar states, reducing explosion by 10-100x

解决方案 3:从中间地址开始(跳过不重要的代码)

# Skip initialization code, start at license check function
state = project.factory.blank_state(addr=0x401234)

# Set up expected register/memory state (from Level 3 analysis)
state.regs.rdi = state.solver.BVS('input', 32*8)

# Explore from this point only
simgr = project.factory.simulation_manager(state)
simgr.explore(find=0x401337)

问题 4:内存转储过大

症状:GDB 转储数 GB 内存,导致磁盘空间耗尽

原因:转储整个地址空间,而不是指定区域

解决方案 1:使用 vmmap 中的特定内存区域

# Check memory mappings
(gdb) info proc mappings

# Example output:
# 0x400000-0x600000  r-xp  /path/binary.exe  (code)
# 0x600000-0x700000  rw-p  /path/binary.exe  (data)
# 0x7ffff7a0d000-0x7ffff7bcd000  r-xp  /lib/libc.so  (library)

# Dump ONLY data section (where secrets likely are)
(gdb) dump binary memory data-section.bin 0x600000 0x700000

# Dump ONLY stack (where local variables are)
(gdb) dump binary memory stack.bin $rsp-0x1000 $rsp+0x1000

解决方案 2:使用选择性断点转储

# Only dump memory at specific breakpoints, not every instruction
/re:dynamic binary.exe \
  --breakpoints 0x401234,0x401567 \
  --dump-at-breakpoints true \
  --dump-regions stack,heap

问题 5:符号执行超时

症状:Angr 运行数小时仍未找到解

原因:约束求解器(Z3)卡在复杂约束上

解决方案 1:增加超时时间并简化约束

/re:symbolic binary.exe \
  --timeout 14400 \  # 4 hours
  --max-states 200 \
  --simplify-constraints true

解决方案 2:使用增量求解

# Add constraints incrementally instead of all at once
state.solver.add(constraint1)
if state.satisfiable():
    state.solver.add(constraint2)
    if state.satisfiable():
        state.solver.add(constraint3)

解决方案 3:使用更快的求解器(CVC4 或 Boolector)

import angr
import claripy

# Use faster solver backend
claripy.backends.backend_manager.backends._eager_backends = [
    claripy.backends.BackendConcrete,
    claripy.backends.BackendZ3  # Replace with BackendCVC4
]

性能优化

加快动态分析(级别 3)
优化 1:并行跟踪系统调用
# Run strace and ltrace in parallel
(strace -o syscalls.log ./binary.exe &)
(ltrace -o libcalls.log ./binary.exe &)
wait
优化 2:使用 GDB 脚本自动化
# GDB Python script for automatic analysis
# re-project/auto-analyze.py

import gdb

breakpoints = [0x401234, 0x401567, 0x4018ab]

for bp_addr in breakpoints:
    gdb.Breakpoint(f"*{bp_addr}")

# Run until first breakpoint
gdb.execute('run')

# At each breakpoint, dump and continue
for i in range(len(breakpoints)):
    # Dump state
    regs = gdb.execute('info registers', to_string=True)
    stack = gdb.execute('x/100x $rsp', to_string=True)

    with open(f'bp-{i}-state.txt', 'w') as f:
        f.write(f"Registers:\n{regs}\nStack:\n{stack}\n")

    # Continue
    if i < len(breakpoints) - 1:
        gdb.execute('continue')

用法:

gdb -x auto-analyze.py ./binary.exe
优化 3:选择性转储内存
# Only dump memory if interesting patterns found
/re:dynamic binary.exe \
  --dump-on-pattern "password|secret|key|token" \
  --dump-regions heap

加快符号执行(级别 4)
优化 1:使用更快的探索策略
# DFS is memory-efficient but may explore wrong paths
simgr.use_technique(angr.exploration_techniques.DFS())

# BFS finds shortest path but uses more memory
simgr.use_technique(angr.exploration_techniques.BFS())

# Hybrid: BFS until 100 states, then switch to DFS
simgr.use_technique(angr.exploration_techniques.Explorer(
    find=0x401337,
    num_find=1
))
优化 2:预先约束输入空间
# If you know input must start with "FLAG"
for i, char in enumerate("FLAG"):
    state.add_constraints(flag.get_byte(i) == ord(char))

# This reduces search space from 256^32 to 256^28
优化 3:Hook 复杂函数
# Replace slow library functions with fast symbolic summaries
project.hook_symbol('strlen', angr.SIM_PROCEDURES['libc']['strlen']())
project.hook_symbol('strcmp', angr.SIM_PROCEDURES['libc']['strcmp']())
project.hook_symbol('memcpy', angr.SIM_PROCEDURES['libc']['memcpy']())

# These are much faster than symbolically executing the actual implementations
优化 4:并行化探索
# Split state space across multiple cores
from multiprocessing import Pool

def explore_from_state(state):
    simgr = project.factory.simulation_manager(state)
    simgr.explore(find=0x401337, avoid=avoid_addrs)
    return simgr.found

# Split initial state into 4 copies with different constraints
states = [state.copy() for _ in range(4)]
states[0].add_constraints(flag[0] < 0x40)
states[1].add_constraints(claripy.And(flag[0] >= 0x40, flag[0] < 0x60))
states[2].add_constraints(claripy.And(flag[0] >= 0x60, flag[0] < 0x80))
states[3].add_constraints(flag[0] >= 0x80)

# Explore in parallel
with Pool(4) as p:
    results = p.map(explore_from_state, states)

# Collect solutions
for found_states in results:
    if found_states:
        print(found_states[0].solver.eval(flag, cast_to=bytes))

Memory-MCP 集成

存储级别 3 的发现
// After dynamic analysis completes
mcp__memory-mcp__memory_store({
  content: {
    binary_hash: "sha256:abc123...",
    re_level: 3,
    execution_summary: {
      breakpoints_hit: ["0x401234", "0x401567", "0x4018ab"],
      runtime_secrets: [
        {type: "password", value: "admin123", location: "0x601000"},
        {type: "api_key", value: "sk_live_...", location: "0x601020"}
      ],
      syscalls: ["open", "read", "socket", "connect", "send"],
      network_activity: [
        {proto: "HTTP", dest: "192.168.1.100:443", data: "POST /api/login"}
      ]
    },
    gdb_dumps: {
      registers: "re-project/dbg/memory-dumps/",
      stack: "re-project/dbg/memory-dumps/",
      heap: "re-project/dbg/memory-dumps/"
    }
  },
  metadata: {
    agent: "RE-Runtime-Tracer",
    category: "reverse-engineering",
    intent: "dynamic-analysis",
    layer: "long_term",
    project: `binary-analysis-${date}`,
    keywords: ["gdb", "dynamic", "runtime", "secrets"],
    re_level: 3,
    binary_hash: "sha256:abc123...",
    timestamp: new Date().toISOString()
  }
})
存储级别 4 的发现
// After symbolic execution completes
mcp__memory-mcp__memory_store({
  content: {
    binary_hash: "sha256:abc123...",
    re_level: 4,
    symbolic_summary: {
      target_address: "0x401337",
      avoid_addresses: ["0x401400", "0x401500"],
      solutions_found: 3,
      solutions: [
        {input: "FLAG-A7B2-C9D4-E1F6", validated: true},
        {input: "FLAG-B8C3-D0E5-F2G7", validated: true},
        {input: "FLAG-C9D4-E1F6-G3H8", validated: true}
      ],
      exploration_metrics: {
        total_states: 847,
        execution_time_sec: 3245,
        coverage_percent: 78.5
      }
    },
    angr_script: "re-project/sym/angr-script.py",
    constraints: "re-project/sym/constraints/"
  },
  metadata: {
    agent: "RE-Symbolic-Solver",
    category: "reverse-engineering",
    intent: "symbolic-execution",
    layer: "long_term",
    project: `binary-analysis-${date}`,
    keywords: ["angr", "symbolic", "z3", "solver"],
    re_level: 4,
    binary_hash: "sha256:abc123...",
    timestamp: new Date().toISOString()
  }
})
交接模式:级别 3 → 级别 4
// Level 3 stores handoff data
mcp__memory-mcp__memory_store({
  key: `re-handoff/dynamic-to-symbolic/${binary_hash}`,
  value: {
    decision: "ESCALATE_TO_LEVEL_4",
    reason: "Target function unreachable with manual inputs",
    target_address: "0x401337",
    avoid_addresses: ["0x401400", "0x401500", "0x401600"],
    input_format: "FLAG-XXXX-XXXX-XXXX",
    breakpoint_findings: {
      "0x401234": {
        description: "License check function",
        comparison_type: "encrypted",
        extractable: false
      }
    }
  }
})

// Level 4 retrieves handoff data
const handoff = await mcp__memory-mcp__vector_search({
  query: `re-handoff/dynamic-to-symbolic/${binary_hash}`
})

// Use handoff data to configure Angr
const target = handoff.target_address
const avoid = handoff.avoid_addresses
const input_format = handoff.input_format

Agent 与命令

调用的 Agent
  1. RE-Runtime-Tracer(Level 3)

    • 专长:使用 GDB/strace/ltrace 进行动态分析
    • 工具:GDB+GEF/Pwndbg、strace、ltrace、沙箱环境
    • 输出:内存转储、系统调用跟踪、运行时机密信息
  2. RE-Symbolic-Solver(Level 4)

    • 专长:使用 Angr/Z3 进行符号执行
    • 工具:Angr、Z3、Python 符号执行框架
    • 输出:合成输入、约束文件、经过验证的解决方案
  3. sandbox-validator(Level 3,自动)

    • 提供安全的二进制执行环境
    • 防止恶意软件逃逸和系统损坏
  4. graph-analyst(Level 4,自动)

    • 生成执行路径可视化图
    • 创建约束依赖关系图
斜杠命令
  • /re:deep <binary> - 完整的 Level 3+4 分析(此技能的主要命令)
  • /re:dynamic <binary> - 仅 Level 3(动态分析)
  • /re:symbolic <binary> - 仅 Level 4(符号执行)
MCP 服务
  • sandbox-validator:通过隔离实现安全的二进制执行
  • memory-mcp:跨会话持久化、交接协调
  • sequential-thinking:用于升级处理的决策门逻辑
  • graph-analyst:可视化执行路径和约束

相关技能


资源

外部工具
  • GDB - GNU 调试器
  • GEF - GDB 增强功能
  • Pwndbg - 用于漏洞利用开发的 GDB 插件
  • Angr - 二进制分析平台
  • Z3 - Microsoft SMT 求解器
学习资源
社区

创建日期:2025-11-01 RE 级别:3-4(动态分析 + 符号执行) 时间限制:3-7 小时 Agent:RE-Runtime-Tracer、RE-Symbolic-Solver 类别:安全、恶意软件分析、CTF、二进制漏洞利用 难度:高级

核心原则

逆向工程:深度分析遵循 3 项基本原则:

原则 1:优先隔离执行

运行时分析必须在隔离环境中进行,以防止恶意软件逃逸和系统遭到入侵。

实际操作:

  • 在带网络监控的快照 VM/容器中执行所有二进制文件
  • 使用沙箱调试器(Docker 中的 GDB、快照模式下的 QEMU)
  • 在执行期间监控系统调用、网络流量和文件操作
  • 为 APT 分析维护气隙实验室基础设施
原则 2:多方法验证

单一分析技术无法提供完整的真相——交叉验证可避免误报。

实际操作:

  • 静态分析发现必须通过动态执行确认
  • 动态行为必须能在多次运行中复现
  • 符号执行结果必须通过真实执行路径验证
  • 内存转储必须与网络捕获和系统调用跟踪相关联
原则 3:渐进式升级

从轻量级方法开始,仅在必要时升级,以尽量缩短分析时间。

实际应用中:

  • 第 3 级(动态分析)可在 1 小时内揭示 80% 的恶意软件行为
  • 只有在手动方式无法触及相关路径时,才升级到第 4 级(符号执行)
  • 使用决策关卡,避免对简单分析任务过度设计
  • 将发现缓存到 memory-mcp 中,避免重复工作

常见反模式

反模式问题解决方案
在主机系统上执行恶意软件系统完全受损、数据外泄、勒索软件部署始终使用隔离的 VM,并启用快照、网络监控和回滚功能
动态分析前跳过静态分析浪费时间执行却不了解程序,漏掉加壳二进制文件先运行第 1–2 级(字符串分析 + 静态分析),识别入口点和断点
过度依赖符号执行状态爆炸、分析超时、资源耗尽仅对手动模糊测试无法触及的输入依赖路径使用符号执行
忽略反分析技术调试器检测会终止分析,VM 检测会改变行为修补反调试检查,使用隐蔽的调试环境,并监控时序攻击
未记录分析方法结果无法复现、发现受到质疑、出现法律问题为所有操作添加时间戳,保存 GDB 记录,并记录所用工具版本和命令

结论

逆向工程:深度分析是静态代码检查与完整理解程序之间的关键桥梁。通过结合运行时执行(第 3 级)和符号路径探索(第 4 级),这项技能可帮助安全研究人员提取机密、验证漏洞,并合成能够到达特定程序状态的输入——这些能力对于恶意软件分析、CTF 挑战和漏洞研究至关重要。

这项技能的强大之处在于其自动化决策关卡和渐进式升级策略。它不会立即转向资源消耗较大的符号执行,而是先使用 GDB 和系统调用跟踪进行轻量级动态分析。只有在手动执行无法到达目标状态时,才会升级到基于 Angr 的符号执行,在最大化发现成果的同时缩短分析时间。

当你需要了解静态分析无法揭示的运行时行为时,可使用这项技能:例如内存中的机密、网络通信模式,或复杂身份验证方案的有效输入。这项技能擅长从恶意软件中提取失陷指标、在 crackmes 中寻找有效许可证密钥,以及为漏洞生成概念验证利用程序。结合 memory-mcp 集成以实现跨会话持久化,以及与固件分析(第 5 级)的交接协调,它构成了一套全面的逆向工程工作流,适用于学术研究和生产环境中的安全运营。

评论

支持 Markdown