Android9.0 代码注入,[原创]Android9.0 hook dlopen问题/如何hook dlopen相关函数

本文探讨了在Android9.0中hook dlopen函数时遇到的问题,由于修改LR寄存器导致EGL_ANDROID_blob_cache的错误,从而影响界面绘制。通过分析dlopen的实现和调用栈,确定了问题根源在于__loader_dlopen函数。解决方案包括hook __loader_dlopen以避免修改LR,以及利用合法地址规避命名空间限制。此外,还讨论了不同Android版本的hook策略和绕过私有API限制的方法。
摘要由CSDN通过智能技术生成

Android9.0中在activity的onCreate之前hook dlopen函数,如果需要返回值(即修改了LR寄存器),那么会触发:E/libEGL: EGL_ANDROID_blob_cache advertised, but unable to get eglSetBlobCacheFuncsANDROID。不会crash,但是界面不会绘制出来。

是因为dlopen(libEGL_adreno.so, 2)、dlopen(libGLESv2_adreno.so, 2)返回都是null。理论上其他任何hook框架也都存在这个问题,测试了几个也确实都存在。

dlopen函数实现在libdl.so,

.text:0000000000000EF8 WEAK dlopen

.text:0000000000000EF8 dlopen ; DATA XREF: LOAD:0000000000000508↑o

.text:0000000000000EF8

.text:0000000000000EF8 var_s0 = 0

.text:0000000000000EF8

.text:0000000000000EF8 ; __unwind {

.text:0000000000000EF8 STP X29, X30, [SP,#-0x10+var_s0]!

.text:0000000000000EFC MOV X29, SP

.text:0000000000000F00 MOV X2, X30 ; a3

.text:0000000000000F04 BL .__loader_dlopen

.text:0000000000000F08 LDP X29, X30, [SP+var_s0],#0x10

.text:0000000000000F0C RET

.text:0000000000000F0C ; } // starts at EF8

.text:0000000000000F0C ; End of function dlopen

这里把LR寄存器当作第三个参数传递给.__loader_dlopen,而我们hook时为了能拿到返回值是修改了LR寄存器的,这是不可避免的。如果不修改LR寄存器,除非我们知道函数结尾,在函数结尾修改LR寄存器或者跳到shellcode/hook函数,但是通常是不现实的,函数开头容易确认,函数结尾很难自动化确认。

// Proxy calls to bionic loader

__attribute__((__weak__))

void* dlopen(const char* filename, int flag) {

const void* caller_addr = __builtin_return_address(0);

return __loader_dlopen(filename, flag, caller_addr);

}

__builtin_return_address函数应该是gcc内部函数,0获取的是被调用函数返回后执行的指令地址,至于1之后的数字是否能获取到函数调用栈待测试。已测试:

1、0获取的就是进入函LR寄存器的值。

2、1获取的是r7(thumb)/r12(arm),即ip寄存器的值,所以能不能获取到正确的值取决于上层是否使用了ip寄存器暂存sp,且ip寄存器之后(栈上)就是在栈上存储的LR寄存器的值。所以不满足这些条件的函数是获取不到的甚至是错误的。

爷爷函数:

.text:0000C250 ; __unwind {

.text:0000C250 PUSH {R4,R5,R7,LR}

.text:0000C252 ADD R7, SP, #8

...

.text:0000C292 BLX j__Z12test_replacev ;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值