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

2 篇文章 1 订阅
1 篇文章 3 订阅

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

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!Frida是一个强大的动态代码注入和调试工具,可以用于hook和修改应用程序的行为。如果你想要hook Native代码,可以使用Frida的JavaScript API来实现。 首先,你需要在设备上安装Frida,并确保设备已经越狱(iOS)或者已经root(Android)。 接下来,你需要编写一个JavaScript脚本来进行hook。在脚本中,你可以使用Frida提供的一些函数来定位和修改Native函数。 例如,下面的代码可以用来hook一个Native函数并修改它的行为: ```javascript // 导入Frida模块 const frida = require('frida'); // 目标进程的名称 const targetProcessName = 'your_target_process_name'; // 要hook函数名称 const targetFunctionName = 'your_target_function_name'; // Frida attach到目标进程 frida.attach(targetProcessName) .then(session => { // 创建一个脚本对象 const script = session.createScript(` // 找到目标函数 const targetFunction = Module.findExportByName(null, "${targetFunctionName}"); // 替换目标函数的实现 Interceptor.replace(targetFunction, new NativeCallback(() => { // 修改函数的行为,这里可以写你想要的逻辑 console.log("Function ${targetFunctionName} hooked!"); // 调用原始函数 const originalFunction = new NativeFunction(targetFunction, 'void', []); originalFunction.call(); // 可以在这里添加你的自定义代码 }, 'void', [])); }); // 加载并运行脚本 script.load() .then(() => { console.log("Script loaded successfully!"); }) .catch(error => { console.log(`Script error: ${error}`); }); }) .catch(error => { console.log(`Attach error: ${error}`); }); ``` 在上面的代码中,我们首先导入了Frida模块,然后指定了目标进程的名称和要hook函数名称。然后我们使用`frida.attach()`函数来连接到目标进程,并创建一个脚本对象。在脚本中,我们使用`Module.findExportByName()`函数来找到目标函数,然后使用`Interceptor.replace()`函数替换目标函数的实现。在替换的实现中,我们可以添加一些自定义的逻辑以修改函数的行为。 最后,我们使用`script.load()`函数加载并运行脚本。如果一切顺利,你应该能看到"Script loaded successfully!"的输出。 这只是一个简单的例子,你可以根据你的需求进行更复杂的hook和修改。希望对你有所帮助!如果有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值