feat(huya): turing密文流式模式判定 + 全双工捕获 (R18)

- 三样本差分: 仅5稳定字节(7cda+69c9f5头), 流式CTR+nonce非ECB
- SSL_write+SSL_read 全双工: req4198B+resp108B 捕获, java侧拼body回溯实锤
- 采样集: golden+f1+f2 三份密文; dfp_live 存档
- turing专项起点: 密钥材料mpdc/81B配置/ga2 齐备
This commit is contained in:
yml2213
2026-08-29 06:24:53 +08:00
parent b06a768eb2
commit 021cd636c8
6 changed files with 1277 additions and 25 deletions
+49 -25
View File
@@ -1,8 +1,8 @@
'use strict';
function emit(row) { try { send(row); } catch (e) {} }
function btOk() {
function btOk(ctx) {
try {
return Thread.backtrace(this.context, Backtracer.ACCURATE).slice(0, 10).map(a => {
return Thread.backtrace(ctx, Backtracer.ACCURATE).slice(0, 14).map(a => {
const m = Process.findModuleByAddress(a);
return m ? m.name + '!' + a.sub(m.base) : a.toString();
}).join(' <- ');
@@ -11,29 +11,53 @@ function btOk() {
const PREF = [0x57, 0x18, 0x82, 0xcf];
let fired = false;
for (const mod of Process.enumerateModules()) {
// ---- SSL_write: 扫描明文请求缓冲中的魔数 -> 全量 dump + 回溯 ----
let addr = null;
try { addr = mod.getExportByName('SSL_write'); } catch (e) {}
if (addr === null) continue;
Interceptor.attach(addr, {
onEnter(args) {
if (fired) return;
const buf = args[1];
const num = args[2].toInt32();
if (num < 40) return;
try {
const b = buf.readByteArray(1 << 20 > num ? num : num); // 尽量读
const u = new Uint8Array(b);
for (let i = 0; i + 4 < u.length; i++) {
if (u[i] === PREF[0] && u[i+1] === PREF[1] && u[i+2] === PREF[2] && u[i+3] === PREF[3]) {
fired = true;
const n = Math.min(num, 12000);
const hex = Array.from((new Uint8Array(buf.readByteArray(n)))).map(x => x.toString(16).padStart(2, '0')).join('');
emit({ event: 'ssl-magic', module: mod.name, num, off: i, full: hex, bt: btOk() });
return;
if (addr !== null) {
Interceptor.attach(addr, {
onEnter(args) {
const ctx = this.context;
if (fired) return;
const buf = args[1];
const num = args[2].toInt32();
if (num < 40) return;
try {
const u = new Uint8Array(buf.readByteArray(Math.min(num, 20000)));
for (let i = 0; i + 4 < u.length; i++) {
if (u[i] === PREF[0] && u[i+1] === PREF[1] && u[i+2] === PREF[2] && u[i+3] === PREF[3]) {
fired = true;
const hex = Array.from(u).map(x => x.toString(16).padStart(2, '0')).join('');
emit({ event: 'ssl-magic', module: mod.name, num, off: i, full: hex, bt: btOk(ctx) });
return;
}
}
}
} catch (e) {}
},
});
emit({ event: 'ssl-hook', module: mod.name });
}
} catch (e) {}
},
});
emit({ event: 'ssl-hook', module: mod.name, fn: 'write' });
}
// ---- SSL_read: 捕获响应 (含 tRsp/t1/sdid 特征的才发) ----
let rd = null;
try { rd = mod.getExportByName('SSL_read'); } catch (e) {}
if (rd !== null) {
Interceptor.attach(rd, {
onEnter(args) {
this._rdBuf = args[1];
this._rdNum = args[2].toInt32();
this._rdMod = mod.name;
},
onLeave(retval) {
const n = retval.toInt32();
if (n <= 40 || n > 20000) return;
try {
const hex = Array.from(new Uint8Array(this._rdBuf.readByteArray(n))).map(x => x.toString(16).padStart(2, '0')).join('');
if (fired || hex.indexOf('74727370') >= 0 || hex.indexOf('dfp') >= 0) {
emit({ event: 'ssl-readcap', module: this._rdMod, num: n, full: hex, bt: btOk(this.context) });
}
} catch (e) {}
},
});
emit({ event: 'ssl-hook', module: mod.name, fn: 'read' });
}
}