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

时间:2015-04-17 03:08:46

标签: c elf userland

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

我已经遵循了loading ELF file in C in user space上的代码,并且当可执行文件可重定位时它运行良好,但如果不是因为程序加载到错误的虚拟内存范围并且立即崩溃,则预期完全失败。

但我尝试修改它以在预期的虚拟偏移量下加载程序(使用phdr.p_vaddr)但是我遇到了一个复杂问题:我的加载器已经在使用该虚拟内存范围了!我无法mmap它,更不用说写任何东西了。我如何继续这样我可以将我的不可重定位二进制文​​件加载到我的加载器的地址空间中,而不会在加载器自己的代码完成之前覆盖它?我是否需要让我的加载程序从完全不同的虚拟内存范围运行,可能是通过让链接器将其链接到通常的虚拟内存范围之上,以获得不可重定位的二进制文件(在我的情况下恰好从0x400000开始)或它有一些技巧吗?

我已经阅读了ELF文档(我在这里使用的是ELF64,但我认为ELF32和ELF64非常相似)和网上的很多文档,我仍然没有得到它。

有人可以解释ELF加载器如何处理这种特殊的复杂情况吗?谢谢!

1 个答案:

答案 0 :(得分:2)

当他发现在一个地方只能是一个物体时,

Archimedes称为“heureka”。如果您的ELF二进制文件必须位于一个位置,因为您无法将其重建为另一个位置,则必须重新定位加载器本身。

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

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

顺便说一句:阿基米德·海瑞卡对于作弊的金匠来说是致命的。我希望你的情况不会那么贵。