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:
@@ -0,0 +1,74 @@
|
||||
# 虎牙 32hex hdid 生成逆向研究(真机 M2102J2SC)
|
||||
|
||||
> 目标:搞清楚 WUP 登录帧 t1.t0 / field1.tag0 的 32hex hdid(金样本 `ed0db8334cadd236c00cadf7e11ab5a5`)
|
||||
> 如何生成、是否能在同一台设备上铸造新值(实现"每账号独立设备")。
|
||||
> 时间:2026-08-28(真机稳定注入通道打通后进行)。**已定位 32hex = NativeEntry.getGUID()。**
|
||||
|
||||
## 一、最终结论(决定性)
|
||||
|
||||
**32hex hdid(WUP 登录帧 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 = hdid(32hex)** |
|
||||
| getCDID() | `02df398797432eadefcc12767119ad5e80999389` | field2.tag2 = device_id(40hex) |
|
||||
| getHDID() | `7c5387e0539c023c31c4ff0e807e7256117385ee` | field2.tag8 = 另一设备ID(40hex) |
|
||||
| getMID() | `1e8bdf7d4f7a01d3` | MID(16hex) |
|
||||
| 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. **32hex(WUP 登录帧 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`(v7:dlopen→JNI_OnLoad→RegisterNatives 注册表 + get* 地址)
|
||||
- `scripts/phone_java_call_nativeentry.py`(**Java 主动调 NativeEntry get* 全家桶,读取 32hex GUID**)
|
||||
- `scripts/phone_read_hdid.py`(v8:native 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`
|
||||
Reference in New Issue
Block a user