# dfpReport 生成流程与逻辑(逆向推演总账) > 目标:讲清楚 dfpReport 上报数据"每一步怎么生成"的完整链路。 > 已破解部分(黑纸白字)+ 待逆向部分(用 ⚠️ 标出)。 ## 一、dfpReport 是什么 虎牙 huyaudb 风控的"设备行为上报"请求,POST 到 `wsapi.huya.com:443 /`,用腾讯 **taf/wup** 协议封装。 请求体(body)= taf 容器,内含若干 tag 字段,其中 **tag2 是核心密文区**(整个设备+行为报文的加密载荷)。 ## 二、请求体生成的完整流程(逻辑推理) ### 第 1 步:准备明文 JSON(554B)——【已完全破解】 ```json {"appId":"5008","appVer":"13.4.22","appkey":"865a...cbb0e3", "channel":"xiaomi","deviceId":"02df...9389","deviceName":"M2102J2SC", "hdid":"7c5387...85ee","heightPixels":"2120", "systemVer":"M2102J2SC,30,11","widthPixels":"1080", ...} ``` 来源: - `appId/appVer/sdkVer/channel` = App 编译期/运行期常量 - `deviceName/systemVer` = Android build props - `widthPixels/heightPixels` = 屏幕分辨率(运行期查询) - **`hdid` / `deviceId` / `appkey` = ⚠️ 设备三元组,这是核心待逆向项**(见第三节) ### 第 2 步:准备 collection ↓ 数据集(大 JSON,每轮变化)——【部分破解,算法待逆向】 一个 ~3400B 的大 JSON,含动态行为数据: - `touch_events`(触摸事件时间/坐标) - `net_intfs`(网络接口状态) - `phoneInfo`(设备/系统信息汇总) - `qimei16/36`(⚠️ 设备指纹 App 的标识,逆向目标) - `risk_apps`(已安装的风险 App,如 magisk) - `scanned_appname`(⚠️ ~2900B 二进制扫描结果) - **`Poseidon_*` 反 frida 检测字段**(读 /proc/self/maps 等检测 hook) ⚠️ **collection 的构建逻辑(App 怎么采这些数据、怎么格式化)是"生成流程"里最大的一块未破解**,但注意:验证已证明 collection **不参与服务端设备身份匹配**(改它只影响"动态/静态"判定,不动 hdid)。 ### 第 3 步:组合成明文平文本(pa)——【已知结构,精确边界待确认】 ``` 明文输入 ≈ JSON(554B) + collection(3420B) [顺序/分隔待最终确认] ``` ### 第 4 步:XOR 加密(逐字节 keystream)——【算法已破解,种子待逆】 - `tag2 = [魔数 10B 57 18 82 cf 66 4b b3 94 01 ee] + [XOR密文]` - keystream 逐字节 XOR 明文 → 密文 - **魔数恒定**(明文头 XOR 固定值) - **keystream 每会话动态** → ⚠️ 种子(时间戳/会话随机+密钥)+ 生成函数待逆向 ### 第 5 步:封装 taf/wup + 加密通信 body 各 tag 打包(taf 编码)→ `POST wsapi.huya.com:443 /`(TLS),`Content-Type: application/octet-stream`,`i-ver: 1`,`User-Agent: okhttp/3.14.9`。 ### 第 6 步:服务端校验(已通过差分实验定论) - 服务端解密 tag2 → 解析明文 JSON 三元组(hdid/deviceId/appkey)+ collection - **三元组在设备库 + collection 完整** → 回显设备 hdid(actionV) - 否则 → 动态随机 token(拒绝) ## 三、核心待逆向项(按"生成流程"重要性排序) ### 3.1 设备三元组(hdid/deviceId/appkey)怎么来【最关键】 已知: - 是真设备派生(`pm clear` 不变,跨会话稳定) - 长度 40hex(hdid/deviceId)、32hex(appkey),像 hash 输出 - libhydeviceid.so 内有 MD5 实现(ror#7 @0xc37c0)+ SHA1 + hex 表 ⚠️ 待逆向: - 从哪些硬件/系统信息(AndroidID/IMEI/build/serial?)派生 - 用哪个 hash(MD5/SHA1/自实现) - 掺什么盐/固定密钥 ### 3.2 collection 的完整构建逻辑 - 哪些数据源、如何采集、如何序列化、顺序 ### 3.3 keystream 的种子与生成函数 - 种子来源(时间戳?线程随机?会话 ID?) - 生成器(自实现伪随机?流密码?) ## 四、验证里"能做什么"的现实 已确认(纯 Python 可做): - `forge_replay.py`:任意帧真实 wire → XOR 差分改明文三元组 → 重放,HTTP 200(服务端接受,只是认不认设备问题) - 捕获比:任何一帧真实 ks 即可加密任意伪造明文(不需要生成器) ## 五、逆向"生成流程"的推荐路径(hook 而非纯静态) 由于 libhydeviceid.so 是 OLLVM 混淆,纯静态难。推荐用 frida 在**生成点 hook**,抓真实输入输出: 1. **hook 三元组派生**:hook MD5(0xc37c0 附近)/ hex 表使用处,抓 hash 输入 → 反推三元组 2. **hook 加密函数入口**:抓 keystream 生成函数输入(种子) 3. **hook collection 构建函数**:抓各字段组装点 但 attach/spawn 反调试都强(已验证 attach 6/6 死,spawn 3-6s 死),给 hook 点逆向带来现实障碍