首页 > 其他分享 >学习笔记-JNI框架层的Hook利用

学习笔记-JNI框架层的Hook利用

时间:2022-11-11 09:22:22浏览次数:33  
标签:addr console name symbol 笔记 Hook var JNI log

系统框架native hook

  • JNI函数符号hook
  • JNI函数参数、返回值打印和替换
  • 动态注册JNI_Onload
  • hook RegisterNatives
  • jnitrace
  1. 引入一个例子,hook GetStringUTFChars这个jni函数,实际上看安卓源码会很明显 发现是在libart.so文件中,我们可以像objection一样将模块枚举出来,然后再把符号给枚举出来 ,发现libart的符号表居然没有被抹去,真香,这里打印下导出符号

function EnumerateAllExports()
{
var modules=Process.enumerateModules();
for(var i=0;i<modules.length;i++)
{
var module=modules[i];
var module_name=modules[i].name;
var exports=module.enumerateExports();
console.log("module_name->",module_name," module.enumerateExports ->",JSON.stringify(exports))
}
}

发现里面并没有我们要hook的函数,2333,所以换个思路直接把符号全部打印出来,libart.so的符号表也没有被抹去。

function hook_JNI()
{
var GetStringUTFChars_addr=null;
var symbools=Process.findModuleByName("libart.so").enumerateSymbols();
//console.log(JSON.stringify(symbool));
for(var i =0;i<symbools.length;i++)
{
var symbol=symbools[i].name;
if((symbol.indexOf("CheckJNI")==-1)&&(symbol.indexOf("JNI")>=0))
{
if(symbol.indexOf("GetStringUTFChars")>=0)
{
console.log("finally found GetStringUTFChars name:",symbol);
GetStringUTFChars_addr=symbools[i].address;
console.log("finally found GetStringUTFChars address :",GetStringUTFChars_addr);
}
}
}

发现可以直接将我们要hook的jni函数的地址打印出来,真的强,不过我也意识到hook native层的东西,首先就是要找到地址,无论是偏移加基地址,还是直接hook出来地址,重点就在于地址,然后就是枚举的时候,要注意筛选,indexOf()函数也用过很多次了。

function hook_JNI()
{
var GetStringUTFChars_addr=null;
var symbools=Process.findModuleByName("libart.so").enumerateSymbols();
//console.log(JSON.stringify(symbool));
for(var i =0;i<symbools.length;i++)
{
var symbol=symbools[i].name;
if((symbol.indexOf("CheckJNI")==-1)&&(symbol.indexOf("JNI")>=0))
{
if(symbol.indexOf("GetStringUTFChars")>=0)
{
console.log("finally found GetStringUTFChars name:",symbol);
GetStringUTFChars_addr=symbools[i].address;
console.log("finally found GetStringUTFChars address :",GetStringUTFChars_addr);
}
}
}
Interceptor.attach(GetStringUTFChars_addr,{
onEnter:function(args){
console.log("art::JNI::GetStringUTFChars(_JNIEnv*,_jstring*,unsigned char*)->",args[0],Java.vm.getEnv().getStringUtfChars(args[1],null).readCString(),args[1],args[2]);
console.log('CCCryptoCreate called from:\n'+Thread.backtrace(this.context,Backtracer.FUZZY).map(DebugSymbol.fromAddress).join("\n")+'\n');

},onLeave:function(retval){
console.log("retval is->",retval.readCString());

}
})
}
setImmediate(hook_JNI);

  1. hook newStringUTFChar函数,并修改参数和返回值,语法记住就行了固定操作

function replace_JNI()
{
var NewStringUTF_addr=null;
var symbools=Process.findModuleByName("libart.so").enumerateSymbols();
//console.log(JSON.stringify(symbool));
for(var i =0;i<symbools.length;i++)
{
var symbol=symbools[i].name;
if((symbol.indexOf("CheckJNI")==-1)&&(symbol.indexOf("JNI")>=0))
{
if(symbol.indexOf("NewStringUTF")>=0)
{
console.log("finally found NewStringUTF_name:",symbol);
NewStringUTF_addr=symbools[i].address;
console.log("finally found NewStringUTF_address :",NewStringUTF_addr);
}
}
}
var NewStringUTF=new NativeFunction(NewStringUTF_addr,"pointer",["pointer","pointer"]);
Interceptor.replace(NewStringUTF_addr,new NativeCallback(function(parg1,parg2){
console.log("parg1,parg2->",parg1,parg2.readCString());
var newPARG2=Memory.allocUtf8String("newPARG2");
//NewStringUTF(parg1,parg2);
var result=NewStringUTF(parg1,parg2);
return result;
},"pointer",["pointer","pointer"]))
}


setImmediate(replace_JNI);

  1. registerNative的hook

function hook_RegisterNatives(){
var RegisterNatives_addr = null;
var symbols = Process.findModuleByName("libart.so").enumerateSymbols()
//console.log(JSON.stringify(symbols))
for(var i = 0;i<symbols.length;i++){
var symbol = symbols[i].name;
if((symbol.indexOf("CheckJNI")==-1)&&(symbol.indexOf("JNI")>=0)){
if(symbol.indexOf("RegisterNatives")>=0){
console.log("finally found RegisterNatives_name :",symbol);
RegisterNatives_addr =symbols[i].address ;
console.log("finally found RegisterNatives_addr :",RegisterNatives_addr);
}
}
}

if(RegisterNatives_addr!=null){
Interceptor.attach(RegisterNatives_addr,{
onEnter:function(args){
console.log("[RegisterNatives]method counts :",args[3]);
var env = args[0];
var jclass = args[1];
var class_name = Java.vm.tryGetEnv().getClassName(jclass);
var methods_ptr = ptr(args[2]);
var method_count = parseInt(args[3]);
for (var i = 0; i < method_count; i++) {
var name_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3));
var sig_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize));
var fnPtr_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize * 2));
var name = Memory.readCString(name_ptr);
var sig = Memory.readCString(sig_ptr);
var find_module = Process.findModuleByAddress(fnPtr_ptr);
console.log("[RegisterNatives] java_class:", class_name, "name:", name, "sig:", sig, "fnPtr:", fnPtr_ptr, "module_name:", find_module.name, "module_base:", find_module.base, "offset:", ptr(fnPtr_ptr).sub(find_module.base));
}
},onLeave:function(retval){
}
})

}else{
console.log("didn`t found RegisterNatives address")
}

}

setImmediate(hook_RegisterNatives);

 

 

 

点击关注,共同学习!
[安全狗的自我修养](https://mp.weixin.qq.com/s/E6Kp0fd7_I3VY5dOGtlD4w)


[github haidragon](https://github.com/haidragon)


https://github.com/haidragon

标签:addr,console,name,symbol,笔记,Hook,var,JNI,log
From: https://www.cnblogs.com/haidragon/p/16879534.html

相关文章

  • 学习笔记-libc框架层的Hook利用
    系统框架层nativehooklibc函数符号hooklibc函数参数、返回值打印和替换主动调用libc读写文件hooklinkerdlopenfrida-trace引入例子,先hookpthread这个libc函......
  • Vue3学习笔记(五)——路由,Router
    一、前端路由的概念与原理1.1.什么是路由路由(英文:router)就是对应关系。1.2.SPA与前端路由SPA指的是一个web网站只有唯一的一个HTML页面,所有组件的展示与切换都......
  • 方滨兴院士讲座笔记
    安全和技术是伴生,没有技术,就没有安全问题人工智能在安全领域的四种表现形态深度伪造:利用人工智能仿生,通过像人脸识别那样的检测,或者AI换脸智能防御:人工智能预测攻击后......
  • Head First Java 读书笔记
    第11章:异常处理如果你把有风险的程序代码包含在try/catch块中,那么编译器会放心很多。try/catch块会告诉编译器你确实知道所调用的方法会有风险,并且也已经准备好要处理......
  • 学习笔记 之 简单了解有关 CSS 那点事儿
    LZ-Says:调整心态,多读书,丰富内心,提升个人文化底蕴。前言前几天,初步了解了下HTML相关的知识点,在学习回顾时,还好,大部分都在,只是新增了一些其他内容,例如自适应等等。上手......
  • C语言学习笔记---sizeof关键字和strlen函数
    sizeof和strlen在C语言中常用来计算字符大小和长度,在应用中却有着本质的区别。 sizeof是C语言中的关键字,其作用是返回一个对象或类型所占的内存字节数。使用方式为:int......
  • MIT6.S081笔记:Lab Xv6 And Unix Utilities
    关于MIT6.S081这门课的前身是MIT著名的课程6.828,MIT的几位教授为了这门课曾专门开发了一个基于x86的教学用操作系统JOS,被众多名校作为自己的操统课程实验。但随......
  • 【学习笔记】AC自动机
    AC自动机其实我将近三个月前就准备写这个并且随笔都建好了,但是一直咕咕到现在才写。其实记忆力好的同学应该意识到这篇其实8月份已经发过了,这次只是更新了一下发布日期而......
  • 模块化笔记软件 Anytype 综合评测
    随着Notion在笔记软件赛道的快速崛起,获得了很多用户的喜欢。然而,Notion也存在部分缺点。对于中国大陆用户而言,使用Notion需要特殊网络。否则,有时候会登录很慢,或者分享/......
  • 模板和泛型编程 C++ primer笔记
    16.1定义模板重载多个相似的函数是麻烦的:比如重载能接受多个类型的compare。使用函数模板之后可以定义成这样:template<typenameT>intcompare(constT&v1,constT......