c-在用户空间中加载一个不可重定位的静态ELF二进制文件



我正在尝试编写一个基本的用户空间ELF加载程序,该加载程序应该能够加载静态链接(而不是动态链接)的不可重定位二进制文件(即,不使用-pie、-fPIE等构建)。目前,它应该可以在x86 CPU上工作。

我已经遵循了在用户空间中用C加载ELF文件的代码,当可执行文件是可重定位的时,它工作得很好,但正如预期的那样,如果不是,它会完全失败,因为程序加载在错误的虚拟内存范围中,并立即崩溃。

但我试图修改它,以在它期望的虚拟偏移量加载程序(使用phdr.p_vaddr),但我遇到了一个复杂的问题:我的加载程序已经在使用那个虚拟内存范围了!我无法对其进行mmap,更不用说向其中写入任何内容了。我如何继续操作,以便在加载程序完成之前将不可重定位的二进制文件加载到加载程序的地址空间,而不会覆盖加载程序自己的代码?我是否需要让我的加载程序从一个完全不同的虚拟内存范围运行,也许是通过让链接器将其链接到不可重定位二进制文件的通常虚拟内存范围之上(在我的情况下,它恰好从0x400000开始),或者它有什么诀窍吗?

我已经阅读了ELF文档(顺便说一句,我在这里使用ELF64,但我认为ELF32和ELF64非常相似)和网上的许多文档,但我仍然不明白

有人能解释一下ELF加载程序是如何处理这种特殊的复杂性的吗?谢谢

阿基米德发现在一个位置只能有一个物体时,他称之为"heureka"。如果你的ELF二进制文件必须在一个位置,因为你不能为另一个位置重建它,你必须重新定位加载程序本身。

不可重定位的ELF没有包含足够的信息来将其移动到其他地址。你可能会编写一个反编译器来检测代码中的所有地址引用,但这并不值得。当您试图分析数据引用(如存储在预初始化变量中的指针)时,会遇到问题。

如果无法获得ELF二进制或可重定位版本的源代码,请重写加载程序。

顺便说一句:阿基米德对作弊的金匠来说是致命的。我希望对你来说没那么贵。

最新更新