1

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

我已经按照在用户空间中将 ELF 文件加载到 C 中的代码进行了操作,并且当可执行文件可重定位时它运行良好,但如果不是因为程序加载到错误的虚拟内存范围并立即崩溃,则正如预期的那样完全失败。

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

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

有人能解释一下 ELF 加载器如何处理这种特殊的并发症吗?谢谢!

4

1 回答 1

3

当阿基米德发现在一个位置只能是一个物体时,他称之为“heureka”。如果您的 ELF 二进制文件必须位于一个位置,因为您无法将其重建到另一个位置,则您必须重新定位加载程序本身。

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

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

顺便说一句:Archimedes heureka 对于作弊的金匠来说是致命的。我希望在你的情况下它不是那么贵。

于 2015-04-17T05:05:27.747 回答