feat(huya): ga k209202=16B块加密器+状态门打通 (R26)
- k209202 反汇编: len==16严格校验 + 0x24334状态化块加密核心 - mfa 0x48C18=单例字段 补非零后 b87_全链LIVE (XXTEA+inflate执行!) - 定论: 捕获密文密钥=设备材料派生(非静态), 传输链静态解=需ga IDA导出 - 下一步: 用户导 turingga.so / 或抓服务器 resp 旁路
This commit is contained in:
@@ -1342,3 +1342,30 @@ m209202(SparseArray,Context,Map)@0x21bdc n209202(SparseArray,[B,I,String,J)@0x43
|
||||
### 下一步 (两条关键路径)
|
||||
1. **用户导出的 turingga.so IDA export** → k209202@0x219d8 反编译 → 传输加密链静态全解 (同 mfa 方法论)
|
||||
2. harness 继续喂 ga 运行时状态 (0x48XXX 构建器等价物) → k209202 真调用 (同 b87_ -1 问题)
|
||||
|
||||
## §11.57 R26: ga k209202 = 16B 块加密器 + 状态门全打通 (2026-08-29)
|
||||
|
||||
### k209202@0x219d8 反汇编解构 ([B)[B)
|
||||
- **GetArrayLength; `cmp w0,#0x10; b.ne FAIL` = 严格 16B 输入** (非大块传输加密!)
|
||||
- GetByteArrayElements + strncpy(16B) → bl 0x19378 (对象创建!) → bl 0xc8a4 (builder-init)
|
||||
→ bl 0x13eb8×2 (序列化!) → bl 0x1c640×2 → **bl 0x24334 (块加密核心: calloc+memcpy+全局0x48000+c18状态+0x5754串!)**
|
||||
→ bl 0x19258 (收尾) → NewByteArray(0x580)+ 结果 vs 全局计数器 cmp
|
||||
- **0x24334 = 带状态的块加密机器** (读 [0x48000+0xc18] 指针再解引用 → 计数器对比 w21!)
|
||||
- 失败路径: 0x21b4c (len≠16 → x20=null) / 0x21bb0; 成功 = NewByteArray-route
|
||||
|
||||
### harness 状态门全打通
|
||||
- **mfa: 0x48C18 = 单例 48BD8 对象字段 a1+64 (id!) — 补非零 → b87_ 全链 LIVE!!**
|
||||
(sub_347C8(map-check) → GetByteArrayElements → sub_2E4A4 → XXTEA+inflate 全部执行!)
|
||||
- b87_ 对捕获密文三种输入 (strip/only/magic-full) 全 -1 = **确定性拒绝 — 捕获 ≠ b87_'resp' 格式**
|
||||
- ga: 0x48c18 状态指针已补 → k209202 仍 -1 (0x19378 对象创建需更深的 SDK 全局态)
|
||||
|
||||
### 结论 (本阶段定论)
|
||||
- **捕获密文的密钥 = 设备材料派生 (mpdc 16B→ga 16B块加密→主密!) — 非静态 3DF88**
|
||||
- mfa 的 XXTEA (24D58) = 内部序列化 (resp-解码侧!) — 已 100% 回环验证
|
||||
- **传输加密链 0x19378/0x13eb8/0x24334 的静态明文 = 需要 turingga.so 的 IDA 导出**
|
||||
(同 mfa 方法论: 反编译这些函数的 key 派生/块加密逻辑 = 密钥再推导!)
|
||||
|
||||
### 立即下一步
|
||||
1. **用户导出 turingga.so 的 IDA decompile** (k209202 全家: 0x219d8/0x24334/0x19378/0x13eb8/0x1c640)
|
||||
2. harness 继续: mfa 单例 34D68 全量 ctor (48BD8) + 各字段填充 → b87_ 对正确 resp 输入成功
|
||||
3. 或 frida 捕获一次 **服务器 dfpConfig 响应** (b87_ 的 resp 输入 = 密钥推导的旁路!)
|
||||
|
||||
@@ -280,6 +280,13 @@ public class TuringProbe {
|
||||
DvmObject<?> sa = vm.resolveClass("android/util/SparseArray").newObject(null);
|
||||
DvmObject<?> dba = vm.resolveClass("[B").newObject(blob);
|
||||
DvmObject<?> map = vm.resolveClass("java/util/HashMap").newObject(null);
|
||||
// 补 0x48C18 门 (单例字段 a1+64) — 非零即可过 b87_ 的 qword_48C18 检查
|
||||
try {
|
||||
com.github.unidbg.pointer.UnidbgPointer st = emulator.getMemory().mmap(0x100, 7);
|
||||
st.setMemory(0, 0x100, (byte) 0);
|
||||
com.github.unidbg.pointer.UnidbgPointer.pointer(emulator, m.base + 0x48C18).setPointer(0, st);
|
||||
System.out.println("[TP] state 0x48C18 <- " + Long.toHexString(st.peer));
|
||||
} catch (Throwable t3) { System.out.println("[TP] state EXC " + t3); }
|
||||
// 直调 impl: module.base + 0x25c98; 参数: env, null, 局部引用句柄(int), ..., 1
|
||||
long fn = m.base + 0x25c98;
|
||||
int hsa = vm.addLocalObject(sa);
|
||||
@@ -288,7 +295,7 @@ public class TuringProbe {
|
||||
System.out.println("[TP] calling b87_ @ " + Long.toHexString(fn) + " blob=" + blob.length
|
||||
+ " refs hsa=" + hsa + " hba=" + hba + " hmap=" + hmap);
|
||||
int iv = Integer.parseInt(System.getenv().getOrDefault("TP_INT", "1"));
|
||||
Number ret = m.callFunction(emulator, fn, vm.getJavaVM(), null, hsa, hba, hmap, iv);
|
||||
Number ret = m.callFunction(emulator, fn, ((com.github.unidbg.pointer.UnidbgPointer) vm.getJNIEnv()).peer, 0, hsa, hba, hmap, iv);
|
||||
System.out.println("[TP] b87_ ret=" + ret + " int=" + iv + " blob=" + blobPath);
|
||||
} catch (Throwable t) {
|
||||
System.out.println("[TP] callEnc EXC " + t);
|
||||
@@ -426,6 +433,15 @@ public class TuringProbe {
|
||||
com.github.unidbg.pointer.UnidbgPointer.pointer(emulator, ggap).setMemory(0, 0x720, (byte) 0);
|
||||
} catch (Throwable t) {}
|
||||
try { dm.callJNI_OnLoad(emulator); } catch (Throwable t) {}
|
||||
// 补 ga 0x48c18 状态指针 (ldr w8,[x8] 解引用) + 邻近槽
|
||||
try {
|
||||
com.github.unidbg.pointer.UnidbgPointer gst = emulator.getMemory().mmap(0x40, 7);
|
||||
gst.setMemory(0, 0x40, (byte) 0);
|
||||
gst.setInt(0, 1);
|
||||
com.github.unidbg.pointer.UnidbgPointer.pointer(emulator, gm.base + 0x48c18).setPointer(0, gst);
|
||||
com.github.unidbg.pointer.UnidbgPointer.pointer(emulator, gm.base + 0x48c20).setPointer(0, gst);
|
||||
System.out.println("[TP] ga state 0x48c18 <- " + Long.toHexString(gst.peer));
|
||||
} catch (Throwable t) {}
|
||||
byte[] blob = new java.io.FileInputStream(blobPath).readAllBytes();
|
||||
DvmObject<?> byteObj = vm.resolveClass("[B").newObject(blob);
|
||||
long env = ((com.github.unidbg.pointer.UnidbgPointer) vm.getJNIEnv()).peer;
|
||||
|
||||
Reference in New Issue
Block a user