# Protocol Analysis

> 网络协议逆向分析（HTTP API/WebSocket/gRPC/Protobuf/自定义二进制协议）。 TRIGGER when: 用户需要分析 API 协议、WebSocket 通信协议、gRPC 接口、Protobuf 结构还原、二进制协议解析、签名/加密请求重放。包括但不限于"分析这个API"、"WebSocket协议怎么解"、"Protobuf逆向"、"请求怎么构造"、"协议分析"、"gRPC怎么调用"、"还原请求格式"。 DO NOT TRIGGER when: 只是找加密入口（用 find-crypto-entry）、或单纯抓包（直接用 MCP 工具）。

- Skill: `zxzvsdcj/protocol-analysis` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add zxzvsdcj/protocol-analysis`
- Raw SKILL.md: https://api.skillmd.com/api/skills/zxzvsdcj/protocol-analysis/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: zxzvsdcj (https://skillmd.com/u/zxzvsdcj)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/zxzvsdcj/protocol-analysis

---


# protocol-analysis

对 **$ARGUMENTS** 执行协议逆向分析。

**MCP 依赖**:
- `js-reverse-mcp` — WebSocket 分析、请求发起栈追踪、JS 内执行
- `android_proxy_mcp` — HTTP/HTTPS 流量捕获与搜索（Android 场景）

---

## 协议类型识别

首先判断目标使用的协议类型：

| 特征 | 协议类型 | 后续处理 |
|------|---------|---------|
| `Content-Type: application/json` | REST JSON API | → Stage A |
| `Upgrade: websocket` | WebSocket | → Stage B |
| `Content-Type: application/grpc` | gRPC | → Stage C |
| `Content-Type: application/x-protobuf` | Protobuf | → Stage C |
| 请求体为不可读二进制 | 自定义二进制协议 | → Stage D |
| `Content-Type: application/x-www-form-urlencoded` | 表单编码 | → Stage A |
| `Content-Type: multipart/form-data` | 多部分表单 | → Stage A |

---

## Stage A: HTTP REST API 分析

### A.1 请求结构分析

```
Web 场景 (js-reverse-mcp):
  1. list_network_requests → 列出所有请求
  2. get_request_initiator(reqid) → 获取请求发起的 JS 调用栈
  3. search_in_sources("api/v1") → 在 JS 中搜索 API 端点定义

Android 场景 (android_proxy_mcp):
  1. traffic_list(domain="api.target.com") → 按域名筛选
  2. traffic_get_detail(reqid) → 查看请求/响应头
  3. traffic_read_body(reqid) → 读取请求/响应体
  4. traffic_search("sign") → 搜索包含签名的请求
```

### A.2 参数分析

```
对比分析:
  1. 收集多次相同接口的请求
  2. 对比哪些字段固定、哪些变化
  3. 变化字段分类:
     - 时间戳类（值递增，通常 10 或 13 位数字）
     - 随机数类（每次不同，无规律）
     - 签名类（固定长度 hex/Base64，值随其他参数变化）
     - 会话类（相同会话内固定，换设备/登录变化）
```

### A.3 签名还原

找到签名参数后，转到 `find-crypto-entry` skill 定位加密入口。

### A.4 请求重放验证

```python
import requests

# 构造请求
headers = {
    "User-Agent": "...",
    "X-Sign": sign(params),
    "X-Timestamp": str(int(time.time())),
}
resp = requests.get("https://api.target.com/v1/feed", headers=headers, params=params)
print(resp.status_code, resp.json())
```

---

## Stage B: WebSocket 协议分析

### B.1 连接发现

```
1. get_websocket_messages() → 列出所有 WebSocket 连接
   返回: wsId, url, 消息数量, 连接状态

2. get_websocket_messages(wsId) → 查看消息概览
   返回: 消息模式分析、方向（发送/接收）、时间

3. search_in_sources("new WebSocket") → 找到 WS 创建代码
```

### B.2 消息格式识别

| 格式 | 识别方法 | 处理方式 |
|------|---------|---------|
| JSON | 可直接解析 | 直接分析字段含义 |
| 二进制 + JSON | 前几个字节是头部，后续是 JSON | 分析头部结构（消息类型/长度） |
| Protobuf | 二进制 + 字段编号 | → Stage C |
| 自定义二进制 | 不可读 | → Stage D |
| 文本协议 | 纯文本，有分隔符 | 分析分隔符和字段格式 |

### B.3 消息追踪

```
1. 在 WebSocket.send 处设断点:
   set_breakpoint_on_text(".send(")
   
2. 触发操作 → 断点命中 → evaluate_script 检查:
   - 发送的消息内容
   - 消息是如何构造的
   - 是否有序列号/心跳机制

3. 在 onmessage 处设断点:
   set_breakpoint_on_text("onmessage")
   → 分析接收到的消息如何被处理
```

### B.4 心跳与认证

```
常见模式:
  - 连接后发送认证消息（含 token/签名）
  - 定时心跳（ping/pong 或自定义心跳包）
  - 消息序列号（递增 ID）
  - 订阅/取消订阅机制
```

---

## Stage C: gRPC / Protobuf 分析

### C.1 Protobuf 结构还原

```
方式 A: 有 .proto 文件
  直接使用 protoc 编译生成代码

方式 B: 从二进制推断（无 .proto）
  1. 安装 protobuf 工具:
     pip install protobuf blackboxprotobuf
  
  2. 使用 blackboxprotobuf 自动推断:
     import blackboxprotobuf
     message, typedef = blackboxprotobuf.decode_message(binary_data)
     print(message)   # 推断的字段结构
     print(typedef)   # 推断的类型定义

  3. 手工还原 .proto:
     根据推断结果编写 proto 文件
```

### C.2 Protobuf 字段类型速查

| Wire Type | 类型 | 字段 |
|-----------|------|------|
| 0 | Varint | int32, int64, uint32, uint64, sint32, sint64, bool, enum |
| 1 | 64-bit | fixed64, sfixed64, double |
| 2 | Length-delimited | string, bytes, embedded messages, repeated |
| 5 | 32-bit | fixed32, sfixed32, float |

### C.3 gRPC 调用重放

```python
# 使用 grpcurl 测试
# grpcurl -d '{"field": "value"}' -plaintext host:port package.Service/Method

# Python gRPC 客户端
import grpc
channel = grpc.insecure_channel('host:port')

# 无 .proto 时，用反射
from grpc_reflection.v1alpha import reflection_pb2_grpc
stub = reflection_pb2_grpc.ServerReflectionStub(channel)
# 通过反射获取服务列表和消息类型
```

---

## Stage D: 自定义二进制协议分析

### D.1 数据采集

收集多组请求/响应的原始二进制数据。

### D.2 格式推断

```
分析步骤:
  1. Hex 对比多组数据
  2. 识别固定头部（magic number / 版本号）
  3. 识别长度字段（通常在前 4-8 字节）
  4. 识别消息类型字段
  5. 推断字段边界和编码方式

常见结构:
  [Magic 2B] [Version 1B] [Type 2B] [Length 4B] [Body NB] [Checksum 2B]
```

### D.3 字段编码识别

| 特征 | 编码方式 |
|------|---------|
| 前缀长度 + 数据 | Length-prefixed |
| 固定宽度 | Fixed-width fields |
| 0x00 结尾 | Null-terminated strings |
| TLV 结构 (Type-Length-Value) | 可扩展协议 |
| 大端序（高位在前） | 网络字节序 |
| 小端序（低位在前） | x86 原生序 |

### D.4 动态分析辅助

```
JS 场景:
  1. 在 ArrayBuffer / DataView 的构造处设断点
  2. 追踪 setUint32 / setUint16 等调用序列
  3. 还原二进制构造逻辑

Android 场景:
  1. Frida hook ByteBuffer / DataOutputStream
  2. 追踪序列化过程
```

---

## 反模式

- **不要假设 JSON 就是 REST** — 有些协议用 JSON over WebSocket，或 JSON-RPC。先确认传输层。
- **不要忽略请求顺序** — 某些 API 需要先调用初始化接口获取 session，再调用业务接口。
- **不要只分析单次请求** — 对比多次请求才能区分固定字段和动态字段。
- **不要手动解析 Protobuf** — 优先用 `protoc --decode_raw` 或 `blackboxprotobuf`，手工解析容易出错。

---

## 完成标准

```
协议分析结果：
- 目标：$ARGUMENTS
- 协议类型：[REST API | WebSocket | gRPC | Protobuf | 自定义二进制]
- 请求格式：[详细字段说明]
- 签名/加密：[算法 + 密钥来源]
- 认证方式：[Token | Cookie | 签名 | 证书]
- Python 重放脚本：output/api_client.py（已验证）
- 验证结果：请求成功 + 业务数据返回
```

## References

| 文件 | 何时读取 |
|------|---------|
| `references/protobuf-reverse.md` | Protobuf 二进制格式详解和手工还原技巧 |
| `references/websocket-analysis.md` | WebSocket 协议分析模式和常见框架（Socket.io/SignalR） |

