diff --git a/docs/HUYA_WEB_FIELD_TRACE.md b/docs/HUYA_WEB_FIELD_TRACE.md new file mode 100644 index 0000000..5b5cf07 --- /dev/null +++ b/docs/HUYA_WEB_FIELD_TRACE.md @@ -0,0 +1,88 @@ +# 虎牙网页设备字段溯源(2026-09-01 浏览器实测实证) + +## 一、来源判定方法(有头 Chrome + 打点探针) + +- `Page.addScriptToEvaluateOnNewDocument` 拦截 `Document.prototype.cookie` setter, + 记录每条写入的 值/时间/调用栈(栈中含脚本 URL + 行号)。 +- `Network.responseReceivedExtraInfo` 捕获服务端 **Set-Cookie** 头。 +- 全新 profile,导航 www.huya.com + 直播间页,静置后导出。 + +## 二、决定性结论:哪些字段服务端下发,哪些浏览器生成 + +### ✅ 服务端 Set-Cookie 下发(仅 5 个) +| 字段 | 实测 | +| --- | --- | +| `PHPSESSID` | l.web.huya.com / l.huya.com | +| `udb_deviceid` | udblgn.huya.com(`w_` + 19 位数字,匿名设备) | +| `sdid` | udblgn.huya.com(`0UnHUgv0_qmfD4KA...` 设备指纹) | +| `v` | 页面版本 | +| `HMACCOUNT` | 百度统计 | + +### ✅ 浏览器脚本 document.cookie 写入(铁证:调用栈) +| 字段 | 生成脚本 | 关键位置 | +| --- | --- | --- | +| `guid` | `a.msstatic.com/huya/main3/npm..pnpm-d84ecac2_850fe68b.js` `Object.setCookie` | 写入 5 次;**位置 12-16 固定 `966a`(跨会话一致)** | +| `_qimei_fingerprint` | `staticfile.qq.com/qimei/qimeisdk-web/0.6.3/index.js` | 写入 1 次 | +| `udb_passdata` | `a.msstatic.com/huya/main3/common/headerfunction_d8b3ad0c.js` `writeCookie` | 固定值 3 | +| `__yasmid` / `__yamid_tt1` | 页面脚本 | 同值 17 位小数 | + +### ⚠️ 浏览器生成但**非 document.cookie 写入**(走 Cookie Store API / localStorage 同步等) +| 字段 | 证据 | 说明 | +| --- | --- | --- | +| `__yamid_new` | 88 条写入中无此 key,但最终 cookie 有值 | **CBCC 前缀 + 递增种子**(见下) | +| `game_did` | 同上 | 30-35 位字母数字 | +| `_qimei_uuid42` | 同上 | `1a` 前缀 + 32hex UUID 结构 + 10hex | + +## 三、设备字段结构规律(真实样本) + +### guid = `0a` + 10hex + `956a`/`966a` + 16hex —— 有固定段,非纯随机 +``` +0a7dfa5fc9ee966aab02a2eaa3ea1de1 ← live 窗口 +0a7dfaa2d7af966a2101f370f470ce50 ← round2 fresh +0a7de265986f956a24015b505c504506 ← reqable 8.31 +0a89d5f6614b956aa6020bbc0cbc18fe ← cahrles 8.31 +``` +位置 12-16 恒为 `956a` / `966a`(产品段?),8.31 为 `956a`、我们机器为 `966a` —— +可能与 SDK/页面版本有关。 + +### __yamid_new = `CBCC`/`CBCB` + 种子6hex + 计数4hex + `0001` + 随机12hex +``` +CBCC 6479D9 B000 0001 52EC19001D2017B2 ← live 窗口 +CBCC 551C11 E000 0001 783D8F5530901BCC ← round2 fresh +CBCC 06ECB5 0000 0001 B63016D6162BC990 ← reqable 8.31 +``` +- 前缀 `CBCC`/`CBCB` 恒定(产品标识) +- 种子段递增且与 `_yasids`(rootsid)**同源共享时钟**: + `yamid=CBCC6479D9B0...` ↔ `rootsid=CBCC647A8A20...`(同会话,种子差 0xB1≈177) +- `0001` 固定,尾部大段随机 + +### _qimei_uuid42 = `1a` + 40hex(32hex UUID 结构 + 10hex 附加) +``` +1a81f140c08100b89fb1be450f640501568684b2ea ← reqable 8.31 +1a901123a1f10045427c1c73420287f44f49d11b45 ← round2 fresh +1a901171b051007527940c2acef15dcd2342b6ff ← live 窗口 +``` +首字节 `1a` 恒定;前 32 hex 符合 RFC 4122 UUID 布局(8-4-4-4-12)。 + +### _qimei_fingerprint = SpookyHashV2(canvas指纹, 31) 32hex +qimeisdk-web 0.6.3 源码已定位: +- 画 "qimei" 文本(Times New Roman 11pt)+ `#f60` 背景 + 透明度矩形 +- 三圆叠加(`#f2f`/`#2ff`/`#ff2` 40 半径)+ 环形 `#f9c` evenodd +- `canvas.toDataURL()` → **SpookyHashV2**(r 函数,64 位,seed=31)→ 32hex + +## 四、溯源结论与建议 + +| 字段 | 来源 | 风控关联性 | 建议 | +| --- | --- | --- | --- | +| `guid` | 浏览器脚本(有固定段 `0a..966a`)| 高(设备与会话绑定) | **必须按结构仿造或复用 wsLaunch 会话值**;随机纯 hex 与真实结构不符 | +| `__yamid_new` | 浏览器脚本(CBCC 前缀+种子)| 高(与 rootsid 同源)| 需要前缀 `CBCC` + 种子同步生成逻辑 | +| `_qimei_uuid42` | QIMEI SDK 0.6.3(`1a` 前缀)| 中 | 前缀 `1a` + UUID 布局 | +| `_qimei_fingerprint` | QIMEI SDK 0.6.3 SpookyHashV2 | 中 | **算法已完全逆向**(源码在手),可精确复现 | +| `game_did` | 浏览器脚本 | 中 | 长度需对齐(35 变体含 `-`)| +| 统计字段(SoundValue 等)| 页面脚本 | 低 | 随机 OK | + +**下一步选项**: +1. `_qimei_fingerprint` 直接用 SpookyHashV2 实现(canvas 指纹用标准值替代) +2. `guid` 采样更多样本确认固定段后按 `0a` + 结构仿造 +3. `__yamid_new` 需找到生成它的具体脚本(非 document.cookie 写入,可能在 + ubtk/埋点脚本里)做种子同步 \ No newline at end of file