linux 使用sh_addr计算PLT的虚拟地址

zbdgwd5y  于 2024-01-06  发布在  Linux
关注(0)|答案(1)|浏览(98)

如果我知道.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有代码篡改,我没有答案。我实际上正在试图找出是否确实如此或排除这种可能性。

oprakyz7

oprakyz71#

如果我知道. plt的sh_addr,是否可以计算.plt节将被加载的内存中的虚拟地址?
是的,您甚至不需要sh_addr--查找.plt.got所需的所有结构都已经在内存中,您不需要解析磁盘上的任何内容。
首先通过调用dlopen(RTLD_DEFAULT, RTLD_LAZY)在内存中定位struct link_map *mapmap为您提供加载到内存中的所有ELF图像的链接列表,并通过.l_ld条目访问每个图像的动态部分。
在每个动态部分中,您需要找到带有.d_tag == DT_PLTGOT的条目,然后使用this answer来遍历.got.plt条目。
但是请注意,如果您的进程已被篡改,则加载程序在内存中的结构也可能已损坏,并且您可能会在尝试访问它们时崩溃。
如果某些代码可以篡改进程内存中加载的共享库的PLT或GOT(执行挂钩),我们如何检测它?
最好的方法是使用-Wl,-z,now,-z,relro标志链接二进制文件。这些标志要求运行时加载器在加载时解析所有.plt引用,并在加载后使用mprotect.got设置为只读。
这使得在程序启动后劫持.got条目变得更加困难(尽管并非不可能)。

相关问题