安卓运行原理以及hook so库,hook启动阶段和重载

1.原理

在这里插入图片描述

2.常用模块

hook so库

Module模块

Module.findExportByName(moduleName|null, exportName)
	moduleName:lib名字
	exportName:函数名字
	返回exportName的地址
Module.findBaseAddress(moduleName)
	moduleName:lib名字
	返回lib的基地址

Process模块

Process.findModuleByAddress(address)
	address:lib的指针地址
	返回一个Module对象

Momery模块

Memory.readCString(pointer)
	pointer:指针地址
	把pointer还原成字符串
Memory.readUtf8String(pointer);
Memory.readAnsiString(pointer)

Interceptor模块:监听

.attach(target, callbacks)
	target:指针地址
	callbacks:回调函数
		onEnter
		onLeave

Hook的系统so

libc.so常调用的函数:

void * dlopen(const char *filename, int flag)加载动态链接库

hook app启动阶段

思路是先hook住包,然后重启

jscode= """
Java.perform(
	function(){
		var TestSig = Java.use('com.yaotong.crackme.MainActivity');
		TestSig.onCreate.overload('android.os.Bundle').implementation = function(){
			send('i am here')
			return true;
		}
	}
)

"""
device = frida.get_usb_device()
//先hook住
pid = device.spawn(['com.yaotong.crackme'])
process = device.attach(pid)

script = process.create_script(jscode)
script.on('message', on_message)
print('[*] Running CTF')
script.load()
、、 然后重启
device.resume(pid)
sys.stdin.read()

打印地址js代码

//打印基地址
var base_address = Module.findBaseAddress('libc.so')
send('base_address:'+base_address)
//打印dlopen地址
var mod_address = Module.findExportByName('libc.so', 'dlopen');
send('mod_address:'+ mod_address);
//打印module地址
var lib_module = Process.findModuleByAddress(base_address);
send('lib_module_name:' + lib_module.name)
//监听
Interceptor.attach(mod_address, {
	onEnter: function(args){
		send("open(" + Memory.readUtf8String(args[0]) + "," + args[1] + ")")
	},
	onLeave:function(retval){
		send("retval:" + retval)
	}
})

如何进行重载

function printstack(){
	send(Java.use('android.util.Log').getStackString(Java.use('java.lang.Exception').$new()))
}
function array2string(array){
	var buffer = Java.array('byte', array)
	var result = ""
	for(var i=0;i<buffer.length;i++){
		result += (String.fromCharCode(buffer[i]))
	}
	return result
}

Java.perform(
	function(){
		var MessageDigest = Java.use('java.security.MessageDigest');
		//重载
		MessageDigest.update.overload('[B').implementation = function(bytesarray){
			send('i am here 0')
			send('orig:' + array2string(bytesarray))
			printstack()
			this.update(bytesarray)
		},
		MessageDigest.update.overload('byte').implementation = function(bytesarray){
			send('i am here 1')
			send('orig:' + array2string(bytesarray))
			printstack()
			this.update(bytesarray)
		},
		MessageDigest.update.overload('java.nio.ByteBuffer').implementation = function(bytesarray){
			send('i am here 2')
			send('orig:' + array2string(bytesarray))
			printstack()
			this.update(bytesarray)
		},
		MessageDigest.update.overload('[B', 'int', 'int').implementation = function(bytesarray){
			send('i am here 3')
			send('orig:' + array2string(bytesarray))
			printstack()
			this.update(bytesarray)
		},
		MessageDigest.getInstance.overloads[0].implementation = function(algorithm){
			send('i am here 4');
			send('call ->getInstance for:' + algorithm)
			return this.getInstance.overloads[0].apply(this, arguments)
		}
	}
)

getExportByName: 返回名为 exportName 的导出的绝对地址。 如果找不到这样的导出,找不到抛出异常

findExportByName: 返回名为 exportName 的导出的绝对地址。 如果找不到这样的导出,找不到就返回null

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
运行hook 动态是一种动态修改程序运行过程中函数行为的技术。在运行时,动态通过修改函数的代码或者替换函数的入口地址来改变函数的行为。这在许多场景中非常有用,比如在调试程序、分析程序行为或者实现动态插桩等方面。 要实现运行hook 动态,一般需要以下步骤: 1. 加载目标程序和目标函数所在的动态。可以使用诸如`dlopen()`函数之类的函数来加载动态,并使用`dlsym()`函数获取目标函数的地址。 2. 修改目标函数的代码或者替换函数的入口地址。可以通过修改函数的二进制代码来实现,也可以通过将目标函数的入口地址替换为自定义的函数地址来完成。这样,在程序执行到目标函数时,将会跳转到我们自己的代码中执行。 3. 编写自定义的代码来替代目标函数的行为。自定义的代码可以实现各种功能,比如记录函数调用信息、修改函数参数或返回值等。 4. 执行目标程序。当目标程序执行到目标函数时,会跳转到自定义的代码中执行。我们可以在自定义的代码中改变函数的行为,或者在执行完自定义代码后再调用原始的目标函数来实现原功能。 总之,运行hook 动态是一种强大的技术,可以在不修改目标程序源代码的情况下改变程序的行为。通过加载目标程序和动态,并修改目标函数的代码或替换入口地址,可以实现自定义的功能。这为调试、分析和插桩等应用场景提供了很大的便利。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值