'use strict'; function emit(row) { try { send(row); } catch (e) {} } function btOk(ctx) { try { 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(' <- '); } catch (e) { return ''; } } 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) { 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, 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' }); } }