关于 reverse-engineering-deep-analysis
面向安全研究人员的深度逆向分析 skill,覆盖隔离环境中的动态分析与符号执行。它要求先检查项目库和既有模式,并以多种方法验证分析结果。
主要功能
- 01先检查库目录与既有模式
- 02在隔离沙箱中执行动态分析
- 03使用 GDB 跟踪运行状态与系统调用
- 04通过 Angr 和 Z3 进行符号执行
- 05采集内存、栈和网络活动证据
- 06交叉验证并记录分析结果
适用场景
- 01在授权范围内分析可疑二进制文件
- 02提取运行时行为和恶意指标
- 03评估漏洞并探索未覆盖的执行路径
- 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.yamlresources/README.mdresources/scripts/angr-symbolic-exec.pygdb-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 地址)
基于证据的验证
所有逆向工程发现都必须通过以下方式验证:
- 多方法分析——通过静态分析 + 动态分析 + 符号执行确认相同行为
- 沙箱验证——在隔离环境中执行,并捕获所有活动
- 网络监控——通过数据包捕获验证基于网络的发现
- 内存取证——通过内存转储验证运行时机密信息
- 行为关联——与已知恶意软件特征(YARA、ClamAV)交叉比对
- 可复现性——第二位分析人员能够根据分析产物复现发现
逆向工程:深度分析
此技能的功能
通过运行时执行和符号探索进行深度逆向工程:
- 第 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{...}"
验证步骤:
- 使用合成的输入运行二进制文件
- 验证执行是否到达目标地址(0x401337)
- 检查输出是否与预期的成功消息相符
- 将经过验证的解存储在 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
-
RE-Runtime-Tracer(Level 3)
- 专长:使用 GDB/strace/ltrace 进行动态分析
- 工具:GDB+GEF/Pwndbg、strace、ltrace、沙箱环境
- 输出:内存转储、系统调用跟踪、运行时机密信息
-
RE-Symbolic-Solver(Level 4)
- 专长:使用 Angr/Z3 进行符号执行
- 工具:Angr、Z3、Python 符号执行框架
- 输出:合成输入、约束文件、经过验证的解决方案
-
sandbox-validator(Level 3,自动)
- 提供安全的二进制执行环境
- 防止恶意软件逃逸和系统损坏
-
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:可视化执行路径和约束
相关技能
- 逆向工程:快速初筛 - Level 1-2(字符串 + 静态分析)
- 逆向工程:固件 - Level 5(固件提取)
- 功能审计 - 验证逆向工程得到的逻辑
- 生产环境验证器 - 确保分析结果可用于生产环境
资源
外部工具
学习资源
- Angr 文档 - 完整的 Angr 指南
- Z3 教程 - Z3 Python 绑定
- GDB 到 LLDB 命令对照表 - 适用于 macOS 用户
- 实用二进制分析 - 书籍
社区
- Angr Slack - Angr 官方社区
- r/ReverseEngineering - Subreddit
- Binary Ninja Discord - 逆向工程社区
创建日期: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 级)的交接协调,它构成了一套全面的逆向工程工作流,适用于学术研究和生产环境中的安全运营。