如果我知道.plt的sh_addr,是否可以计算出.plt段将被加载到的内存中的虚拟地址?我需要添加什么基址才能到达该地址?
编辑5一月2024
很抱歉造成了混乱,让我解释一下我正在解决的问题。
如果某些代码可以篡改进程内存中加载的共享库的PLT或GOT(执行挂钩),我们如何检测它?我在想,是否可以通过解析内存中的ELF文件来找到共享库的PLT或GOT。
然而,我读到的文章是关于解析磁盘上的ELF文件的,所以我想知道我是否能够解析磁盘上的ELF文件并找到PLT或GOT部分的sh_addr,然后我是否可以使用sh_addr中的值添加到内存中的基址并在内存中找到PLT或GOT。
从那里我想检查PLT中的操作码,看看它们是否被修改过。如果是GOT,那么我想检查地址,看看它是否会导致未知库中的某个函数。
至于为什么我认为共享库的PLT或GOT有代码篡改,我没有答案。我实际上正在试图找出是否确实如此或排除这种可能性。
1条答案
按热度按时间oprakyz71#
如果我知道. plt的sh_addr,是否可以计算.plt节将被加载的内存中的虚拟地址?
是的,您甚至不需要
sh_addr
--查找.plt
和.got
所需的所有结构都已经在内存中,您不需要解析磁盘上的任何内容。首先通过调用
dlopen(RTLD_DEFAULT, RTLD_LAZY)
在内存中定位struct link_map *map
。map
为您提供加载到内存中的所有ELF图像的链接列表,并通过.l_ld
条目访问每个图像的动态部分。在每个动态部分中,您需要找到带有
.d_tag == DT_PLTGOT
的条目,然后使用this answer来遍历.got.plt
条目。但是请注意,如果您的进程已被篡改,则加载程序在内存中的结构也可能已损坏,并且您可能会在尝试访问它们时崩溃。
如果某些代码可以篡改进程内存中加载的共享库的PLT或GOT(执行挂钩),我们如何检测它?
最好的方法是使用
-Wl,-z,now,-z,relro
标志链接二进制文件。这些标志要求运行时加载器在加载时解析所有.plt
引用,并在加载后使用mprotect
将.got
设置为只读。这使得在程序启动后劫持
.got
条目变得更加困难(尽管并非不可能)。