Files
live-hub-py/docs/dfpReport生成流程.md
yml2213 36b5d78050 docs(huya): 记录 dfpReport 零设备生成突破与生成器工具
- 破解进度: 服务端不校验 cw 内容, 随机 4146B cw 即可 200 + 签发新 t2/t5
- 生成流程: 零设备注册链 getDfpConfig->selectOperator->dfpReport 打法
- tools/dfp_gen.py: cw/body 构建器 (TAF 4226B 结构)
- tools/dfp_cli.py: 注册链 CLI
- evidence: cw JSON 段/collection 段抓取样本
2026-08-27 17:57:38 +08:00

4.4 KiB

dfpReport 生成流程与逻辑(逆向推演总账)

目标:讲清楚 dfpReport 上报数据"每一步怎么生成"的完整链路。 已破解部分(黑纸白字)+ 待逆向部分(用 ⚠️ 标出)。

一、dfpReport 是什么

虎牙 huyaudb 风控的"设备行为上报"请求,POST 到 wsapi.huya.com:443 /,用腾讯 taf/wup 协议封装。 请求体(body)= taf 容器,内含若干 tag 字段,其中 tag2 是核心密文区(整个设备+行为报文的加密载荷)。

二、请求体生成的完整流程(逻辑推理)

第 1 步:准备明文 JSON(554B)——【已完全破解】

{"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 点逆向带来现实障碍