frida 常用的一些demo 打印native 函数的堆栈 参数,返回值 等

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值