- docs/HUYA_APP_OVERVIEW.md: 整体流程/三形态hdid区分/登录入口盘点/随机化矩阵/风险清单/真机Frida现状 - core/huya 各模块 docstring 加风险标记与 hdid 名称混淆提示, 指向总览 - tools/app_login_flow 标注已过时(未接注册链), tools/huya_device_profile 标注与 core 策略关系 - scripts/phone_stable_capture.py + diag_phone_lifecycle.py: 真机 spawn+art_callsite 稳定抓帧/四组诊断 - evidence/diag_phone/: 真机基线/attach/稳定抓帧实验证据 (90s 存活无 EGL 崩)
111 lines
7.8 KiB
Markdown
111 lines
7.8 KiB
Markdown
# 虎牙 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/dfp_register.register_device() │
|
||
│ getDfpConfig → selectOperator → dfpReport(随机cw) │
|
||
│ 返回 (t1, safedeviceid, device_id) ← 全新,非画像旧值 │
|
||
│ 失败 → 抛 DfpRegistrationError → HuyaAppLoginError,终止,不回退 │
|
||
│ │
|
||
│ ② WUP 密码登录 wup_password_login_raw() │
|
||
│ POST wup.huya.com hypasswordLogin(safedeviceid/device_id 用①的)│
|
||
│ ├─ 正常 → 解出 114B cred + 真实 uid │
|
||
│ └─ pt_auth 滑块 → solve_safe_auth() 自动过验 → 重发登录(≤3轮) │
|
||
│ │
|
||
│ ③ 本地铸证:nonce_forge(uid+k1) → cert_forge 铸证书 → envelope_forge │
|
||
│ 补丁 WUP 信封(证书 + UID) │
|
||
│ ④ 模拟扫码绑定四步流 QrRole(getQrId→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_id(40hex)** | `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/huya,Web 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 配套) |
|
||
| 滑块 UA | **固定** 小米 M2102J2SC | `app_login.APP_UA_MOBILE` | ⚠ 与随机机型画像不一致 |
|
||
| session / traceId / 登录行为 JSON | **固定金样本** | `_golden_session_assets()` | ⚠ 多账号相同,异常画像 |
|
||
| QrRole context / reqid / page_id | **随机** | `QrRole`(uuid/random) | 低 |
|
||
|
||
---
|
||
|
||
## 五、风险与未解决项(诚实清单)
|
||
|
||
1. **hdid 固定共享** → 服务端可在设备维度把多个账号关联起来(见 §2 #1)。纯代码无法铸造新 hdid;换掉即 `APP_SIGN_NOT_MATCH`。
|
||
2. **滑块 UA / session / traceId 固定** → 与随机机型画像不自洽,长期易形成异常画像。
|
||
3. **qr_auth / dx_auth 无自动闭环** → 碰上直接失败(`QR_AUTH_REQUIRED`)。
|
||
4. **无稳定性数据** → 没有 20/50/100 次连续成功率、多账号/IP/时段矩阵。
|
||
5. **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 会标记)。
|