81 lines
2.7 KiB
JavaScript
81 lines
2.7 KiB
JavaScript
// R37: 挂 libhydeviceid.so 加密调用链 — 抓加密函数的密钥/nonce 参数
|
|
// 已知链 (R36 deflate bt): 0x57e7c(gzip包装) <- 0x58d38 <- 0x60e6c <- 0x5b1f4 <- 0x5a938 <- 0x20e924 <- JNI
|
|
'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 HY = null;
|
|
var events = 0;
|
|
var MAX = 400;
|
|
|
|
function dumpArgs(args, tag, ctx){
|
|
if (events >= MAX) return;
|
|
var row = {event:'call', fn:tag, args:[]};
|
|
for (var i=0;i<4;i++){
|
|
try {
|
|
var p = args[i];
|
|
var h = hexb(p, 48);
|
|
// 判定是否像指针指向数据
|
|
row.args.push({x:String(p), h: h});
|
|
} catch(e){ row.args.push({x:String(args[i]), h:''}); }
|
|
}
|
|
try {
|
|
row.bt = Thread.backtrace(ctx, Backtracer.ACCURATE).slice(0,12).map(function(a){
|
|
var m=Process.findModuleByAddress(a); return m? m.name+'!0x'+a.sub(m.base).toString(16) : a.toString();
|
|
});
|
|
} catch(e){}
|
|
events++;
|
|
emit(row);
|
|
}
|
|
|
|
function arm(){
|
|
if (HY) return true;
|
|
HY = Process.findModuleByName('libhydeviceid.so');
|
|
if (!HY) return false;
|
|
var offs = [0x57e7c, 0x58d38, 0x60e6c, 0x5b1f4, 0x5a938, 0x20e924];
|
|
for (var off of offs){
|
|
(function(off){
|
|
try {
|
|
Interceptor.attach(HY.base.add(off), {
|
|
onEnter(args){ this.tag='0x'+off.toString(16); this.on=true;
|
|
if (events < MAX) dumpArgs(args, this.tag+':e', this.context); },
|
|
onLeave(ret){
|
|
if (this.on && events < MAX){
|
|
events++;
|
|
emit({event:'ret', fn:this.tag, ret:String(ret), x0:String(this.context.x0), x1:String(this.context.x1)});
|
|
}
|
|
}
|
|
});
|
|
} catch(e){ emit({event:'hook-e', off:off, e:String(e).substring(0,120)}); }
|
|
})(off);
|
|
}
|
|
emit({event:'armed-hy'});
|
|
return true;
|
|
}
|
|
|
|
var poll = setInterval(function(){ if (arm()) clearInterval(poll); }, 150);
|
|
|
|
// SSL_write: 同轮 wire 密文
|
|
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<u.length;i++) s += (u[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'});
|