docs(huya): 逆向定位 32hex hdid = NativeEntry.getGUID() + 真机注入通道证据

核心结论:
- 32hex hdid (WUP 登录帧 field1.tag0) = com.huya.security.hydeviceid.NativeEntry.getGUID()
- 金样本 ed0db8 为金样本设备 GUID; 当前真机 M2102J2SC getGUID()=0a7dfaa882938a6ab502511452142c57(稳定)
- NativeEntry 全字段: getGUID(32hex)/getCDID(40hex)/getHDID(40hex)/getMID(16hex)/getSDID(base64 safedeviceid)
- 单机不可铸造: 改 serialno/ANDROID_ID/删files/hydevice持久化 均不变(硬锚底层硬件)
- libhydeviceid.so 为 OLLVM+datadiv 壳; 用 dlopen->JNI_OnLoad->RegisterNatives(env表索引215) 绕开混淆

脚本: phone_probe_registernatives2(注册表)/phone_java_call_nativeentry(Java读getGUID)/phone_read_hdid(native hook)
      phone_dump_hydev(dump解密so)/phone_probe_login_frame(登录帧)/arm64_disasm(反汇编)
证据: hdid_regtable/java_nativeentry/hdid_read/login_frames/hdid_probe* + libhydeviceid_{original,dump}.so
This commit is contained in:
yml2213
2026-08-28 12:30:34 +08:00
parent 45b5e9128c
commit 0c6aff6a6d
23 changed files with 86238 additions and 0 deletions
+74
View File
@@ -0,0 +1,74 @@
# 虎牙 32hex hdid 生成逆向研究(真机 M2102J2SC)
> 目标:搞清楚 WUP 登录帧 t1.t0 / field1.tag0 的 32hex hdid(金样本 `ed0db8334cadd236c00cadf7e11ab5a5`
> 如何生成、是否能在同一台设备上铸造新值(实现"每账号独立设备")。
> 时间:2026-08-28(真机稳定注入通道打通后进行)。**已定位 32hex = NativeEntry.getGUID()。**
## 一、最终结论(决定性)
**32hex hdidWUP 登录帧 field1.tag0= `com.huya.security.hydeviceid.NativeEntry.getGUID()` 的返回值。**
- 金样本 `ed0db8...` 是**金样本设备**的 getGUID() 值;
- **当前真机 M2102J2SC 的 getGUID() = `0a7dfaa882938a6ab502511452142c57`**32hex,交叉验证稳定:
在 5 个设备上报帧中出现 + Java 主动调用一致)。
**getGUID() 每台设备唯一且稳定(硬锚硬件,同 getCDID/getHDID 一样),可被 `NativeEntry`
native 方法直接可靠读取。**
因此**"生成 32hex hdid" 无需逆向算法**:每台真机天然由 libhydeviceid.so 生成并提供它独有的
32hex getGUID()。多真机设备池 = 每台调 getGUID() 采集各自唯一值。
### 单机不可铸造(3 个决定性实验)
`ro.serialno` / `ANDROID_ID` / 删 `files/hydevice/` 持久化后重启,设备标识(UUID 文件名 +
getGUID 等)**全部不变** —— 因 libhydeviceid.so 基于底层硬件(SoC/IMEI)稳定生成,刷不掉。
## 二、NativeEntry 全部字段(已可靠读取)
通过 dlopen 拦截 → JNI_OnLoad(0x22c4c8) → RegisterNatives(JNIEnv 函数表索引 215)dump 出
`com.huya.security.hydeviceid.NativeEntry` 的 19 个 native 方法,Java 主动调用实测值:
| NativeEntry 方法 | 真机实测值 | 对应 WUP 登录帧字段 |
|---|---|---|
| **getGUID()** | **`0a7dfaa882938a6ab502511452142c57`** | **field1.tag0 = hdid32hex** |
| getCDID() | `02df398797432eadefcc12767119ad5e80999389` | field2.tag2 = device_id40hex |
| getHDID() | `7c5387e0539c023c31c4ff0e807e7256117385ee` | field2.tag8 = 另一设备ID40hex |
| getMID() | `1e8bdf7d4f7a01d3` | MID16hex |
| getSDID() | `PQwemAN9...`base64 180B | safedeviceid |
- Java 类 `com.huya.security.hydeviceid.NativeEntry` 注册 method 地址(libhydeviceid.so 偏移):
getCDID@0x20eb08 / getSDID@0x20ede8 / **getHDID@0x20f0c8** / init@0x20e6e4 /
getGUID@0x20f8c8 / getMID@0x20fba8 / linkId@0x20fe88(其余 setPhoneInfo/setMotionEvent/上报类略)。
- 另有 `com.huyaudb.HuyaAuthCore` 注册 `init/unInit/sendMsg/receiveNet`WUP 消息收发)。
### hdid 名称混淆(已彻底澄清)
项目里"hdid"对应**多个不同值**
1. **32hexWUP 登录帧 field1.tag0= getGUID()** —— 设备 GUID,硬锚,每台唯一;
2. 40hex `7c5387` = getHDID() = huyaudb 上报里被命名为 "hdid"**同名不同值**);
3. 40hex `02df39` = getCDID() = device_id
4. 16hex `1e8bdf7d4f7a01d3` = getMID()
5. 凭据文件 `files/hydevice/<UUID>``64a33427...`)持久化加密凭据。
## 三、libhydeviceid.so 加壳(静态逆向极难,但已绕过)
- **OLLVM 混淆**`based on Obfuscator-LLVM 9.0.9svn`+ **datadiv 运行时壳**~70 个 `.datadiv_decode*`
解密函数 + `hy_fopen64/hy_read/hy_syscall/hy_write/hyftell` 文件 I/O 壳 + 读 TracerPid 反调试)。
-**dlopen→JNI_OnLoad→RegisterNatives** 动态拿到方法表,绕开混淆,无需反汇编。
- 已 dump 解密后代码:`evidence/diag_phone/libhydeviceid_dump.so`(内存态)+ 原始
`libhydeviceid_original.so`
## 四、可行方向(服务于"每账号独立设备")——**推荐,已具备采集能力**
**多真机采集设备池**:每台真机用真机注入通道(spawn+art_callsite bypass)读
`{getGUID(32hex), getCDID(40hex), getHDID(40hex), getMID(16hex), getSDID(base64)}`
这些值每台唯一、稳定、被服务端认可。采集多台建设备池轮换,即可实现每账号独立设备。
**无需逆向铸造算法**,直接读 NativeEntry 即可。
## 五、实验脚本(真机)
- `scripts/phone_probe_registernatives2.py`v7dlopen→JNI_OnLoad→RegisterNatives 注册表 + get* 地址)
- `scripts/phone_java_call_nativeentry.py`**Java 主动调 NativeEntry get* 全家桶,读取 32hex GUID**
- `scripts/phone_read_hdid.py`v8native hook get* 用原生 JNI GetStringUTFChars 解码)
- `scripts/phone_dump_hydev.py`dump 解密后的 libhydeviceid.so
- `scripts/phone_probe_hdid*.py`(早期符号 / 属性 / 文件探针,过程记录)
- 证据:`evidence/diag_phone/{hdid_regtable,hdid_read,java_nativeentry,login_frames}.json` /
`libhydeviceid_{original,dump}.so`