feat(huya): 💎 JAVA侧全逆! Cprivate XXTEA+会话密钥架构+Lyra TLV格式 (R30)

- Cprivate.java 加密/解密器全文 (XXTEA+MD5密钥变换+尾字长度)
- 密钥=SecureRandom 16字符[A-Za-z0-9] (guava.c内存明文! RSA封装上送)
- Lyra TLV: (type<<4)|tag, type 0-13 全表
- 捕获密文可用 Cprivate.a(data,会话key) 解密 - key在内存!
- 下一步: frida抓guava.c → 真key解密明文
This commit is contained in:
yml2213
2026-08-29 08:12:10 +08:00
parent 9586eaa8a3
commit 5a138376ca
10 changed files with 193 additions and 0 deletions
+34
View File
@@ -1446,3 +1446,37 @@ full: 7c da | 11 | 69 c9 f5 28 9c 4d 46 | 95 6f 21 | 10 bb 80
1. sub_1BAD8/1AA64 (编码上下文!) — 请求密钥路径
2. b209202 a6=1 harness 全调用 (喂捕获密文 → 解码输出!)
3. 或: 版本字节 01/11 的密钥变体
## §11.61 R30: 💎💎 JAVA 侧全逆 — 请求 XXTEA + 会话密钥架构 + Lyra TLV 格式 (2026-08-29)
### Cprivate.java = 请求加密器 (jadx 直读!)
```java
// b(data, key) = 加密 (XXTEA!):
// a(key) = key.length > 16 ? MD5(key) : key ← 密钥变换!
// words; v[last] = data.length ← 尾字=明文长度!
// XXTEA: sum -= 0x9E3779B9; e = (sum>>>2)&3; k[(i&3)^e]! ← 与 native sub_24D58 同构!
// a(data, key) = 解密 (140行!): 逆循环 + 长度校验 (i11<=i3<<2!)
```
- **KEY 变换确认: >16B → MD5; 16B 内 → 原样**
### 密钥架构 (Perseus.java + Guava.java!)
- **密钥 = SecureRandom 16 字符 [A-Za-z0-9] (62^16!)** — 内存字符串 guava.c!
- RSA-encrypt(hex(key), 内嵌公钥 MIIBI...) → 帧1 上送服务器 (guava.b 信封!)
- "EP_TuringMM" 标识串 + Guava{seq, envelope, KEY-STRING, sessionId, expire}
- 请求密文 key = guava.c 的 UTF-8 字节 (16B 不触发 MD5!)
### Lyra/Lynx TLV 格式 (请求结构!)
- 帧头 = (type<<4)|tag; type==15 → 扩展 tag 下一字节!
- type: 0=1B 1=2B 2=4B 3=8B 4=4B 5=8B 6=lenB+str 7=4Blen+bytes 8/9=集合 10=map 11=END
- 请求 = 帧10(配置) + 帧11(CIPHER 字段2!) — 捕获密文 = Cprivate.b(序列化事件, session-key!)
- 13B 头 decode 进行中 (first: '7c' = type7-tagC bytes!)
### 结论
- **捕获密文 = Java Cprivate.a(data, 16字符会话密钥) 可解 — 密钥在 app 内存 (guava.c)!**
- 静态/哈希密钥全错的根因: 每次会话随机 16 字符!
- 纯代码铸造 = 伪造会话: RSA 信封自己签不了 → 但可 frida 内存取 key!
### 下一步 (R31)
1. frida 抓 guava.c (16字符) — Java 层单点 hook (Perseus.a 本地串 / Guava 实例)
2. 用真 key 跑 Cprivate.a(捕获密文) = 明文事件!
3. Lynx 全解码器 (13B 头语义 + 帧结构)