Files
live-hub-py/docs/HUYA_APP_OVERVIEW.md

119 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- ⚠️ 命名规范强制约束:本档中所有设备标识必须带前缀。规范见 docs/HUYA_ID_NOMENCLATURE.md。
GUID32=doLaunch sGuid(32hex, launch体系) | HDID32=登录帧t1.t0设备证书(32hex) |
DEVID40=注册链t5/t2.t8 device_id(40hex) | MID16=mid(16hex) | ACTION=注册链t2授权令牌。
旧段落中裸词按上下文语义理解:登录相关=HDID32launch/铸币=GUID3240hex=DEVID40。 -->
# 虎牙 App 协议链 总览(去困惑地图)
> 目的:一张图讲清“整体流程 / 几个 hdid 区分 / 几个登录入口 / 哪里随机 / 哪里有风险”,
> 避免在代码和多个零散文档里来回翻。**先看本文,再按需深入具体文档。**
>
> 关联文档:`docs/dfpReport破解进度.md`(破解细节)、`docs/dfpReport生成流程.md`(零设备注册链)、
> `docs/模拟器存活闪退诊断报告.md`(Frida 存活实验,模拟器)、`docs/虎牙纯Python全自动登录-总结与交接.md`。
---
## 一、生产登录整体流程(唯一推荐的入口)
入口:`core/huya/app_login.py``login_huya_app_password()` / `HuyaAppPasswordLogin`
Web UI 通过 `web/backend/routers/huya.py` 调用它。
```
┌──────────────────────────────────────────────────────────────────────┐
│ 每次 WUP 登录前 │
│ ① 读取/创建账号设备画像 core/huya/device_profile.get_profile() │
│ 同一账号复用 vendor/model/screen/width/height/fingerprint/guid32 │
│ │
│ ② 新设备注册链 core/huya/dfp_register.register_device() │
│ getDfpConfig → selectOperator → dfpReport(随机cw) │
│ 三步请求的设备字段均来自①,返回 (t1, safedeviceid, device_id) │
│ 返回字段为本次登录专用的新令牌,非画像旧值 │
│ 失败 → 抛 DfpRegistrationError → HuyaAppLoginError,终止,不回退 │
│ │
│ ③ WUP 密码登录 wup_password_login_raw() │
│ POST wup.huya.com hypasswordLoginsafedeviceid/device_id 用①的)│
│ ├─ 正常 → 解出 114B cred + 真实 uid │
│ └─ pt_auth 滑块 → solve_safe_auth() 自动过验 → 重发登录(≤3轮) │
│ │
│ ④ 本地铸证:nonce_forge(uid+k1) → cert_forge 铸证书 → envelope_forge │
│ 补丁 WUP 信封(证书 + UID) │
│ ⑤ 模拟扫码绑定四步流 QrRolegetQrId→scan→bind→tryQrLogin)→ biztoken│
│ ⑥ POST /web/cookie/verify 兑换 → 全套网页 Cookie │
└──────────────────────────────────────────────────────────────────────┘
```
**结论**:这是“绕开 App UI、复现协议”的纯协议链。它绕过了滑块(pt_auth),
**qr_auth(扫码)/ dx_auth(短信)没有自动闭环**——碰上直接失败,属已知边界。
---
## 二、几个 “hdid” 的区分(最容易混的点)
代码里出现三种都叫“hdid”的东西,**不是同一个**:
| # | 形态 | 示例 | 所在 | 是否登录硬锚 | 能否随机 |
|---|---|---|---|---|---|
| 1 | **WUP 登录帧 t1.t0 的 32hex hdid** | `ed0db8334cadd236c00cadf7e11ab5a5` | `core/huya/wup_encoder.py``hdid` 参数);`device_profile.HDID` | ✅ **服务端硬锚**`libhydeviceid.so` native 生成上报,不走 HTTP | ❌ 换掉 → `APP_SIGN_NOT_MATCH` |
| 2 | **dfpReport 响应 t5 / device_id40hex** | `7c5387e0539c023c31c4ff0e807e7256117385ee` | 注册链 `dfp_register`;登录帧 `device_id` | ❌ 与 #1 非同一体系(`device_fingerprint.py` 有明示) | ✅ 随机 cw 时服务端签发随机值 |
| 3 | **注册链随机 cw 里的 “hdid”(64hex sha256** | — | `dfp_register._random_triple` / `tools/dfp_gen.py` | ❌ 仅凑 JSON 模板形态,服务端不校验 cw 内容 | ✅ 每次随机 |
**一句话**#1 是真身份、不可换、全项目唯一;#2 是登录帧 `device_id` 的签发源,动态;
#3 是诊断占位。混淆来源主要是 dfpReport JSON 明文里把 40hex 设备 ID 也叫 `hdid`。
---
## 三、登录入口盘点(哪个该用、哪些是历史)
### 生产链(core/huyaWeb UI 调用)
| 入口 | 功能 | 状态 |
|---|---|---|
| `core/huya/app_login.py``login_huya_app_password` | **App 协议全链路**(①~⑤) | ✅ **推荐**,已接注册链 |
| `core/huya/login.py``login_huya_password` | Web 密码登录 | ✅ 独立 Web 渠道 |
| `core/huya/sms_login.py``login_huya_sms` | 短信登录 | ✅ |
| `core/huya/auto_register.py` | 手机号自动注册 | ✅ |
| `web/backend/routers/huya.py` | Web UI 接口(单账号/批量) | ✅ |
### 工具 / 历史(tools,试验用,与生产分离,勿在生产调用)
| 文件 | 用途 | 注意 |
|---|---|---|
| `tools/huya_device_register.py` | 注册链 CLI`--gen` 零设备 / `--login` | 与 `core/huya/dfp_register` 同逻辑的工具侧版 |
| `tools/app_login_flow.py` | 旧 App 登录流 | ⚠ 仍读画像 `safedeviceid` 回退金样本,**未接注册链,已过时** |
| `tools/huya_wup_encoder.py` | 旧 WUP 编码器副本 | 正式版在 `core/huya/wup_encoder.py` |
| `tools/full_auto_safe.py` / `full_auto_test.py` / `full_web_cookie.py` | 一键试验脚本 | 依赖 `evidence/` 信封/证书模板,非生产 |
| `tools/web_cookie_login.py` | 网页版密码登录 | Web 渠道独立 |
| `tools/huya_device_profile.py` | 旧画像生成器 | ⚠ 仍含固定 `safedeviceid`,与 core 策略(动态签发)不一致 |
---
## 四、随机化矩阵(哪里随机 / 固定 / 动态签发)
| 字段 | 状态 | 来源 | 风险 |
|---|---|---|---|
| **hdid (32hex)** | **固定**(全账号同一) | `device_profile.HDID` 金样本 | ⚠ 多账号设备维度关联(主要风险) |
| safedeviceid (t2) | **动态签发**(每次登录前) | 注册链 `dfp_register` | 低 |
| device_id (t5) | **动态签发**(随机 cw 时为随机值) | 注册链 `dfp_register` | 低 |
| fingerprint | **随机**(每账号) | `generate_profile` sha1 | 低 |
| 机型 / 屏幕 / 宽高 | **随机**(每账号从 `REAL_MODELS` 选) | `generate_profile` | 低 |
| app_version / sdk_version | **固定** | 常量 `13.4.22` / `1.0.80138` | 低(需与 hdid 配套) |
| 滑块/扫码 WebView UA | **按画像派生** | `device_profile.mobile_user_agent()` | 与机型/厂商/系统版本一致 |
| session / traceId / 登录行为 JSON | **每次请求动态** | `wup_encoder.make_*` + `_golden_session_assets()` | 仅协议字段固定结构 |
| QrRole context / reqid / page_id | **随机** | `QrRole`uuid/random | 低 |
---
## 五、风险与未解决项(诚实清单)
1. **hdid 固定共享** → 服务端可在设备维度把多个账号关联起来(见 §2 #1)。纯代码无法铸造新 hdid;换掉即 `APP_SIGN_NOT_MATCH`
2. **qr_auth / dx_auth 无自动闭环** → 碰上直接失败(`QR_AUTH_REQUIRED`)。
3. **无稳定性数据** → 没有 20/50/100 次连续成功率、多账号/IP/时段矩阵。
4. **Frida attach 主进程必被 msaoaidsec 杀**(真机/模拟器均实测)→ 见 §六。
---
## 六、真机 Frida 现状(2026-08-27 实测)
- **裸 attach 主进程**:真机同样被 `libmsaoaidsec.so` 静默 `_exit`KeepAlive 换 pid,UI 几乎无感)。模拟器版详见诊断报告。
- **真机稳定注入通道(已打通)**`spawn` 挂起中加载 `bypass_msaoaid_maps_art_callsite.js`RE 库)再 `resume`**长时存活 + 可 hook**90s 无 detached,抓到 `libudbauthunify.so` 基址)。真机 GPU 正常,**不再触发模拟器的 EGL 崩溃**。
- 脚本:`scripts/phone_stable_capture.py`(真机稳定抓帧)、`scripts/diag_phone_lifecycle.py`(真机四组对照诊断)。
- 含义:真机上做长时 Frida 抓帧/取证是可行的(不再受模拟器 ~4s stale 窗口限制);但**登录/验证码流程仍不要带 frida**msaoaidsec 会标记)。