ELF文件的native hook:ELF的运行时状态

💡 原文中文,约9600字,阅读约需23分钟。
📝

内容提要

本文介绍了ELF文件结构和虚拟内存概念,包括虚拟地址映射到物理地址的页映射,共享库的虚拟内存共享,以及导出符号的重定位和hook实现。同时介绍了dl_iterate_phdr函数查询共享库分布情况。

🔎

延伸解读

虚拟内存:安全与抽象的基石

文章指出,虚拟内存为每个进程提供独立的地址空间,防止程序间恶意篡改,同时抽象了物理内存和磁盘的差异。32位系统最大寻址4GB,通过分页映射减少页表开销。理解这一点是分析运行时ELF状态的前提,因为hook操作发生在虚拟地址空间,而非磁盘文件。

共享库的内存共享与隔离机制

多个进程可共享同一动态库的只读段,节省物理内存;但可写段通过写时复制(copy-on-write)为每个进程维护独立副本,避免相互干扰。这解释了为何修改共享库数据不会影响其他进程,也为hook时替换函数地址而不破坏其他程序提供了基础。

重定位与hook的实现原理

程序运行时,动态链接器将共享库的导出符号地址写入调用方的GOT/PLT表。native hook通过替换重定位地址,将目标函数指向自定义函数。由于各ELF文件(主程序、共享库)的GOT表独立,修改一个库中的调用不会影响其他库,这保证了hook的局部性和安全性。

运行时地址查询:dl_iterate_phdr

文章演示了使用dl_iterate_phdr遍历已加载共享库,获取每个库的基地址和段信息。例如libc.so加载在0x7f5f7b200000,结合ELF文件中的偏移,可计算出函数在运行时的真实地址。这是实现hook的关键步骤,确保能准确定位并修改目标地址。

❓

Q&A

什么是ELF文件的native hook?

ELF文件的native hook是通过替换重定位地址来实现的,可以在不影响其他程序的情况下进行函数的钩取。

虚拟内存的作用是什么?

虚拟内存为每个程序提供独立的内存空间,防止程序间的数据相互干扰,提高安全性。

如何实现多个进程共享动态链接库?

多个进程通过虚拟内存空间共享动态链接库,操作系统在内存中只保留一份库的副本,并为每个进程建立虚拟地址与物理地址的映射关系。

ELF文件中的导入符号和导出符号有什么区别?

导入符号是ELF文件中引入的外部符号,而导出符号是ELF内部定义的符号,可以被外部使用。

如何使用dl_iterate_phdr函数?

dl_iterate_phdr函数用于查询运行时的共享库分布情况,可以获取每个共享库的名称和基地址等信息。

写时赋值技术如何实现数据隔离?

写时赋值技术在进程尝试修改共享库的可读写段时,会复制该段数据到新的物理内存区域,从而实现数据的隔离。

🏷️

标签

➡️

继续阅读