- name
- reverse-engineering
- category
- binary
- description
- Reverse engineering workflow for web, desktop binaries, mobile apps, network protocols, encryption, signatures, and dynamic analysis.
# 逆向工程
## 概述
逆向工程是从外部观察推断内部实现的过程。四个目标领域共享同一核心哲学:
**从可见到隐藏、从静态到动态、从简单到复杂。**
通用工作流:`目标识别 → 表面分析 → 深入分析 → 机制还原 → 复现`
不要上来就深入细节——先理解你面对的是什么,再选择合适的工具和方法。
## 何时使用
- **Web**:开发爬虫、提取 API、竞品技术分析、复现网站功能
- **二进制**:软件安全审计(授权)、恶意软件分析、互操作性开发
- **移动端**:App 安全审计、SDK 行为分析、第三方库审查
- **协议**:IoT 设备逆向、自定义协议还原、API 文档补全
**不适用:** 未授权的渗透测试、窃取商业数据、绕过付费墙、制作盗版软件。
> **法律提示:** 逆向工程必须在合法授权范围内进行。中国适用《网络安全法》《数据安全法》《计算机软件保护条例》。仅在拥有书面授权、CTF 比赛、Bug Bounty 计划或自有系统安全审计时进行。
## 通用基础
### 常见加密速查
不管逆向什么目标,加密是共性问题。以下是最常见的算法和 Python 复现一行式:
```python
import hashlib, hmac, base64
from Crypto.Cipher import AES, DES, DES3, PKCS1_v1_5
from Crypto.PublicKey import RSA
from Crypto.Util.Padding import pad, unpad
# --- 哈希 ---
hashlib.md5(b'text').hexdigest()
hashlib.sha256(b'text').hexdigest()
hmac.new(b'key', b'msg', hashlib.sha256).hexdigest()
# --- AES ---
aes = AES.new(b'16bytekey123456', AES.MODE_CBC, b'16byteiv12345678')
base64.b64encode(aes.encrypt(pad(b'plaintext', 16))).decode() # 加密
unpad(AES.new(b'16bytekey123456', AES.MODE_CBC, b'16byteiv12345678').decrypt(base64.b64decode('密文')), 16).decode() # 解密
# AES-ECB 无 IV: AES.new(key, AES.MODE_ECB)
# --- RSA ---
key = RSA.import_key(open('pub.pem').read())
base64.b64encode(PKCS1_v1_5.new(key).encrypt(b'plaintext')).decode()
# --- 国密 SM2/SM4 (pip install gmssl) ---
from gmssl import sm2, sm4
# SM2: sm2.CryptSM2(public_key=pub, private_key='').encrypt(plain)
# SM4: sm4.CryptSM4().set_key(key, sm4.SM4_ENCRYPT); crypt.crypt_ecb(plain)
# --- 编码检测 ---
# Base64 特征:A-Za-z0-9+/=,长度 4 的倍数
# Hex 特征:0-9a-f,长度偶数
# URL 编码:%XX 格式
```
### 调试基础
**断点策略:**
| 类型 | 适用场景 | 工具 |
|------|---------|------|
| 软件断点 | 代码级调试,函数入口 | x64dbg/GDB/LLDB |
| 条件断点 | 只在特定条件触发 | 所有调试器 |
| 硬件断点 | 反调试绕过、内存访问 | x64dbg/GDB (`watch`) |
| 内存断点 | 监控内存区域读写执行 | x64dbg/Cheat Engine |
| 日志断点 | 不暂停,只记录值 | x64dbg/WinDbg |
**调用栈阅读:**
```
关键原则:从下往上读(最下面是调用起点,最上面是当前执行点)
关注:函数名、参数值、返回地址、栈上的局部变量
```
**内存布局(x86/x64):**
```
高地址 ┌─────────────┐
│ Stack │ ← 局部变量、函数参数(向下增长)
├─────────────┤
│ ↓ ↑ │
├─────────────┤
│ Heap │ ← malloc/new 分配(向上增长)
├─────────────┤
│ .bss │ ← 未初始化全局变量
├─────────────┤
│ .data │ ← 已初始化全局变量
├─────────────┤
│ .text │ ← 代码段(只读、可执行)
低地址 └─────────────┘
```
### 逆向方法论
**静态 vs 动态分析选择:**
| 场景 | 推荐方法 | 原因 |
|------|---------|------|
| 代码逻辑清晰 | 静态分析 | 直接阅读伪代码更高效 |
| 有反调试/混淆 | 动态分析 | 运行时绕过比静态还原更快 |
| 加密算法还原 | 动态 + Hook | 直接拦截输入输出 |
| 漏洞发现 | 静态为主 | 需要全面审查代码路径 |
| 协议分析 | 动态抓包 | 运行时数据最真实 |
**发现记录模板:**
```markdown
## 逆向发现 #N
- **目标:** [文件/接口/协议]
- **方法:** [静态分析/动态调试/Hook/抓包]
- **发现:** [具体功能、算法、密钥、接口]
- **证据:** [截图/日志/代码片段]
- **复现:** [如何验证这个发现]
- **置信度:** [高/中/低]
```
## 第一部分:Web 逆向
### 1.1 技术指纹识别
**快速检测:**
```bash
# HTTP 头
curl -sI https://example.com | grep -iE "server|x-powered-by|x-framework|set-cookie"
# HTML 特征(前 100 行)
curl -s https://example.com | head -100
# 寻找:meta generator、script src、注释中的框架标识
# JS bundle 框架水印
curl -s https://example.com | grep -oP 'src="[^"]*\.js"' | head -5
curl -s https://example.com/static/js/main.js | grep -oE '(React|Vue|Angular|Next|Nuxt|Svelte)' | sort -u
```
**常见指纹表:**
| 特征 | 技术 | 特征 | 技术 |
|------|------|------|------|
| `__NEXT_DATA__` | Next.js | `__nuxt` / `__NUXT__` | Nuxt.js |
| `data-reactroot` | React | `ng-version` | Angular |
| `__vue__` / `data-v-` | Vue.js | `vite` 相关路径 | Vite |
| `Set-Cookie: PHPSESSID` | PHP | `Set-Cookie: JSESSIONID` | Java |
| `Set-Cookie: csrftoken` | Django | `/wp-content/` | WordPress |
| `X-Powered-By: Express` | Node.js | `.wxml/.wxss` | 微信小程序 |
### 1.2 前端架构分析
**SPA 路由提取:**
```javascript
// Vue Router
JSON.stringify(
document.querySelector('#app').__vue_app__
?.config.globalProperties?.$router?.options?.routes
?.map(r => ({ path: r.path, children: r.children?.map(c => c.path) })),
null, 2
)
// Next.js — 从 _buildManifest.js 获取页面路由
fetch('/_next/static/' + document.querySelector('script[src*="_buildManifest"]')
?.src.match(/_next\/static\/([^/]+)/)?.[1] + '/_buildManifest.js')
.then(r => r.text()).then(console.log)
```
**构建产物分析:**
```bash
# 查找 source map(可能泄露完整源码)
curl -s https://example.com/static/js/main.js.map -o main.map
npx source-map-explorer main.map
# 提取路由和 API 端点
curl -s https://example.com/static/js/main.js | \
grep -oP '"/(api|auth|admin|dashboard|user|login|register)[^"]*"' | sort -u
```
### 1.3 网络流量捕获
**DevTools 操作流程:**
1. Network 面板 → 勾选 "Preserve log"
2. 清空记录 → 执行目标操作(登录、搜索、翻页等)
3. 按类型筛选:XHR/Fetch 为主
4. 检查每个请求:URL、Headers、Body、Response、Status Code
**curl 复现模板:**
```bash
# 从 DevTools 右键 → Copy as cURL 获取完整命令
# 精简为最小参数后复现
curl -X POST 'https://example.com/api/v1/search' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <token>' \
-d '{"keyword":"test","page":1}' | jq '.data'
```
**批量端点发现:**
```bash
curl -s https://example.com/static/js/app.js | \
grep -oP '["`]/api/[^"`\s]+["`]' | tr -d '"' | sort -u
```
### 1.4 认证逆向
**认证机制识别:**
```
Set-Cookie: sessionid=xxx → Cookie-based
响应体 {token, refresh_token} → JWT-based
302 重定向到第三方 → OAuth/SSO
```
**登录流程追踪:**
```
1. Network 面板 → 输入账号密码 → 点击登录
2. 找到 POST 请求(通常 /login, /auth, /api/auth)
3. 分析请求体:{username, password, captcha?, csrf_token?}
4. 分析响应:Set-Cookie / token / redirect
5. 追踪后续请求如何携带凭证(Cookie / Authorization Header)
```
**JWT 解码:**
```bash
echo "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.xxx" | cut -d. -f2 | base64 -d 2>/dev/null | jq
```
**Token 提取:**
```javascript
// localStorage / sessionStorage
Object.keys(localStorage).forEach(k =>
console.log(k, '=', localStorage[k].substring(0, 50))
);
```
### 1.5 加密速查表
| 加密库 | 特征关键词 | 典型用途 | 详细参考 |
|--------|-----------|---------|---------|
| JSEncrypt | `setPublicKey`, `encrypt()` | RSA 加密密码 | → references/web-re.md |
| CryptoJS.AES | `CryptoJS.AES`, `aes-encrypt` | 参数加密/响应解密 | → references/web-re.md |
| sm-crypto | `sm2`, `sm4`, `gmCrypt` | 国密算法 | → references/web-re.md |
| forge | `forge.cipher`, `forge.pki` | RSA/AES/证书 | → references/web-re.md |
| Web Crypto | `SubtleCrypto`, `crypto.subtle` | 浏览器原生加密 | → references/web-re.md |
| WASM 加密 | `wasm`, `Module._malloc` | 高强度混淆 | → references/web-re.md |
**签名机制 4 种模式:**
```
模式 1: sign = MD5(key1=val1&key2=val2&secret=xxx) # 参数排序 + 密钥
模式 2: sign = HMAC-SHA256(secret, timestamp+nonce+body) # HMAC
模式 3: sign = SHA256(ts + nonce + sorted_params + secret) # 时间戳+随机数
模式 4: sign = Base64(HMAC-SHA256(secret, method+path+body_hash)) # 请求体哈希
```
> **详细加密逆向**(JS Hook 代码、WASM 分析、JS 反混淆、密钥提取技巧)→ **references/web-re.md**
### 1.6 数据流文档化
**端点文档模板:**
```markdown
### POST /api/v1/login
- 用途:用户登录
- 参数:{ username: string, password: string }
- 认证:无
- 响应:{ code: 0, data: { token: string, expires_in: int } }
- 注意:密码经 RSA 加密(见 login.js 中的 encrypt 函数)
```
**Python 复现模板:**
```python
import requests
class SiteClient:
def __init__(self, base_url):
self.base_url = base_url
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...',
'Accept': 'application/json',
})
def login(self, username, password):
resp = self.session.post(f'{self.base_url}/api/login', json={
'username': username, 'password': password,
})
data = resp.json()
if data.get('code') == 0:
self.session.headers['Authorization'] = f"Bearer {data['data']['token']}"
return data
def get_users(self, page=1, size=20):
return self.session.get(f'{self.base_url}/api/users',
params={'page': page, 'size': size}).json()
```
> **详细安全测试**(认证测试、越权检测、漏洞报告模板)→ **references/web-re.md**
## 第二部分:二进制逆向
### 2.1 文件识别
```bash
# 快速识别文件类型
file target.exe # 通用识别
binwalk target.exe # 嵌入文件检测
# Detect It Easy (DIE) — GUI 工具,识别编译器、壳、加密库
# PEiD — PE 文件查壳(经典工具)
```
| 文件类型 | 平台 | 特征 | 分析工具 |
|---------|------|------|---------|
| PE (.exe/.dll) | Windows | `MZ` 魔数 | IDA, x64dbg, dnSpy |
| ELF (.so/可执行) | Linux | `ELF` 魔数 | IDA, GDB, Ghidra |
| Mach-O | macOS | `FEEDFACE/F` | Hopper, LLDB |
| .NET DLL | 跨平台 | IL 元数据 | dnSpy, ILSpy |
| .class/.jar | 跨平台 | `CAFEBABE` | jadx, CFR |
| .dex | Android | `dex\n035` | jadx, apktool |
### 2.2 静态分析
**IDA Pro 核心操作:**
```
View on GitHub