将一个静态链接的ELF二进制文件转换为动态链接

11

我有一个 ELF 二进制文件,已经静态链接到 libc 库。我无法访问它的 C 代码。我想使用 OpenOnload 库,它在用户空间中实现了套接字,因此与标准 libc 版本相比提供了更低的延迟。

OpenOnload 实现了标准的套接字 API,并使用 LD_PRELOAD 覆盖了 libc 版本。但是,由于这个 ELF 二进制文件是静态链接的,它不能使用 OpenOnload 版本的套接字 API。

我认为可以通过以下步骤将该二进制文件转换为与 OpenOnload 动态链接:

  1. 添加新的程序头:PT_INTERP、PT_DYNAMIC 和 PT_LOAD。
  2. 在 PT_DYNAMIC 中添加条目以列出与 libc 的依赖项。
  3. 在新的 PT_LOAD 部分中添加所需 libc 函数的 PLT 存根。
  4. 修改现有 libc 函数的二进制代码,使其跳转到相应的 PLT 存根。

首先,我尝试只添加三个 PT_LOAD 段。新段头被添加在现有的 PT_LOAD 段头之后。现有段的 vm_addr 没有被修改。现有段的文件偏移量根据 p_align 在下一个对齐地址下方进行了偏移。新的 PT_LOAD 段被添加到文件的末尾。

在重写文件后,当我运行它时,内核成功加载了它,但它立即崩溃了。

我的问题是:

  1. 如果我只是移动 ELF 二进制文件中的文件偏移量而不修改 vm_addresses,会在运行二进制文件时引发任何错误吗?
  2. 我正在尝试的事情是否可能实现?有人尝试过吗?

5
理论上这是可行的,但我认为你几乎肯定会遇到无限数量的漏洞 - 你甚至还没有遇到的最大问题是,glibc希望在任何给定的地址空间中只有一个自身的副本,如果这个期望被违反,重要的东西(如malloc)将会不可预测地崩溃。你可能最好运行整个二进制文件通过一个反汇编器,手动修剪掉所有的libc代码,然后重新组装和链接它。 - zwol
我可能只会为该库编写一个薄包装器。 - Jari Komppa
我同意Zack的观点。你会花费不合理的时间去做这件事,而且它可能不会像你想象的那样好(细节决定成败)。所以不要这么做! - Basile Starynkevitch
Zack,glibc是否希望只加载一份副本或仅使用一份副本?我的意思是,如果我将所有对静态链接的glibc函数的调用重定向到动态加载的函数中,它可以正常工作吗? - javed
Zack,你能详细解释一下反汇编器吗?我应该怎么做呢?我的意思是在Linux上我可以使用哪个反汇编器? - javed
请原谅我的好奇心,您是在尝试通过NSE来加速TAP吗? - Achintya Sharma
2个回答

5
你所尝试的自动化方式是不可能实现的。在静态链接时,所有识别libc函数调用的重定位信息都已被解析和删除。如果二进制文件中存在调试符号,则可以确定“文本段中这些字节对应于某个libc函数”,但无法确定函数的引用,因为它们嵌入到指令字节流中而没有标记进行标识。你可以使用基于反汇编的启发式算法,但它们将是不完整和不可靠的(可能会出现假阴性和假阳性)。
至于偏移量的移动,你绝对不能更改静态链接二进制文件的任何加载地址。如果你需要在加载段之前插入头文件,你需要插入一个完整的页面,并更新程序头表中的文件偏移量(添加1页),同时保持虚拟地址加载偏移量不变。然而,由于你所尝试的内容总体上是不可能的,偏移量移动问题是你最不用担心的。
也许,如果该程序不要求高性能,你可以在qemu应用级仿真下运行它,qemu通过套接字仿真/包装器进行操作。

1
如果二进制文件中存在调试符号,在Linux上您不需要调试符号,只需要普通符号就足够了。"没有标记来识别它们"。我不认为这是正确的。如果二进制文件没有被剥离,objdump -d将显示CALL socketCALL accept等内容。 - Employed Russian
1
那仍然需要反汇编。正在发生的是,在反汇编过程中,objdump看到了call指令,然后查找目标地址以查看它是否与符号匹配。然而,并没有与call指令的地址相关联的标记来标识它。 - R.. GitHub STOP HELPING ICE
好的,二进制文件确实有符号。就像你所描述的,objdump也能够显示调用libc函数的位置,因此我可以手动重定向这个调用到其他地方(手动添加PLT条目)。 - javed
我不确定qemu的工作原理,但由于目标是实现低延迟,再添加一层抽象只会增加延迟,所以我认为这并没有帮助。 - javed
针对实验,我已经将文件偏移量移动了一个页面大小(4096),但生成的二进制文件却出现了segmentation fault错误,而我无法理解为什么会出错? - javed
你是否在页眉和程序之间插入了额外的页面? - R.. GitHub STOP HELPING ICE

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接