背景
在Matrix发布后,可以检查文件是否存在泄漏的问题,处于好奇,了解一下原理
原理
通过Hook系统在本进程中的open
和close
、read
、write
这些系统函数,来了解打开的文件以及其是否被释放。由于只是Hook本App的系统调用,所以不需要Root权限也可以完成。
方案
- 由于要Hook的函数在
libopenjdkjvm.so
、libjavacore.so
、libopenjdk.so
三个so中,所以需要分别注入这些So文件 - 使用自定义的函数替换系统So中的函数地址
寻找So的基址
- 获取本进程对应的So的基址,通过
procselfmaps
获取So对应的位置- 调用
fopen
传入文件路径以及rb
来打开maps
文件,b
模式代表读取二进制(binary) - 调用
fgets
函数,读取procselfmaps
的每一行 - 调用
strchr
函数,找到-
出现的第一个位置 - 通过地址的计算,得到该内存页面的访问权限
rwx
- 判断是否为
rx
,如果不是的话,则越过该页面继续查找 - 通过
strstr
函数,比较该So的路径是否在maps
的这一行中 - 如果存在于该行,则通过
strtoul
将该行的首地址根据16进制转换成虚拟地址
- 调用
- 获取到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_phoff
与e_shoff
找到ELF文件中的程序头与节头的地址
- 通过一个数据结构
- 填充剩下的ELF信息
- 根据
soinfo->phdr
与soinfo->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是哪种类型的,例如SYSTAB
,REL
,STRTAB
,HASH
等等
- 根据
DYNAMIC
段中保存的是Elf_Dyn
的数组,所以可以根据p->vaddr
+p_memsz
得到DYNAMIC
段的总大小,再除以sizeof(Elf_Dyn)
,就能得到Elf_Dyn
的总数了
替换So中的函数
首先,需要定位函数名的符号地址,再替换rel
段中的函数地址
符号地址的定位
符号地址的定位有两种方式,通过Hash表查找,或者通过线性比较查找
- 通过Hash表查找:
- 计算函数名的Hash值
- 在Hash表中根据
name_hash%nbucket
得到函数名对应的符号链,ELF文件也是通过链式方法来解决hash冲突的 - 判断
Elf_Sym
的类型是否为STT_FUNCTION
,如果不是则继续 - 比较
Elf_Sym
的sys_name
与函数名是否匹配,如果匹配则代表找到了函数对应的Elf_Sym
结构
- 线性查找
- 从
soinfo->sym
开始遍历 - 判断
Elf_Sym
的类型是否为STT_FUNCTION
,如果是的话,则比较名字
- 从
替换REL段
在找到目标函数的符号(对应的Elf_Sym
)之后,需要开始替换
- 根据之前找到的
REL
/RELA
表进行遍历 - 根据
Elf_Rel
/Elf_Rela
结构中的r_info
来获取函数的Index - 比较从
Elf_Sym
相同的Index,如果相同则认为找到了目标函数在重定向表中的位置 - 判断目标内存页面的内存是否可写,如果不可写,调用
mprotect
修改目标页面的权限 - 将目标位置的函数地址进行替换
- 修改回目标页面的访问权限
至此So的Hook完成,目标函数也替换完成
文章来源于互联网:腾讯Matrix分析–ELFHook原理
阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/16929,转载请注明出处。
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/16929,转载请注明出处。
评论0