// R38: 追踪 RC4 key (32hex) 的诞生点 — Java MessageDigest + udb md5 + 0x60e6c 反查副本 '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 nEvents = 0; // ---- 1) Java MessageDigest 全量 (md5/sha1) ---- setImmediate(function(){ Java.perform(function(){ try { var MD = Java.use('java.security.MessageDigest'); MD.digest.overload().implementation = function(){ var algo = this.getAlgorithm(); var out = this.digest(); try { var hex = Array.prototype.map.call(out, function(b){ return ('0'+(b&0xff).toString(16)).slice(-2); }).join(''); nEvents++; emit({event:'java-digest', algo: algo, out: hex}); } catch(e){} return out; }; MD.digest.overload('[B').implementation = function(inp){ var algo = this.getAlgorithm(); var out = this.digest(inp); try { var hex = Array.prototype.map.call(out, function(b){ return ('0'+(b&0xff).toString(16)).slice(-2); }).join(''); var inHex = Array.prototype.map.call(inp, function(b){ return ('0'+(b&0xff).toString(16)).slice(-2); }).join(''); nEvents++; emit({event:'java-digest', algo: algo, out: hex, in_hex: inHex.substring(0,2048)}); } catch(e){} return out; }; emit({event:'java-md5-hooked'}); } catch(e){ emit({event:'java-e', e:String(e).substring(0,150)}); } }); }); // ---- 2) udbauthunify md5 (0x32e71c) 原始参数 ---- function armUdb(){ var u = Process.findModuleByName('libudbauthunify.so'); if (!u) return false; try { Interceptor.attach(u.base.add(0x32e71c), { onEnter(args){ this.a = []; for (var i=0;i<4;i++) this.a.push({x:String(args[i]), h:hexb(args[i],96)}); this.lr = this.returnAddress; }, onLeave(){ try { var outs = []; for (var i=0;i<2;i++) outs.push(hexb(this.a[i].x ? ptr(this.a[i].x) : ptr(0), 96)); nEvents++; emit({event:'udb-md5', args:this.a, out_re:outs, lr: String(this.lr)}); } catch(e){} } }); emit({event:'udb-armed'}); return true; } catch(e){ return false; } } // ---- 3) 0x60e6c 到位点 + 全内存反查 key 副本 ---- function armHy(){ var h = Process.findModuleByName('libhydeviceid.so'); if (!h) return false; try { Interceptor.attach(h.base.add(0x60e6c), { onEnter(args){ try { var s = ''; try { s = args[1].readCString(64); } catch(e){} nEvents++; emit({event:'key-site', x1:String(args[1]), key:s}); if (s && s.length === 32) { setTimeout(function(){ var pat = ''; for (var i=0;i<16;i++) pat += s.substr(i,2).split('').join('')+' ' ; pat = s.substring(0,16).split('').map(function(c){ return ('0'+c.charCodeAt(0).toString(16)).slice(-2); }).join(' '); var n=0; for (var r of Process.enumerateRanges('rw-')) { if (r.size > 96*1024*1024) continue; var ms=[]; try { ms = Memory.scanSync(r.base, r.size, pat); } catch(e){ continue; } for (var m of ms){ if (n>=10) break; n++; emit({event:'key-copy', addr:String(m.address), src: r.file? r.file.path : String(r.base), around: hexb(m.address.sub(160), 352)}); } if (n>=10) break; } emit({event:'key-copies-done', n:n}); }, 50); } } catch(e){ emit({event:'key-e', e:String(e).substring(0,150)}); } } }); // 4) JNI 边界 0x20e924 参数 Interceptor.attach(h.base.add(0x20e924), { onEnter(args){ if (nEvents > 3000) return; var rows=[]; for (var i=0;i<3;i++) rows.push({x:String(args[i]), h:hexb(args[i],48)}); nEvents++; emit({event:'jni-boundary', args:rows}); } }); emit({event:'hy-armed'}); return true; } catch(e){ emit({event:'hy-e', e:String(e).substring(0,150)}); return false; } } var udb=false, hy=false; var poll = setInterval(function(){ if (!udb) udb = armUdb(); if (!hy) hy = armHy(); if (udb && hy) clearInterval(poll); }, 200); // ---- 5) SSL_write 同轮密文 ---- var done = false; for (var mod of Process.enumerateModules()){ var addr = null; try { addr = mod.getExportByName('SSL_write'); } catch(e){} if (!addr) continue; Interceptor.attach(addr, { onEnter(args){ if (done) return; try { var num = args[2].toInt32(); if (num < 60 || num > 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(''); emit({event:'post', num:num, hex:hex}); } catch(e){} } }); } emit({event:'script-loaded'});