From 0944e9c86b09a4a5240f2864d6a1746388adc6c9 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sat, 29 Aug 2026 06:29:34 +0800 Subject: [PATCH] =?UTF-8?q?docs(huya):=20R19=20turing=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E6=97=B6=E8=B7=AF=E7=BA=BF=E7=BB=88=E6=80=81=20=E2=80=94=20?= =?UTF-8?q?=E4=B8=93=E9=A1=B9=E4=BA=A4=E6=8E=A5=E8=B5=84=E4=BA=A7=E9=BD=90?= =?UTF-8?q?=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - turing类定位(ga果汁混淆系) + Java载荷hook零触发(=全native, 路线关闭) - 静态密钥假设否定; 流式密文实锤 - 交接: 密文x3/请求全文/组件/工具/触发方法全收录 (docs §11.49) --- docs/HUYA_HDID_ALGORITHM_GEN.md | 23 +++++++++ tools/frida/capture_20260829_062527.jsonl | 2 + tools/frida/capture_20260829_062648.jsonl | 2 + tools/frida/hook_turing_jni.js | 58 +++++++++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 tools/frida/capture_20260829_062527.jsonl create mode 100644 tools/frida/capture_20260829_062648.jsonl create mode 100644 tools/frida/hook_turing_jni.js diff --git a/docs/HUYA_HDID_ALGORITHM_GEN.md b/docs/HUYA_HDID_ALGORITHM_GEN.md index 83be3f2..c06c11c 100644 --- a/docs/HUYA_HDID_ALGORITHM_GEN.md +++ b/docs/HUYA_HDID_ALGORITHM_GEN.md @@ -1143,3 +1143,26 @@ dfpReport: tReq = [10B 魔数 57 18 82 cf 66 4b b3 94 01 ee][3988B 加密采 2. 密钥材料候选: mpdc_32hex / getDfpConfig 81B配置 / ga2 / turing.dat 3. 下一步: (a) frida 追 turing 内部 encrypt 调用 (JNI 层), (b) 静态 OLLVM 破 ga/mfa, (c) 若只求实用: 重放已捕获密文即可 (同设备身份) + +--- + +## §11.49 R19: turing 运行时路线终态 (2026-08-29) — 专项交接 + +### 本轮排查结论 +- turing 类定位: com.tencent.turingfd.sdk.ams.ga.{Lemon,Sultana,Solar,Blueberry,Pineapple,...} (果汁混淆系) +- Java 侧载荷 hook = 0 触发: turing 采集/加密全 native, Java 仅薄壳 (payload 不经过 Java 方法) -> Java-hook 路线关闭 +- 密文体流式模式实锤 (nonce 头 7cda..69c9f5, 仅5稳定字节) +- 静态密钥假设 (XOR-mpdc/内生钥) 全否定: 81B 配置/64B turing.dat = 真加密非简单 XOR + +### 破解 dfp 加密体的可行路线 (专项, 估时) +1. native 静态: libturingga/mfa (296KB, OLLVM, -fvisibility=hidden) — 多日 +2. native 动态: turing 加密函数的内存级 buff 追踪 (SSL 命中时刻向前追) — 日级 +3. 密钥链: 破 getDfpConfig 81B 配置 (服务端下发镜钥) — 依赖 1/2 +4. 实用主义: **重放已捕获密文 = 同设备身份注册成功** (现状方案不受影响) + +### 交接资产 (evidence/dfp_live/ + docs) +- 密文采样 ×3: golden(3908B) + f1(3531B) + f2(3931B) +- 请求全文: dfpReport_post_full*.bin (3798B/4198B) +- 组件: libturingga.so / libturingmfa.so / 32hex mpdc / 81B config / ga2 / turing.dat +- 工具: hook_ssl_magic.js (全双工) / hook_turing_jni.js / run_capture.py 自愈 +- 触发方法: 清 turing 状态重注册 (备份 tar 可回滚) diff --git a/tools/frida/capture_20260829_062527.jsonl b/tools/frida/capture_20260829_062527.jsonl new file mode 100644 index 0000000..bcbdb19 --- /dev/null +++ b/tools/frida/capture_20260829_062527.jsonl @@ -0,0 +1,2 @@ +{"event": "turing-classes", "list": ["android.text.util.-$$Lambda$Linkify$7J_-cMhIF2bcttjkxA2jDFP8sKw", "java.security.spec.ECFieldFp", "com.tencent.turingfd.sdk.ams.ga.Lemon", "com.tencent.turingfd.sdk.ams.ga.Sultana$do", "com.tencent.turingfd.sdk.ams.ga.Blueberry$do", "com.tencent.turingfd.sdk.ams.ga.Solar$if", "com.tencent.turingfd.sdk.ams.ga.Segment", "com.tencent.turingfd.sdk.ams.ga.Pineapple", "com.tencent.turingfd.sdk.ams.ga.Cumquat$do", "com.tencent.turingfd.sdk.ams.ga.Perseus", "com.tencent.turingfd.sdk.ams.ga.default", "com.tencent.turingfd.sdk.ams.ga.White", "com.tencent.turingfd.sdk.ams.ga.Nectarine$if$do", "com.tencent.turingfd.sdk.ams.ga.Rambutan", "com.tencent.turingfd.sdk.ams.ga.Sultana$if", "com.tencent.turingfd.sdk.ams.ga.Guava", "com.tencent.turingfd.sdk.ams.ga.Pitaya", "com.tencent.turingfd.sdk.ams.ga.Bryony", "com.tencent.turingfd.sdk.ams.ga.Core", "com.tencent.turingfd.sdk.ams.ga.Solar", "com.tencent.turingfd.sdk.ams.ga.native", "com.tencent.turingfd.sdk.ams.ga.Shaddock", "com.tencent.turingfd.sdk.ams.ga.synchronized", "com.tencent.turingfd.sdk.ams.ga.Pistachio", "com.tencent.turingfd.sdk.ams.ga.Sorosis", "com.tencent.turingfd.sdk.ams.ga.Pineapple$do", "com.tencent.turingfd.sdk.ams.ga.Quarenden$do", "com.tencent.turingfd.sdk.ams.ga.Flat", "com.tencent.turingfd.sdk.ams.ga.Auriga", "com.tencent.turingfd.sdk.ams.ga.private"]} +{"event": "turing-hooks-done", "n": 0} diff --git a/tools/frida/capture_20260829_062648.jsonl b/tools/frida/capture_20260829_062648.jsonl new file mode 100644 index 0000000..9665dd8 --- /dev/null +++ b/tools/frida/capture_20260829_062648.jsonl @@ -0,0 +1,2 @@ +{"event": "turing-classes", "list": ["android.text.util.-$$Lambda$Linkify$7J_-cMhIF2bcttjkxA2jDFP8sKw", "java.security.spec.ECFieldFp", "com.tencent.turingfd.sdk.ams.ga.Lemon", "com.tencent.turingfd.sdk.ams.ga.Sultana$do", "com.tencent.turingfd.sdk.ams.ga.Blueberry$do", "com.tencent.turingfd.sdk.ams.ga.Solar$if", "com.tencent.turingfd.sdk.ams.ga.Segment", "com.tencent.turingfd.sdk.ams.ga.Pineapple", "com.tencent.turingfd.sdk.ams.ga.Cumquat$do", "com.tencent.turingfd.sdk.ams.ga.Perseus", "com.tencent.turingfd.sdk.ams.ga.default", "com.tencent.turingfd.sdk.ams.ga.White", "com.tencent.turingfd.sdk.ams.ga.Nectarine$if$do", "com.tencent.turingfd.sdk.ams.ga.Rambutan", "com.tencent.turingfd.sdk.ams.ga.Sultana$if", "com.tencent.turingfd.sdk.ams.ga.Guava", "com.tencent.turingfd.sdk.ams.ga.Pitaya", "com.tencent.turingfd.sdk.ams.ga.Bryony", "com.tencent.turingfd.sdk.ams.ga.Core", "com.tencent.turingfd.sdk.ams.ga.Solar", "com.tencent.turingfd.sdk.ams.ga.native", "com.tencent.turingfd.sdk.ams.ga.Shaddock", "com.tencent.turingfd.sdk.ams.ga.synchronized", "com.tencent.turingfd.sdk.ams.ga.Pistachio", "com.tencent.turingfd.sdk.ams.ga.Sorosis", "com.tencent.turingfd.sdk.ams.ga.Pineapple$do", "com.tencent.turingfd.sdk.ams.ga.Quarenden$do", "com.tencent.turingfd.sdk.ams.ga.Flat", "com.tencent.turingfd.sdk.ams.ga.Auriga", "com.tencent.turingfd.sdk.ams.ga.private"]} +{"event": "turing-hooks-done", "n": 14} diff --git a/tools/frida/hook_turing_jni.js b/tools/frida/hook_turing_jni.js new file mode 100644 index 0000000..3c0cd91 --- /dev/null +++ b/tools/frida/hook_turing_jni.js @@ -0,0 +1,58 @@ +'use strict'; +function emit(row) { try { send(row); } catch (e) {} } +setTimeout(() => { + try { + Java.perform(() => { + const found = []; + Java.enumerateLoadedClasses({ + onMatch(name) { + if (/Turing|turing|DFp|Dfp|dfp/i.test(name)) found.push(name); + }, + onComplete() { + emit({ event: 'turing-classes', list: found.slice(0, 30) }); + const hooked = {}; + for (const cn of found.slice(0, 20)) { + try { + const K = Java.use(cn); + const ms = K.class.getDeclaredMethods(); + for (const m of ms) { + const mn = m.getName(); + const pt = m.getParameterTypes(); + const hasPayload = Array.from(pt).some(t => ['byte[]','java.lang.String','[B','java.util.Map'].indexOf(t.getName()) >= 0); + if (!hasPayload) continue; + const dsc = m.toGenericString ? m.toGenericString().slice(0, 120) : mn; + try { + K[mn].overloads.forEach(ov => { + const key = cn + '#' + mn + '#' + ov.argumentTypes.length; + if (hooked[key]) return; + hooked[key] = true; + ov.implementation = function () { + try { + const args = Array.from(arguments).map((a, ix) => { + try { + if (a === null || a === undefined) return String(a); + if (ov.argumentTypes[ix] && ov.argumentTypes[ix].className === 'byte[]') { + const arr = Java.array('byte', a); + return 'byte[' + arr.length + ']:' + Array.from(arr.slice(0, 60)).map(b => (b & 0xff).toString(16).padStart(2, '0')).join(''); + } + const s = String(a); + return s.length > 120 ? s.slice(0, 60) + '…(' + s.length + ')' : s; + } catch (e2) { return ''; } + }); + emit({ event: 'turing-jni', cls: cn, method: mn, nArgs: args.length, args: args.slice(0, 5) }); + } catch (e3) {} + return ov.apply(this, arguments); + }; + }); + } catch (e4) {} + } + } catch (e5) {} + } + emit({ event: 'turing-hooks-done', n: Object.keys(hooked).length }); + }, + }); + }); + } catch (e) { + emit({ event: 'turing-err', msg: String(e).slice(0, 200) }); + } +}, 3500);