'use strict'; function emit(row) { try { send(row); } catch (e) {} } function btOk(ctx) { try { return Thread.backtrace(ctx, Backtracer.ACCURATE).slice(0, 10).map(a => { const m = Process.findModuleByAddress(a); return m ? m.name + '!' + a.sub(m.base) : a.toString(); }).join(' <- '); } catch (e) { return ''; } } const PREF = [0x57, 0x18, 0x82, 0xcf]; let fired = false; function hexOfBytes(arr, max) { try { return Array.from(Java.array('byte', arr).slice(0, max || 96)).map(b => (b & 0xff).toString(16).padStart(2, '0')).join(''); } catch (e) { return ''; } } // ===== SSL_write magic ===== for (const mod of Process.enumerateModules()) { 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], 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 n = Math.min(num, 20000); 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(this.context) }); return; } } } catch (e) {} }, }); } // ===== turing encrypt bridge ===== setTimeout(() => { try { Java.perform(() => { const targets = [ { cls: 'com.tencent.turingfd.sdk.ams.ga.native', methods: ['a'] }, { cls: 'com.tencent.turingfd.sdk.ams.ga.TNative$aa', methods: ['k209202_2A742FA224BA8A2A', 'k87_D2D99D56FECC73FD'] }, { cls: 'com.tencent.turingfd.sdk.ams.ga.Seedless', methods: ['getAIDCode', 'getAIDTicket'] }, ]; let hooked = 0; for (const t of targets) { let K = null; try { K = Java.use(t.cls); } catch (e) { continue; } for (const mn of t.methods) { try { K[mn].overloads.forEach(ov => { 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[]') return 'byte[' + Java.array('byte', a).length + ']:' + hexOfBytes(a, 80); const s = String(a); return s.length > 160 ? s.slice(0, 80) + '…(' + s.length + ')' : s; } catch (e2) { return ''; } }); emit({ event: 'turing-enc', cls: t.cls, method: mn, phase: 'enter', args: args.slice(0, 4) }); } catch (e3) {} const r = ov.apply(this, arguments); try { if (r !== null && r !== undefined) { if (r instanceof Java.use('byte[]')) emit({ event: 'turing-enc', cls: t.cls, method: mn, phase: 'leave', ret: 'byte[' + Java.array('byte', r).length + ']:' + hexOfBytes(r, 100) }); else { const s = String(r); emit({ event: 'turing-enc', cls: t.cls, method: mn, phase: 'leave', ret: s.length > 160 ? s.slice(0, 80) + '…(' + s.length + ')' : s }); } } } catch (e4) {} return r; }; hooked++; }); } catch (e5) {} } } emit({ event: 'turing-enc-hooks', n: hooked }); }); } catch (e) { emit({ event: 'turing-enc-err', msg: String(e).slice(0, 160) }); } }, 2500);