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

标签 c elf userland

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

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

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

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

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

最佳答案

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

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

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

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

关于c - 在用户空间加载不可重定位的静态 ELF 二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29689558/

相关文章:

[NSURLConnection sendSynchronousRequest] 回调后无法访问 NString

compiler-construction - ELF文件中的“节到段映射”存储在哪里?

c - 实现用户级线程库启动一个新线程[作业]

Linux 用户态执行

c++ - 是否可以使用代码块从文件运行一些案例测试而不使用文件函数

c - 通过 C 调用进入 Visual Studio 调试器

c - 指针加法检查

c - 函数 "main"的代码在目标文件中的哪里开始?

shared-libraries - Linux ELF 文件 : How to get the shared object belonging to an imported function