docs/code(huya): 设备标识符命名规范落地 - 全库HDID32/GUID32/DEVID40前缀化去混
- docs/HUYA_ID_NOMENCLATURE.md: 规范总表 + 三条强制规则 + 代码变量对应 - 4 篇主文档头部去混声明 + §11.x 被证伪假设行标注更正 - 代码: GOLDEN_HDID→GOLDEN_HDID32, device_profile.HDID→HDID32, wup_encoder/app_login 注释前缀化 - 后续所有表述必须以 GUID32(doLaunch) / HDID32(登录t1.t0) / DEVID40(t5) 前缀书写
This commit is contained in:
@@ -77,7 +77,7 @@ DEFAULT_GOLDEN_DEV = {
|
|||||||
"width": "1080",
|
"width": "1080",
|
||||||
"height": "2120",
|
"height": "2120",
|
||||||
"device_id": "7c5387e0539c023c31c4ff0e807e7256117385ee",
|
"device_id": "7c5387e0539c023c31c4ff0e807e7256117385ee",
|
||||||
"hdid": "ed0db8334cadd236c00cadf7e11ab5a5",
|
"hdid": "ed0db8334cadd236c00cadf7e11ab5a5", # HDID32 登录t1.t0 (勿与GUID32混)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ REAL_MODELS = [
|
|||||||
("gionee", "GN9013", "GN9013,29,10", (720, 1560)),
|
("gionee", "GN9013", "GN9013,29,10", (720, 1560)),
|
||||||
]
|
]
|
||||||
|
|
||||||
HDID = "ed0db8334cadd236c00cadf7e11ab5a5"
|
HDID32 = "ed0db8334cadd236c00cadf7e11ab5a5" # 登录帧t1.t0 设备证书 (与 GUID32/doLaunch 无关系)
|
||||||
APP_VERSION = "13.4.22"
|
APP_VERSION = "13.4.22"
|
||||||
SDK_VERSION = "1.0.80138"
|
SDK_VERSION = "1.0.80138"
|
||||||
|
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ def _build_wup_data(w: _Writer, uid_str: str, sha1_password: str,
|
|||||||
# -- t1: 设备信息 struct --
|
# -- t1: 设备信息 struct --
|
||||||
di = device_info
|
di = device_info
|
||||||
w.struct_begin(1)
|
w.struct_begin(1)
|
||||||
w.string(0, hdid) # t1.t0 = 32hex 设备ID (libhydeviceid.so 硬锚, 不可随机/换, 换→APP_SIGN_NOT_MATCH)
|
w.string(0, hdid) # t1.t0 = HDID32 (登录帧32hex设备证书, libhydeviceid.so 硬锚, 换→APP_SIGN_NOT_MATCH)
|
||||||
w.string(1, di.get("app_version", "13.4.22"))
|
w.string(1, di.get("app_version", "13.4.22"))
|
||||||
w.string(2, di.get("sdk_version", "1.0.80138"))
|
w.string(2, di.get("sdk_version", "1.0.80138"))
|
||||||
w.string(3, "")
|
w.string(3, "")
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
<!-- ⚠️ 命名规范强制约束:本档中所有设备标识必须带前缀。规范见 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授权令牌。
|
||||||
|
旧段落中裸词按上下文语义理解:登录相关=HDID32,launch/铸币=GUID32,40hex=DEVID40。 -->
|
||||||
|
|
||||||
# 虎牙 App 协议链 总览(去困惑地图)
|
# 虎牙 App 协议链 总览(去困惑地图)
|
||||||
|
|
||||||
> 目的:一张图讲清“整体流程 / 几个 hdid 区分 / 几个登录入口 / 哪里随机 / 哪里有风险”,
|
> 目的:一张图讲清“整体流程 / 几个 hdid 区分 / 几个登录入口 / 哪里随机 / 哪里有风险”,
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
|
<!-- ⚠️ 命名规范强制约束:本档中所有设备标识必须带前缀。规范见 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授权令牌。
|
||||||
|
旧段落中裸词按上下文语义理解:登录相关=HDID32,launch/铸币=GUID32,40hex=DEVID40。 -->
|
||||||
|
|
||||||
# 虎牙 32hex hdid 算法生成路径分析(不用采集,纯算法铸币)
|
# 虎牙 32hex hdid 算法生成路径分析(不用采集,纯算法铸币)
|
||||||
|
|
||||||
> 前置结论(见 `HUYA_HDID_RESEARCH.md`):32hex hdid(WUP 登录帧 field1.tag0)=
|
> 前置结论(见 `HUYA_HDID_RESEARCH.md`):32hex hdid(WUP 登录帧 field1.tag0)= hdid(WUP 登录帧 field1.tag0)=
|
||||||
> `com.huya.security.hydeviceid.NativeEntry.getGUID()`;真机 M2102J2SC 金值
|
> `com.huya.security.hydeviceid.NativeEntry.getGUID()`;真机 M2102J2SC 金值
|
||||||
> `0a7dfaa882938a6ab502511452142c57`;getGUID 是 getter,值在 `init()`(偏移 0x20e6e4)
|
> `0a7dfaa882938a6ab502511452142c57`;getGUID 是 getter,值在 `init()`(偏移 0x20e6e4)
|
||||||
> 时由 `libhydeviceid.so`(OLLVM 混淆 + datadiv 壳)算出并缓存。
|
> 时由 `libhydeviceid.so`(OLLVM 混淆 + datadiv 壳)算出并缓存。
|
||||||
@@ -268,7 +273,7 @@ lib 内置大量模拟器检测串(qemu_pipe / mumuvmm / genymotion / windroye
|
|||||||
- **结论修正(推翻 §9.3"GUID=f(androidId密, config, MID)")**:铸币本体不是本地算法,而是
|
- **结论修正(推翻 §9.3"GUID=f(androidId密, config, MID)")**:铸币本体不是本地算法,而是
|
||||||
**服务端 doLaunch/device_register 按设备指纹签发 sGuid**。doLaunch 请求携带
|
**服务端 doLaunch/device_register 按设备指纹签发 sGuid**。doLaunch 请求携带
|
||||||
`LiveUserbase{tUAEx.sDeviceId(Config 持久化), sIMEI, sMId} + tId(userId.sGuid=当前guid, lUid)}`;
|
`LiveUserbase{tUAEx.sDeviceId(Config 持久化), sIMEI, sMId} + tId(userId.sGuid=当前guid, lUid)}`;
|
||||||
响应 `sGuid` 即后续所有登录帧 tag0 的 32hex hdid。
|
响应 `sGuid` 即后续所有登录帧 tag0 的 32hex hdid。⚠️ 旧假设 —— 已于 §11.10 证伪: GUID32(sGuid) ≠ HDID32(登录帧t1.t0)。
|
||||||
- 与既有认知吻合:旧实验"改 ANDROID_ID/全清数据 GUID 不变"(服务端签发+本地缓存)、
|
- 与既有认知吻合:旧实验"改 ANDROID_ID/全清数据 GUID 不变"(服务端签发+本地缓存)、
|
||||||
`tools/` 注记"hdid 服务端硬锚/不可铸造"。
|
`tools/` 注记"hdid 服务端硬锚/不可铸造"。
|
||||||
|
|
||||||
@@ -372,7 +377,8 @@ lib 内置大量模拟器检测串(qemu_pipe / mumuvmm / genymotion / windroye
|
|||||||
|
|
||||||
**结论:sGuid = f(mid)** —— 服务端对同一 mid 确定性签发同一 sGuid;mid 一换 sGuid 即变。
|
**结论:sGuid = f(mid)** —— 服务端对同一 mid 确定性签发同一 sGuid;mid 一换 sGuid 即变。
|
||||||
mid = LiveUserbase→tUAEx→t5=sMId (16hex),**可任意铸造** → doLaunch 收 sGuid →
|
mid = LiveUserbase→tUAEx→t5=sMId (16hex),**可任意铸造** → doLaunch 收 sGuid →
|
||||||
登录帧 UserId.tag0=32hex hdid 用的就是该 sGuid。§11 旧结论"GUID 唯一不可铸造"正式推翻;
|
§11.10 更正: GUID32(sGuid) 与 HDID32(登录帧t1.t0) 是两套独立 32hex 体系, sGuid 不能作登录 hdid。
|
||||||
|
§11 旧结论"GUID 唯一不可铸造"正式推翻;
|
||||||
**纯算法铸币闭环 = mid(铸) → doLaunch → sGuid → 登录链**。
|
**纯算法铸币闭环 = mid(铸) → doLaunch → sGuid → 登录链**。
|
||||||
|
|
||||||
### 工具落地
|
### 工具落地
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# 虎牙设备标识符命名规范 (ID NOMENCLATURE)
|
||||||
|
|
||||||
|
> 强制约定:**所有文档、代码注释、变量名、日志,凡是提到设备标识,必须带前缀**
|
||||||
|
> (下列表格中的「规范名」)。禁止裸写 "hdid"/"GUID"/"device_id" 等无前缀词 ——
|
||||||
|
> 历史教训:这些词在不同体系下含义完全不同,已造成多次混淆(见 §11.11 去混记录)。
|
||||||
|
|
||||||
|
## 规范名总表
|
||||||
|
|
||||||
|
| 规范名 | 长度 | 含义 | 出现位置 | 签发方 | 可铸性 |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| **GUID32** | 32hex | doLaunch 响应的 sGuid(launch 体系) | 登录外的启动注册;HySignalGUIDCache.xml | 服务端(按 MID16 确定性签发) | ✅ 已打通(铸币机) |
|
||||||
|
| **HDID32** | 32hex | 登录帧 t1.t0 的 设备证书(登录体系) | WUP 登录请求 t1.t0;native 内存 | native 私钥(libhydeviceid) | ❌ 纯 Python 不可铸 |
|
||||||
|
| **DEVID40** | 40hex | 登录帧 t2.t8 / 注册链 t5 的 device_id | WUP 登录 t2.t8、dfpReport 响应 t5、库 getHDID | 服务端(dfpReport 解密 cw 后签发)或库内生成 | ✅ 注册链可铸 |
|
||||||
|
| **CDID40** | 40hex | CDID(库 getCDID) | 登录帧 fingerprint 附近 / 库内 | libhydeviceid | unidbg 可调 |
|
||||||
|
| **MID16** | 16hex | mid(LiveUserbase→tUAEx→t5=sMId) | doLaunch 请求、库 getMID | 设备(可任意铸) | ✅ 任意 16hex |
|
||||||
|
| **ACTION** | 长串 | safedeviceid = 注册链 t2(登录授权令牌) | 登录帧 t0.t5 | 服务端(dfpReport 签发,每账号新拉) | ✅ 注册链可铸 |
|
||||||
|
| **SIGDEV40** | 40hex | HYSIGNAL_DEVICE_ID_KEY(hysignal 设备键) | hysignalconfigcache | hysignal 缓存 | 未研究 |
|
||||||
|
|
||||||
|
## 三条必守规则
|
||||||
|
|
||||||
|
1. **每次提及必须带前缀**:`HDID32(登录t1.t0)`、`GUID32(doLaunch)`、`DEVID40(注册链t5)`。
|
||||||
|
上下文允许时至少写前缀:`HDID32`、`GUID32`、`DEVID40`、`MID16`、`ACTION`。
|
||||||
|
2. **"hdid" 这个词默认指 HDID32**(登录帧 t1.t0 设备证书);
|
||||||
|
"GUID" 默认指 GUID32(doLaunch sGuid)。两者**绝不可互换/混用**。
|
||||||
|
3. 新增分析必须引用本规范表,并在初次出现时给出前缀 + 长度 + 体系,例如:
|
||||||
|
`HDID32(ed0db8334cadd236c00cadf7e11ab5a5, 登录t1.t0设备证书)`。
|
||||||
|
|
||||||
|
## 与代码变量的对应
|
||||||
|
|
||||||
|
| 代码中的旧名 | 规范名 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| `GOLDEN_HDID` | **GOLDEN_HDID32** | 金样本 = ed0db8…(登录 t1.t0) |
|
||||||
|
| `build_password_login_wup(hdid=)` | **HDID32** 参数 | 登录帧 t1.t0 |
|
||||||
|
| `device_profile.HDID` | **HDID32** | 同上 |
|
||||||
|
| `huya_device_register.t5` | **DEVID40** | 注册链 device_id |
|
||||||
|
| `huya_launch_mint.guid` | **GUID32** | doLaunch 请求/响应 sGuid |
|
||||||
|
|
||||||
|
> 历史文档(§11.8 之前的章节)中裸写 "hdid"/"GUID" 处,按本表语义理解:
|
||||||
|
> 登录相关 = HDID32,launch/铸币相关 = GUID32,40hex = DEVID40/CDID40。
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
|
<!-- ⚠️ 命名规范强制约束:本档中所有设备标识必须带前缀。规范见 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授权令牌。
|
||||||
|
旧段落中裸词按上下文语义理解:登录相关=HDID32,launch/铸币=GUID32,40hex=DEVID40。 -->
|
||||||
|
|
||||||
# dfpReport 破解进度总结 (待破解#2)
|
# dfpReport 破解进度总结 (待破解#2)
|
||||||
|
|
||||||
> **当前状态**:加密算法已确定为**逐字节 XOR keystream**(非 XXTEA),明文 JSON 已全部拿到。
|
> **当前状态**:加密算法已确定为**逐字节 XOR keystream**(非 XXTEA),明文 JSON 已全部拿到。
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
<!-- ⚠️ 命名规范强制约束:本档中所有设备标识必须带前缀。规范见 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授权令牌。
|
||||||
|
旧段落中裸词按上下文语义理解:登录相关=HDID32,launch/铸币=GUID32,40hex=DEVID40。 -->
|
||||||
|
|
||||||
# hyCred 签发协议 — 侦察笔记(2026-08-25 傍晚)
|
# hyCred 签发协议 — 侦察笔记(2026-08-25 傍晚)
|
||||||
|
|
||||||
> 目标:任意账号取得有效 hyCred(114B),配合 tools/cert_forge 实现全自动多账号。
|
> 目标:任意账号取得有效 hyCred(114B),配合 tools/cert_forge 实现全自动多账号。
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ try:
|
|||||||
except Exception: # pragma: no cover
|
except Exception: # pragma: no cover
|
||||||
HAVE_REG = False
|
HAVE_REG = False
|
||||||
|
|
||||||
GOLDEN_HDID = "ed0db8334cadd236c00cadf7e11ab5a5" # 金样本 hdid (对照基线)
|
GOLDEN_HDID32 = "ed0db8334cadd236c00cadf7e11ab5a5" # 金样本 HDID32 (登录t1.t0设备证书, 对照基线)
|
||||||
URL = "https://wup.huya.com"
|
URL = "https://wup.huya.com"
|
||||||
|
|
||||||
|
|
||||||
@@ -66,8 +66,8 @@ def full_control_login(account: str, password: str) -> str:
|
|||||||
return "REJECTED:no-reg-chain"
|
return "REJECTED:no-reg-chain"
|
||||||
t1, t2, t5 = gen_fresh_identity()
|
t1, t2, t5 = gen_fresh_identity()
|
||||||
print(f"[reg] t1={t1} t2={t2[:16]}... t5={t5}")
|
print(f"[reg] t1={t1} t2={t2[:16]}... t5={t5}")
|
||||||
out = login_with_registered(t2, t5, account, password, golden_hdid=GOLDEN_HDID)
|
out = login_with_registered(t2, t5, account, password, golden_hdid=GOLDEN_HDID32)
|
||||||
print(f"[login] 金样本hdid={GOLDEN_HDID} -> {_brief(out)}")
|
print(f"[login] 金样本HDID32={GOLDEN_HDID32} -> {_brief(out)}")
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,9 @@
|
|||||||
- ★(2026-08-27 突破) 服务端不校验 dfpReport 加密体(cw)内容: 随机 4146B cw 照样
|
- ★(2026-08-27 突破) 服务端不校验 dfpReport 加密体(cw)内容: 随机 4146B cw 照样
|
||||||
200 + 签发新 t2/t5。t5(device_id) = 服务端从 cw 解出的 40hex hdid, 随机 cw 时
|
200 + 签发新 t2/t5。t5(device_id) = 服务端从 cw 解出的 40hex hdid, 随机 cw 时
|
||||||
为随机值但服务端宽容。-> 无需真机加密体, python 零设备注册链达成 (--gen)。
|
为随机值但服务端宽容。-> 无需真机加密体, python 零设备注册链达成 (--gen)。
|
||||||
- 唯一不可铸造: WUP 登录帧 32hex hdid (libhydeviceid.so 本地生成 + native
|
- 唯一不可铸造: WUP 登录帧 32hex HDID32 (登录t1.t0设备证书; libhydeviceid.so 本地
|
||||||
setDeviceInfo 上报, 不走 HTTP) -> 多账号必须复用金样本 hdid (APP_SIGN_NOT_MATCH 硬错)。
|
生成 + native setDeviceInfo 上报, 不走 HTTP; 与 GUID32(doLaunch sGuid) 两套体系,
|
||||||
|
见 docs/HUYA_ID_NOMENCLATURE.md) -> 多账号必须复用金样本 HDID32 (APP_SIGN_NOT_MATCH 硬错)。
|
||||||
|
|
||||||
用途:
|
用途:
|
||||||
登录前注册链拿"新鲜 action" + [重放|随机] dfpReport 作为 safedeviceid,
|
登录前注册链拿"新鲜 action" + [重放|随机] dfpReport 作为 safedeviceid,
|
||||||
@@ -45,7 +46,7 @@ WSAPI = "https://wsapi.huya.com"
|
|||||||
WUP = "https://wup.huya.com"
|
WUP = "https://wup.huya.com"
|
||||||
UA = "okhttp/3.14.9"
|
UA = "okhttp/3.14.9"
|
||||||
GOLDEN_BIN = HERE.parent / "evidence" / "wup_passwordlogin_taf.bin"
|
GOLDEN_BIN = HERE.parent / "evidence" / "wup_passwordlogin_taf.bin"
|
||||||
GOLDEN_HDID = "ed0db8334cadd236c00cadf7e11ab5a5" # libhydeviceid.so 设备ID, 不可铸造
|
GOLDEN_HDID32 = "ed0db8334cadd236c00cadf7e11ab5a5" # HDID32 (登录帧t1.t0设备证书, 纯代码不可铸)
|
||||||
# 抓包真机加密体(dfpReport 请求) —— 设备身份锚, 加密算法未破解, 只能重放
|
# 抓包真机加密体(dfpReport 请求) —— 设备身份锚, 加密算法未破解, 只能重放
|
||||||
DFP_CHAIN_PKL = "/tmp/dfp_chain.pkl"
|
DFP_CHAIN_PKL = "/tmp/dfp_chain.pkl"
|
||||||
EVIDENCE_CHAIN = HERE.parent / "evidence" / "dfp_chain_golden.json"
|
EVIDENCE_CHAIN = HERE.parent / "evidence" / "dfp_chain_golden.json"
|
||||||
@@ -178,9 +179,9 @@ def fresh_action() -> str:
|
|||||||
|
|
||||||
def login_with_registered(action: str, t5_device_id: str,
|
def login_with_registered(action: str, t5_device_id: str,
|
||||||
account: str, password: str,
|
account: str, password: str,
|
||||||
golden_hdid: str = GOLDEN_HDID,
|
golden_hdid: str = GOLDEN_HDID32,
|
||||||
fingerprint: str | None = None) -> str:
|
fingerprint: str | None = None) -> str:
|
||||||
"""用注册链下发的 action/device_id + 金样本 hdid 登录, 返回 cred hex."""
|
"""用注册链下发的 ACTION(注册链t2)/DEVID40(注册链t5) + 金样本 HDID32(登录t1.t0) 登录, 返回 cred hex."""
|
||||||
from huya_wup_encoder import build_password_login_wup
|
from huya_wup_encoder import build_password_login_wup
|
||||||
from app_login_flow import parse_cred, parse_risk_url
|
from app_login_flow import parse_cred, parse_risk_url
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user