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

系统框架层native hook

  • libc函数符号hook
  • libc函数参数、返回值打印和替换
  • 主动调用libc读写文件
  • hook linker dlopen
  • frida-trace
  1. 引入例子,先hook pthread这个libc函数,流程个人理解是,先看函数是否导出,如果导出可以直接使用frida api获得函数地址,至于是否导出,objection安排上,没导出,那就直接枚举so的所有符号,枚举出名字和地址,然后直接attach,还是hook,attach使用于只改变参数和返回值,hook的话,类似重载函数。

function begin()
{
Java.perform(function(){
Java.choose("com.example.demoso1.MainActivity",{
onMatch:function(instance)
{
console.log("Found instance");
instance.init();
},onComplete:function(){
console.log("Search complete!");
}
})
})
}
function hook_pthread()
{
var pthread_create_addr=Module.findExportByName("libc.so","pthread_create");
console.log("pthread_create_addr:",pthread_create_addr);
var time_addr=Module.findExportByName("libc.so","time");
Interceptor.attach(pthread_create_addr,{
onEnter:function(args){
console.log("args->",args[0],args[1],args[2]);
var libnativebaseaddress=Module.findBaseAddress("libnative-lib.so");
if(libnativebaseaddress!=null)
{
console.log("libnativebaseaddress->",libnativebaseaddress);
var detect_frida_loop_addr=args[2]-libnativebaseaddress;
console.log("detect_frida_loop offset is->",detect_frida_loop_addr);
if(args[2]-libnativebaseaddress==64944)
{
args[2]=time_addr;
}
}
},onLeave:function(retval)
{
}
})
}
function replace_pthread()
{
var pthread_create_addr=Module.findExportByName("libc.so","pthread_create");
console.log("pthread_create_addr->",pthread_create_addr);
var pthread_create=new NativeFunction(pthread_create_addr,"int",["pointer","pointer","pointer","pointer"]);
Interceptor.replace(pthread_create_addr,new NativeCallback(function(parg1,parg2,parg3,parg4){
console.log(parg1,parg2,parg3,parg4);
var libnativebaseaddress=Module.findBaseAddress("libnative-lib.so");
if(libnativebaseaddress!=null)
{
console.log("libnativebaseaddress->",libnativebaseaddress);
if(parg3-libnativebaseaddress==64944)
{
return null;
}
}
return pthread_create(parg1,parg2,parg3,parg4);
},"int",["pointer","pointer","pointer","pointer"])
)
}
setImmediate(replace_pthread);

  1. 自己主动调用读写函数,并将导出函数的名字和地址,打印到内存卡中,主要是api的使用,熟悉了,问题不大的

function beginAnti(){
Java.perform(function(){
Java.choose("com.example.demoso1.MainActivity",{
onMatch:function(instance){
console.log("Found instance!");
instance.init();
},onComplete:function(){console.log("Search complete!")}
})
})
}
function hook_pthread(){
var pthread_create_addr = Module.findExportByName("libc.so", "pthread_create");
var time_addr = Module.findExportByName("libc.so", "time");
console.log("pthread_create_addr=>",pthread_create_addr)
Interceptor.attach(pthread_create_addr,{
onEnter:function(args){
console.log("args=>",args[0],args[1],args[2],args[4])
var libnativebaseaddress = Module.findBaseAddress("libnative-lib.so")
if(libnativebaseaddress!=null){
console.log("libnativebaseaddress=>",libnativebaseaddress);
//var detect_frida_loop_addr = args[2]-libnativebaseaddress;
//console.log("detect_frida_loop offset is =>",detect_frida_loop_addr)
if(args[2]-libnativebaseaddress == 64900){
console.log("found anti frida loop!,excute time_addr=>",time_addr);
args[2]=time_addr;
}
}
},onLeave:function(retval){
console.log("retval is =>",retval)
}
})
}
function replace_pthread(){
var pthread_create_addr = Module.findExportByName("libc.so", "pthread_create");
console.log("pthread_create_addr=>",pthread_create_addr)
var pthread_create = new NativeFunction(pthread_create_addr,"int",["pointer","pointer","pointer","pointer"])
Interceptor.replace(pthread_create_addr,
new NativeCallback(function(parg1,parg2,parg3,parg4){
console.log(parg1,parg2,parg3,parg4)
var libnativebaseaddress = Module.findBaseAddress("libnative-lib.so")
if(libnativebaseaddress!=null){
console.log("libnativebaseaddress=>",libnativebaseaddress);
if(parg3-libnativebaseaddress == 64900){
return null;
}
}
return pthread_create(parg1,parg2,parg3,parg4)
},"int",["pointer","pointer","pointer","pointer"]))
}
function writeSomething(path,contents){
var fopen_addr = Module.findExportByName("libc.so", "fopen");
var fputs_addr = Module.findExportByName("libc.so", "fputs");
var fclose_addr = Module.findExportByName("libc.so", "fclose");
//console.log("fopen=>",fopen_addr," fputs=>",fputs_addr," fclose=>",fclose_addr);
var fopen = new NativeFunction(fopen_addr,"pointer",["pointer","pointer"])
var fputs = new NativeFunction(fputs_addr,"int",["pointer","pointer"])
var fclose = new NativeFunction(fclose_addr,"int",["pointer"])
console.log(path,contents)
var fileName = Memory.allocUtf8String(path);
var mode = Memory.allocUtf8String("a+");
var fp = fopen(fileName,mode);
var contentHello = Memory.allocUtf8String(contents);
var ret = fputs(contentHello,fp)
fclose(fp);
}
function EnumerateAllExports(){
/*
var packageName = null
Java.perform(function(){
packageName = Java.use('android.app.ActivityThread').currentApplication().getApplicationContext().getPackageName();
console.log("package name is :",packageName)
})
if(!packageName){
console.log("can`t get package name ,quitting .")
return null;
}
*/
var modules = Process.enumerateModules();
//console.log("Process.enumerateModules => ",JSON.stringify(modules))
for(var i=0;i<modules.length;i++){
var module = modules[i];
var module_name = modules[i].name;
//var exports = module.enumerateExports();
var exports = module.enumerateSymbols();
console.log("module_name=>",module_name," module.enumerateExports = > ",JSON.stringify(exports))
for(var m =0; m<exports.length;m++){
console.log("m=>",m)
//writeSomething("/sdcard/"+packageName+"/"+module_name+".txt", "type:"+exports[m].type+ " name:"+ exports[m].name+" address:"+exports[m].address+"\n")
writeSomething("/sdcard/settings/"+module_name+".txt", "type:"+exports[m].type+ " name:"+ exports[m].name+" address:"+exports[m].address+"\n")
}
}
}
setImmediate(EnumerateAllExports)

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


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


https://github.com/haidragon

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
return-to-libc攻击是一种典型的缓冲区溢出攻击方式,它绕过了内存的数据执行保护机制。在执行return-to-libc攻击时,攻击者通过精心构造的恶意输入,将栈溢出造成的缓冲区溢出利用到无法执行任意代码的情况下。 返回到C库(return-to-libc)是一种利用栈溢出漏洞的攻击技术。正常情况下,当程序发生栈溢出时,攻击者可以将恶意代码注入到程序的内存中并执行。然而,现代操作系统和编译器通常会实施一些保护措施,如地址空间布局随机化(ASLR)和栈不可执行(NX)等,以防止这种攻击。 return-to-libc攻击的基本思想是利用目标程序中的已知函数,如C库函数,来达到执行恶意代码的目的。通过了解函数名称和地址,攻击者可以通过篡改程序的返回地址来使程序跳转到所需的函数。而且,由于这些函数已经在内存中,不在栈上执行,因此可以绕过堆栈溢出和执行保护。 在return-to-libc攻击中,攻击者通过构造恶意输入,覆盖目标程序的返回地址,并将其设置为C库函数的地址,如system()或execve()。这样一来,当程序返回时,不会执行恶意代码,而是跳转到C库函数,攻击者可以使用这些函数来执行所需的操作,如系统命令执行。 然而,现代操作系统通常会实施一些防御措施来阻止return-to-libc攻击,如堆栈保护(stack protector)和地址空间布局随机化(ASLR)。这些措施增加了攻击难度,使得攻击者更难以成功利用return-to-libc攻击。因此,及时更新补丁和使用安全编程实践是防止此类攻击的关键。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C-haidragon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值