1.frida hook native 打印寄存器和指针参数的值
var str_name_so = "libxxxx.so"; //要hook的so名
var str_name_func = "getxxxx"; //要hook的函数名
var n_addr_func = Module.findExportByName(str_name_so , str_name_func);
console.log("func ShowMessageBoxID addr is ---" + n_addr_func);
Interceptor.attach(n_addr_func, {
onEnter: function(args)
{
this.val = args[1];
//获取到so某一处地址的寄存器的值
console.log("addr_xxx OnEnter :", Memory.readCString(this.context.r7));
},
//在hook函数之后执行的语句
onLeave:function(retval)
{
//打印函数执行完后 参数地址的内容 如果 传入的是指针 在函数内部赋值 就需要在函数执行完后才打印
//获取的方法 this.val = args[0] 这里是获取第1个参数 this.val = args[1]; 获取第二个参数
//console.log(hexdump(this.val, { offset: 0,length: 1,header: false,ansi: false}));
console.log(retval ); //打印返回值
//console.log("hook on leave")
}
});
hook java类全部方法
function hookCls(params) {
Java.perform(function(){
var classname='xxxxxxx';
var gclass = Java.use(classname);
console.log('\n[Hook Class: '+classname+']');
var gmethods = gclass.class.getDeclaredMethods();
gmethods.forEach(function (method) {
var methodName = method.getName();
var overloads = gclass[methodName].overloads;
overloads.forEach(function (overload) {
var proto = '(';
overload.argumentTypes.forEach(function (type) {proto += type.className + ', ';});
if (proto.length > 1) {proto = proto.substr(0, proto.length - 2);}
proto += ')';
console.log('[HOOK:'+methodName+proto+' success!]');
overload.implementation = function(){
console.log('[Hooking: ' + methodName + proto+']');
for(var i = 0; i < arguments.length; i++){
console.log('\t[arg'+i+'] = '+arguments[i]);
}
var ret=this[methodName].apply(this, arguments);
console.log('\t[return] ='+ret);
return ret;
}
})
})
})
}
dump 某处的内存
var soAddr = Module.findBaseAddress("libFORScanLite.so");
var passwordAddr = soAddr.add(0x147C20);
console.log(hexdump(passwordAddr, {
offset: 0,
length: 0x1000,
header: true,
ansi: true,
}));
apk启动太快 找不到so基址的hook方法
//刚注入的时候这个so还没加载,需要hook dlopen
function inline_hook() {
var base_hello_jni = Module.findBaseAddress("libxx.so");
console.log("base_hello_jni:", base_hello_jni);
if (base_hello_jni) {
console.log(base_hello_jni);
//inline hook
var addr_07320 = base_hello_jni.add(0x2E637);//指令执行的地址,不是变量所在的栈或堆
Interceptor.attach(addr_07320, {
onEnter: function (args) {
console.log("addr_07320 R0 R3:", this.context.r0,this.context.r3);//注意这里是怎么得到寄存器值的
}, onLeave: function (retval) {
}
});
}
}
//8.0以下所有的so加载都通过dlopen
function hook_dlopen() {
var dlopen = Module.findExportByName(null, "dlopen");
Interceptor.attach(dlopen, {
onEnter: function (args) {
this.call_hook = false;
var so_name = ptr(args[0]).readCString();
if (so_name.indexOf("libxx.so") >= 0) {
console.log("dlopen:", ptr(args[0]).readCString());
this.call_hook = true;//dlopen函数找到了
}
}, onLeave: function (retval) {
if (this.call_hook) {//dlopen函数找到了就hook so
inline_hook();
}
}
});
// 高版本Android系统使用android_dlopen_ext
var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");
Interceptor.attach(android_dlopen_ext, {
onEnter: function (args) {
this.call_hook = false;
var so_name = ptr(args[0]).readCString();
if (so_name.indexOf("libxx.so") >= 0) {
console.log("android_dlopen_ext:", ptr(args[0]).readCString());
this.call_hook = true;
}
}, onLeave: function (retval) {
if (this.call_hook) {
inline_hook();
}
}
});
}
native打印堆栈的方法
打印尽可能准确的堆栈信息
console.log('RegisterNatives called from:\\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\\n') + '\\n');
打印多的堆栈信息
console.log('RegisterNatives called from:\\n' + Thread.backtrace(this.context, Backtracer.FUZZY).map(DebugSymbol.fromAddress).join('\\n') + '\\n');
打印字符串
ptr(xxx).readUtf16String() //打印utf16编码 在有中文情况下好使
ptr(xxx).readUtf8String() //打印标准编码
ptr(xxx).readCString()
ptr(xxx).readAnsiString()//仅仅 windows 上可用
Memory.readCString(xxx)
frida-trace
frida-trace -U -f com.astech.forscanlite -i "read"
frida-trace -U -f com.astech.forscanlite -i "fread"
打印fread 读取内容和长度 修改frida-trace handlers/libc.so/fread.js
onEnter(log, args, state) {
log('fread(buf ,len)',args[0],args[2]);
this.buf = args[0]
this.len = Number(args[2]) //使用Number() 转成数值
},
onLeave(log, retval, state) {
console.log(hexdump(this.buf, {
offset: 0,
length: this.len,
header: true,
ansi: true,
}));
}