Loading... ## 一、hook导出函数基本框架 ```javascript Java.perform(function x(){ var str_name_so = "so文件名"; //需要hook的so名 // 需要hook的有导出函数名,可以在Exports表中看到 var ptr_func = Module.findExportByName(str_name_so, "有导出的函数名"); Interceptor.attach(ptr_func,{ //onEnter: 进入该函数前要执行的代码,其中args是传入的参数,一般so层函数第一个参数都是JniEnv,第二个参数是jclass,从第三个参数开始是我们java层传入的参数 onEnter: function(args) { send("*******nativeGetPendingEntry"); // send("args[2]=" + args[2]); //第一个传入的参数 // send("args[3]=" + args[3]); //第二个参数 send("=============================Stack strat======================="); send(Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n')); send("=============================Stack end ======================="); }, onLeave: function(retval){ //onLeave: 该函数执行结束要执行的代码,其中retval参数即是返回值 send("return:"+retval); //返回值 // retval.replace(100); //替换返回值为100 } }); }); ``` ## 二、hook无导出函数基本框架 ```javascript Java.perform(function x(){ var str_name_so = "so文件名"; //需要hook的so名 var n_addr_func_offset = so中的偏移地址; //需要hook的函数的偏移 onReceivedError var n_addr_so = Module.findBaseAddress(str_name_so); //加载到内存后 函数地址 = so地址 + 函数偏移 var n_addr_func = parseInt(n_addr_so, 16) + n_addr_func_offset; var ptr_func = new NativePointer(n_addr_func); Interceptor.attach(ptr_func,{ //onEnter: 进入该函数前要执行的代码,其中args是传入的参数,一般so层函数第一个参数都是JniEnv,第二个参数是jclass,从第三个参数开始是我们java层传入的参数 onEnter: function(args) { send("*******target func"); // send("args[2]=" + args[2]); //第一个传入的参数 // send("args[3]=" + args[3]); //第二个参数 send("=============================Stack strat======================="); send(Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n')); send("=============================Stack end ======================="); }, onLeave: function(retval){ //onLeave: 该函数执行结束要执行的代码,其中retval参数即是返回值 send("return:"+retval); //返回值 // retval.replace(100); //替换返回值为100 } }); }); ``` ## 三、Interceptor拦截器 其中Interceptor拦截器分为 ● Interceptor.attach(target, callbacks[, data]):拦截位于 target 的方法的调用. target 是一个 NativePointer 类型的对象, 指明了您想要拦截的方法的地址。 ● Interceptor.detachAll(): 分离所有之前附加上的回调。 ● Interceptor.replace(target, replacement[, data]):使用 replacement 替换 target 处的方法. 这通常在您需要完全或部分地替换已有方法时很有用。 ● Interceptor.revert(target): 将 target 处的方法还原到之前的实现。 ● Interceptor.flush():确保任何待定的更改已提交到内存. 这应该仅在少有的必要的情况中被执行, 例如, 您刚刚 attach() 或 replace() 了一个您即将通过 NativeFunction 调用的方法. 待定的改动将自动地在当前线程即将离开 JavaScript 运行时或 send() 被调用时被齐平, 比如在 RPC 方法中返回, 以及调用 console 中的任意 API。 最后修改:2024 年 01 月 23 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏