关于Android x86平台 函数hook知识的一点记录

对x86平台更熟悉一些,所以就写一下x86的吧,至于arm平台,只是寄存器有些不同,其他的思路应该还是差不多的。其实主要是对了解的知识做一下记录,方便以后翻出来看看 Linux系统的注入一般是使用ptrace函数,对指定进程使用ptrace,可以暂停进程,并可以读/写目标进程指定内存/寄存器,整个注入的流程其实很简单,假设我们要替换运行进程P中的某个函数调用M_org,大致的思路如
摘要由CSDN通过智能技术生成

对x86平台更熟悉一些,所以就写一下x86的吧,至于arm平台,只是寄存器有些不同,其他的思路应该还是差不多的。

其实主要是对了解的知识做一下记录,方便以后翻出来看看

 

Linux函数hook一般是使用ptrace函数,对指定进程使用ptrace,可以暂停进程,并可以读/写目标进程指定内存/寄存器,整个hook的流程其实很简单,

假设我们要替换运行进程P中的某个函数调用M_org,大致的思路如下:

1,生成一个动态库libInject.so,里面包含了用来替换M_org的函数M_replace;另外还有一个hook_work函数用来做替换操作;

2,获得目标进程P的进程号tPid;

3,分别获得加载到目标进程P中的dlopen,dlsym,dlclose,dlerror函数地址;

4,通过上一步获得的目标进程dlopen函数地址,在目标进程里加载libInject.so,并取得返回的so句柄;

5,调用dlsym获得目标进程中hook_work函数(刚才已经加载libInject.so了,这个函数位于这个模块里)地址,并调用它;

hook_work主要做以下工作:

w1,通过解析包含M_org函数的动态库,假设叫libM.so(如果这个函数直接位于目标程序里,则解析目标binary文件),找到libM.so在被加载模块中对应的GOT表相对于libM.so被加载位置偏移量;

w2,获得libM.so在目标进程P中加载位置,再加上一步获得的GOT偏移量,可获得libM.so的GOT表在目标进程中的地址;

w3,获得M_org的地址,并遍历第w2步获得的GOT表项,如果有一项对应的地址和M_org地址相同,则将这个表项里的地址替换成M_replace函数地址

 

整个步骤完成之后,以后每次调用M_org函数时,在GOT表项里找到的实际是M_replace函数地址,也就是说实际执行的是M_replace函数!

注意android的链接加载器和linux的链接加载器稍微有点不同,而正是这点不同之处可以使得w1~w3能正常工作:

标准Linux链接器是ld.so,支持Lazy绑定,引用模块A在真正开始调用被应用模块B中符号时,才将该符号地址写到A中于B对应的GOT表项中,也就是说,模块A在编译期间生成的调用模块B的原始代码,流程是从调用代码到PLT表到链接器。运行期第一次调模块乙时,首先进入链接器,链接器根据调用信息加载模块B搜寻其符号并将找到的函数地址填入GOT表,之后的后续调用流程就直接走PLT/GOT表了。这种机制能减少加载时的开销。

Android虽然内核基于Linux,但其动态链接机制却不是ld.so而是自带的linker,不支持Lazy绑定。也就是说,上述模块AB如果在Android平台上,则是模块A加载时,linker就会根据模块A中的.rel.plt表和字符串表中的内容加载模块B并搜索其所需

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值