前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >腾讯Matrix分析--ELFHook原理

腾讯Matrix分析--ELFHook原理

作者头像
None_Ling
发布2019-04-09 17:50:11
2.1K0
发布2019-04-09 17:50:11
举报
文章被收录于专栏:Android相关

背景

在Matrix发布后,可以检查文件是否存在泄漏的问题,处于好奇,了解一下原理

原理

通过Hook系统在本进程中的openclosereadwrite这些系统函数,来了解打开的文件以及其是否被释放。由于只是Hook本App的系统调用,所以不需要Root权限也可以完成。

方案

  1. 由于要Hook的函数在libopenjdkjvm.solibjavacore.solibopenjdk.so三个so中,所以需要分别注入这些So文件
  2. 使用自定义的函数替换系统So中的函数地址

寻找So的基址

  1. 获取本进程对应的So的基址,通过\proc\self\maps获取So对应的位置
    • 调用fopen传入文件路径以及rb来打开maps文件,b模式代表读取二进制(binary)
    • 调用fgets函数,读取\proc\self\maps的每一行
    • 调用strchr函数,找到-出现的第一个位置
    • 通过地址的计算,得到该内存页面的访问权限rwx
    • 判断是否为rx,如果不是的话,则越过该页面继续查找
    • 通过strstr函数,比较该So的路径是否在maps的这一行中
    • 如果存在于该行,则通过strtoul将该行的首地址根据16进制转换成虚拟地址
  2. 获取到So的基址之后,获取该ELF文件的相关信息
    • 通过一个数据结构loaded_soinfo来保存已经打开的ELF文件信息
    • 通过上面找到的So的基址,将So的名字与基址保存到loaded_soinfo
    • 将So的基址地址赋值给Elf_Addr对象,该数据结构代表占用4字节的地址,属性为soinfo->base
    • 将So的基址地址赋值给Elf_Ehdr对象,该数据结构代表ELF文件的文件头,里面包含着程序头、Section节表的信息
    • 验证ELF文件的Magic Number,包括0x7fELF,大小端排序、So文件类型等
    • 根据ELF文件头的e_phoffe_shoff找到ELF文件中的程序头与节头的地址
  3. 填充剩下的ELF信息
    • 根据soinfo->phdrsoinfo->ehdr->phnum找到Elf32_Phdr的范围,也就是程序头表的范围
    • 遍历程序头表中的所有Segment的Type,计算类型为PT_LOAD的Segment的偏移量以及Flag
    • 找到类型为DYNAMIC的Segment,计算dynamic segment的地址,以及数量
    • 遍历DYNAMIC段中的所有Elf_Dyn,然后根据dyn->d_un.d_val是否为DT_RELA来表示该So是否使用了重定向表
    • 遍历所有Elf_Dyn数据结构中的d_tag,来判断该Entity是哪种类型的,例如SYSTABRELSTRTABHASH等等

DYNAMIC段中保存的是Elf_Dyn的数组,所以可以根据p->vaddr+p_memsz得到DYNAMIC段的总大小,再除以sizeof(Elf_Dyn),就能得到Elf_Dyn的总数了

替换So中的函数

首先,需要定位函数名的符号地址,再替换rel段中的函数地址

符号地址的定位

符号地址的定位有两种方式,通过Hash表查找,或者通过线性比较查找

  1. 通过Hash表查找:
    • 计算函数名的Hash值
    • 在Hash表中根据name_hash%nbucket得到函数名对应的符号链,ELF文件也是通过链式方法来解决hash冲突的
    • 判断Elf_Sym的类型是否为STT_FUNCTION,如果不是则继续
    • 比较Elf_Symsys_name与函数名是否匹配,如果匹配则代表找到了函数对应的Elf_Sym结构
  2. 线性查找
    • soinfo->sym开始遍历
    • 判断Elf_Sym的类型是否为STT_FUNCTION,如果是的话,则比较名字

替换REL段

在找到目标函数的符号(对应的Elf_Sym)之后,需要开始替换

  1. 根据之前找到的REL/RELA表进行遍历
  2. 根据Elf_Rel/Elf_Rela结构中的r_info来获取函数的Index
  3. 比较从Elf_Sym相同的Index,如果相同则认为找到了目标函数在重定向表中的位置
  4. 判断目标内存页面的内存是否可写,如果不可写,调用mprotect修改目标页面的权限
  5. 将目标位置的函数地址进行替换
  6. 修改回目标页面的访问权限

至此So的Hook完成,目标函数也替换完成

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.04.01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 原理
  • 方案
  • 寻找So的基址
  • 替换So中的函数
    • 符号地址的定位
    • 替换REL段
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档