// R35: 内存快照 @SSL_write — 定位密文缓冲区全部拷贝 + 邻域转储 + 会话密钥 // 目标: 在密文刚生成/刚发出的瞬间, 从堆内存里找到 (a) 明文 deflate 缓冲 (b) 16B 会话密钥 'use strict'; function emit(o){ try{ send(o); }catch(e){} } function hexb(p,n){ try{ return Array.from(new Uint8Array(p.readByteArray(n))).map(b=>('0'+b.toString(16)).slice(-2)).join(''); }catch(e){ return ''; } } var STATIC_KEY = 'f15e78d23033c2c4bac8a925677e863a'; var done = false; function scanRanges(ranges, patternHex, maxHits){ var pat = ''; for (var i=0;i 96*1024*1024) continue; try { var ms = Memory.scanSync(rg.base, rg.size, pat); for (var m=0; m 60000) return; var u = new Uint8Array(args[1].readByteArray(num)); var s = ''; for (var i=0;i=32 && u[i]<127) ? String.fromCharCode(u[i]) : '.'; if (s.indexOf('dfpReport') < 0) return; done = true; var hex = Array.prototype.map.call(u, function(x){return ('0'+x.toString(16)).slice(-2)}).join(''); var idx = hex.indexOf('571882cf664bb39401ee'); emit({event:'post', num:num, hex:hex, idx:idx}); if (idx < 0) return; // 线上密文前缀 (magic 后 10B 起, 取 16B 作内存搜索指纹) var CIPH = hex.substring(idx+20, idx+20+32); emit({event:'cipher-prefix', ciph:CIPH}); var bt = Thread.backtrace(this.context, Backtracer.ACCURATE).slice(0,30).map(function(a){ var m=Process.findModuleByAddress(a); return m? m.name+'!0x'+a.sub(m.base).toString(16) : a.toString(); }).join(' <- '); emit({event:'bt', bt:bt}); setTimeout(function(){ // ---- 1) Java 堆: Perseus/Guava 会话密钥 ---- try { Java.perform(function(){ try { Java.enumerateClassLoaders({ onMatch: function(loader){ try { Java.classFactory.loader = loader; Java.choose('com.tencent.turingfd.sdk.ams.ga.Perseus', { onMatch: function(inst){ try { var g = inst.b.value; emit({event:'perseus', key: g ? String(g.c.value) : null, envLen: g && g.b && g.b.value ? g.b.value.length : -1, d: g && g.d ? String(g.d.value) : null}); } catch(e){ emit({event:'perseus-e', e:String(e).substring(0,150)}); } }, onComplete: function(){} }); } catch(e){} }, onComplete: function(){} }); } catch(e){ emit({event:'j-e', e:String(e).substring(0,150)}); } }); } catch(e){} // ---- 2) native 堆扫描 ---- var ranges = enumAllRW(); emit({event:'ranges', n:ranges.length, bytes: ranges.reduce(function(a,r){return a+r.size;},0)}); // 2a. 密文拷贝定位 var hits = scanRanges(ranges, CIPH, 24); emit({event:'cipher-copies', n:hits.length, addrs: hits.map(function(h){return String(h.a);})}); // 每处转储 ±2KB 邻域 (前 8 处全量, 其余只记地址) for (var i=0;i=48&&c<=57)||(c>=65&&c<=90)||(c>=97&&c<=122); if (ok){ if(!run) start=j; run+=String.fromCharCode(c); } else { if (run.length===16 && !(cands[run])) { cands[run]=1; cn++; } run=''; } } if (run.length===16 && !cands[run]) { cands[run]=1; cn++; } } catch(e){} } emit({event:'key-cands', n:cn, keys:Object.keys(cands)}); // 2d. 全堆 zlib 头候选 (78 01/5e/9c/da) — 限量转储 256B 供主机验证 var zs=0; for (var r=0; r96*1024*1024) continue; for (var pi=0; pi<4 && zs<120; pi++){ var zpat = ['78 01','78 5e','78 9c','78 da'][pi]; var ms=[]; try { ms = Memory.scanSync(rg.base, rg.size, zpat); } catch(e){ continue; } for (var m=0; m