Files
live-hub-py/tools/frida/hook_hy.js
T

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'});