diff --git a/docs/HUYA_HDID_ALGORITHM_GEN.md b/docs/HUYA_HDID_ALGORITHM_GEN.md index b96be62..07dba3d 100644 --- a/docs/HUYA_HDID_ALGORITHM_GEN.md +++ b/docs/HUYA_HDID_ALGORITHM_GEN.md @@ -1630,3 +1630,8 @@ APK 内嵌: appkey 865a..c798 (datadiv 加密 .data) ──运行时解密── - 登录链 (已破): uid+getkey → xxtea/AES-OTP (§11.44); appSign=md5("5008_ver_k1") (R15) - 会话链: Perseus SecureRandom 16字符 → RSA 信封 (R34) — 独立通道, 与 dfpReport 无关 - **端到端伪造 = 纯离线**: JSON 构造 + tools/dfp_rc4.py (key 为常量), 无需设备! + +## §11.68 终态索引 (2026-08-29) +全流程定案总结移至 `docs/登录系统全流程定案.md`: 三库架构 / 常量总账 / 登录链 / dfpReport 链 / +纯协议无卡点结论 + 一号一设备方案。核心: dfpReport RC4 key = APK 内嵌常量 (datadiv@3912240), +纯协议登录链 (dfp_register → app_login) 已无设备依赖。 diff --git a/docs/登录系统全流程定案.md b/docs/登录系统全流程定案.md new file mode 100644 index 0000000..ef01c5d --- /dev/null +++ b/docs/登录系统全流程定案.md @@ -0,0 +1,114 @@ +# 虎牙登录系统全流程定案(R35-R39 终态) + +> 日期: 2026-08-29 · 状态: 纯协议账号密码登录无卡点, 一号一设备成立 +> 本文是全链路终态总结; 算法细节见 `HUYA_HDID_ALGORITHM_GEN.md` §11.44-45 / §11.66-67。 + +## 一、总体架构: 三个库, 三条链 + +``` + com.duowan.kiwi (13.4.22) + │ + ┌─────────────────────┼──────────────────────┐ + ▼ ▼ ▼ +libudbauthunify.so libhydeviceid.so libturingmfa/ga.so + 账号登录(UDB) ★核心枢纽★ 腾讯turing SDK + md5/AES/xxtea/OTP ├─ hdid 生成 (XXTEA 属 hdid 子系统, + 账号级凭据 ├─ turing SDK 静态链接 与 dfpReport 无关) + └─ dfpReport 加密(RC4) +``` + +`libhydeviceid.so` 是枢纽 — "45 个钩子零调用"之谜的答案: turing SDK 整个被静态 +链接进该库, dfpReport 加密走库自身路径; `libz.deflate` 是它的必经外部导出 +(R36 以此为锚点定位)。 + +## 二、密钥/身份常量总账 (全部实锤) + +| 常量 | 值 | 存放位置 | 用途 | +|---|---|---|---| +| dfpReport RC4 key | `865a4924a40897ac1fcfe6b4c2abc798` | libhydeviceid .data (datadiv 加密) 字符串表 @3912240, 紧邻 "dfpReport" | 报文流加密。**APK 内嵌常量, 与设备无关** (R39) | +| k1 | `865a4924a40897ac1fcfe6b4c2cbb0e3` | BusinessCfg+0x10 (同在 datadiv) | appSign 派生 + 登录 AESkey 派生 | +| channelKey | `865a4924a40897ac1fcfe6b4c2cbb045` | resinfo (AES-ECB, key=`HuyaUdb1928374650qwertyuiop` 前16B), 服务端下发 | t1 设备指纹 | +| appSign | `ed0db8334cadd236c00cadf7e11ab5a5` | 运行时算出 | = MD5("5008_13.4.22_" + k1), 跨账号稳定 (R15) | +| hdid | 40hex (`7c5387e0...85ee`) | 设备派生 | getHDID / 登录身份 | +| getkey 表 | (1,2)=`MKDKeridjing7avnsasdSDHI`, (1,3)=`nskdI7MDGKSDJsnadjdoonvs` | libudbauthunify .data | AESkeyMgr 按 (1,cnt) 取盐 | +| xxtea key | 账号 UID (如 `1199666914671`) | 登录时填入 | UDB OTP 内层加密 | +| Perseus 会话密钥 | 16字符 `[A-Za-z0-9]`, SecureRandom | 内存 (RSA 信封上行) | 独立通道, 与 dfpReport 无关 (R34) | + +## 三、登录链 (UDB, 账号密码 → cred) + +1. **WUP 封装**: 登录请求走 taf/wup POST `wsapi.huya.com`; `createWupRequestData@0x38dab0` 构造, t1.t0 = appSign +2. **OTP 生成** (全链语义 100% 定案 §11.44): `getOtp(uid, 2, 2, "5008", k1, cred, cnt, nonce)`, + 明文 = `02 0c00 [12B xxtea(uid)] 7200 [114B cred]`, **AESkey = md5_char16(k1 + getkey(1,cnt))**, AES-ECB +3. **cred 凭据**: 账号级, 每次登录轮换; `cred0`/`credAnonymous` 落盘 (加密) +4. **会话密钥链**: `Perseus.a()` SecureRandom 16字符 → RSA 公钥封装 → guava{seq, env, KEY, d, expire} 上行 + +## 四、dfpReport 链 (风控上报, R35-R37 完全攻破) + +``` +采集指纹 JSON (~7-8KB: Athena + deviceinfo/Hebe_D1-D5 + guid + signature + terminal + version) + → gzip (level 9, 头 1f8b08 00 00000000 02 03) + → RC4(865a...c798) keystream 逐字节 XOR ← 密钥是 APK 常量! + → wire body = [10B "magic"(=keystream⊕gzip头, 非真魔数)] + [密文] (+尾部10B) + → taf/wup → POST wsapi.huya.com /dfpReport +``` + +- 触发配方: 清 `app_turingdfp/app_turingfd` + `resinfo*` (保留登录) → spawn → ~40s 自动重注册上报 +- 服务端判定 (差分实验定论): 三元组在设备库 + collection 完整 → 回显 hdid; 否则动态随机 token +- collection (行为数据) 不影响设备身份判定, 只影响动态/静态分级 +- 历史验证: 12/12 历史密文解密 + 3 轮伪造密文逐字节一致 (`tools/dfp_rc4.py` selftest) + +## 五、纯协议登录现状 (无卡点定案) + +生产链已存在且跑通: + +``` +core/huya/dfp_register.py 每次登录前: getDfpConfig → selectOperator → dfpReport(零设备伪造) + → 服务端签发 safedeviceid(t2) + device_id(t5, 40hex) +core/huya/app_login.py WUP hypasswordLogin (账号密码, t2/t5 填入登录帧) + → 正常: 直出新鲜 cred(114B) + → 风控: safe_auth 滑块自动过验 (pt_auth JS 逆向闭环) → 重发直出 +``` + +### R35-R39 带来的两个实质升级 + +1. **旧链隐形枷锁解除**: 旧伪造方式 = "一帧真实 wire 的 keystream 做 XOR 差分改明文", + 受限于捕获帧 3625B 长度且共用捕获 keystream。现在密钥是 APK 常量, gzip+RC4 离线无限 + 生成, 伪造报文与真机**密码学不可区分** (同 app 版本真机每轮 keystream 也相同 — + "magic" 恒定的原因)。 +2. **伪造质量升级**: R36 解出的 12 份真实指纹 JSON (Athena/Hebe/guid/signature/terminal/ + version 完整结构) 即标准模板, 可构造字段级真实 collection。 + +### 一号一设备方案 + +- 每账号一套设备画像 (hdid 40hex, guid, Hebe_D1-D5, CDID) → 跑一次注册链 → + 服务端签发该"设备"的 safedeviceid/device_id → 登录绑定 +- 同一账号后续 dfpReport 保持同一套画像值 (自洽); 不同账号画像互不相同 +- 滑块风控已有自动过验兜底 + +### 留意点 (非卡点) + +登录帧 t1.t0 的 32hex hdid 是"服务端硬锚" (libhydeviceid 设备 ID 体系), 注册链目前 +用随机占位 — 实测服务端照常签发; 若风控升级开始校验 t1.t0, 需补 hdid 真实派生算法 +(仓库最初主课题)。 + +## 六、离线复原能力清单 + +**✅ 纯离线可做 (无设备)**: dfpReport 全伪造 (`tools/dfp_rc4.py`) · appSign 计算 · +resinfo 加解密 · OTP 引擎 (V2 模型) · WUP 编解码 (`huya_wup_encoder.py`/`taf_decode.py`) · +历史密文批量解密 (12/12) + +**⚠️ 仍需真机**: 绕过配方 (唯一实测稳定 = RE 仓库三脚本两阶段流程; 合并版 bypass_all.js +未通过三层健康检查已弃用, 见 `Frida绕过配方.md`) · collection 完整采集逻辑 (Poseidon +反检测字段) · 换版本时 datadiv 常量重提取 (unidbg hydev harness 可离线做) + +## 七、工具索引 + +| 工具 | 说明 | +|---|---| +| `tools/dfp_rc4.py` | dfpReport 编解码器 (rc4_keystream/decrypt/encrypt/gzip_wrap + CLI) | +| `scripts/bypass_healthcheck.py` | 三层判定: pid 稳定 / 界面轨迹 / 崩溃 ANR + 主线程冻结探针 | +| `scripts/hook_*.py` | 各钩子 runner; `hook_final_capture.py` 的两阶段时序为模板 | +| `tools/frida/hook_deflate.js` | libz deflate 锚点钩 (只挂 libz.so; GL 驱动同名符号禁挂) | +| `tools/frida/hook_hy.js` | RC4 key 捕获 (libhydeviceid!0x60e6c x1) | +| `evidence/dfp_live/dec_*.json` | 12 份真实指纹明文 (伪造模板) | +| `tools/unidbg/hydev/` | libhydeviceid 离线 harness (datadiv 解密) |