安卓逆向-IDA | so层的hook(Frida)

Java层代码是对系统层(so层)的封装,所以假如说APP开发者直接调用系统的接口而不是Java层,有些地方我们hook不出来,所以需要深入去了解so层的接口

在这里插入图片描述

IDA的使用

在这里插入图片描述

按F5可将汇编代码转C

在这里插入图片描述

JNI_OnLoad

在这里插入图片描述

so层的hook接口模块(Frida)

Frida 常用模块API:
.attach(target,callbacks)
 target:指针地址
 callbacks:回调函数
  onEnter
  onLeave
.replace(target,replacement)
 replacement:进行替换的代码内容
  • Module 模块:处理so相关
# 返回exportName的地址指针
.findExportByName(moduleName|null,exportName)
 moduleName:lib里so文件的名字
 exportName:函数名字
 
# 返回lib的基地址
.findBaseAddress(moduleName)
 moduleName:lib名字
  • Process 模块:处理当前线程相关
# 返回一个Module对象
.findModuleByAddress(address)
 address:lib的指针地址
  • Memory 模块:内存操作相关
# 把pointer还原成字符串
.readCString(pointer)
 pointer:指针地址
.readUtf8String(pointer)
.readAnsiString(pointer)
  • 案例
// 假如说hello.so库里有个printhello方法

// 可以找到 hello.so 里的printhello方法的内存地址
var pointer = Module.findExportByName("hello.so", "printhello" )
// 可以得到hello.so的基地址
var base_pointer = Module.findBaseAddress("hello.so")
// 把hello.so还原成对象(返回的model对象有什么属性https://frida.re/docs/javascript-api/#module)
var model = Process.findModuleByAddress(base_pointer)
// 通过target(指针地址)对函数进行hook
Interceptor.attach(target,
    {
    
    
        onEnter: function(args) {
    
    
            //target被调用时进入
            //do something
        },
        onLeave:function(retval){
    
    
            //do something
            //target执行完,退出target前执行
        }
    }
)

// hook libc.so库里的dlopen方法
var mod_address = Module.findExportByName("libc.so","dlopen");
send('mod_address:'+mod_address);
Interceptor.attach(mod_address,
	{
    
    
		onEnter:function(args){
    
    
			// 传入libc.so的dlopen函数的args[0]是文件名,args[1]是属性
			send("open("+Memory.readUtf8String(args[0])+","+args[1]+")");
		}
		onLeave:function(retval){
    
    
			send("retval:"+retval);
		}
});

  • 经常hook的系统库
libc.so 
/ /常调用的函数:
// 加载动态链接库
void * dlopen(const char *filename, int flag)
  • 需要hook程序刚启动时的写法(文件位置:E:\1A爬虫课程 平哥\爬虫课程 平哥\叶森\猿人学-爬虫进阶课\section2-安卓逆向\逆向工具及演示APP\hook自毁程序启动时的dlopen方法.py)
import frida, sys

def on_message(message, data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)

jscode = """
var mod_address = Module.findExportByName("libc.so","dlopen");
send('mod_address:'+mod_address);
Interceptor.attach(mod_address,
	{
		onEnter:function(args){
			// 传入libc.so的dlopen函数的args[0]是文件名,args[1]是属性
			send("open("+Memory.readUtf8String(args[0])+","+args[1]+")");
		},
		onLeave:function(retval){
			send("retval:"+retval);
		}
});
"""
# 定位jar包
device= frida.get_usb_device()
pid = device.spawn(['com.yaotong.crackme'])
process = device.attach(pid)
# 传入上面的js代码创造脚本
script = process.create_script(jscode)
# 接受信息打印信息模块
script.on('message', on_message)
print('[*] Running')
script.load()
# 重启
device.resume(pid)
sys.stdin.read()

猜你喜欢

转载自blog.csdn.net/m0_50685012/article/details/113784660