将静态链接的elf二进制文件转换为动态链接

时间:2012-12-20 16:41:18

标签: c linux elf openonload

我有一个静态链接到libc的elf二进制文件。 我无法访问其C代码。 我想使用OpenOnload库,它在用户空间中实现套接字,因此与标准libc版本相比提供更低的延迟。 OpenOnload实现标准套接字api,并使用LD_PRELOAD覆盖libc版本。 但是,由于此elf二进制文件是静态链接的,因此无法使用套接字API的OpenOnload版本。

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

  1. 添加新的程序标题:PT_INTERP,PT_DYNAMIC和PT_LOAD。
  2. 在PT_DYNAMIC中添加条目以列出与libc的依赖关系。
  3. 在新的PT_LOAD部分中为所需的libc函数添加PLT存根。
  4. 修改libc函数的现有二进制代码以跳转到相应的PLT存根。
  5. 作为第一次剪辑,我尝试添加3个PT_LOAD段。在现有PT_LOAD段标头之后添加了新的段标头。此外,未修改现有段的vm_addr。基于p_align,现有段的文件偏移量被下移到下一个对齐的地址。 新的PT_LOAD段已添加到文件末尾的文件中。

    重新编写文件后,当我运行它时,它被内核正确加载,但随后立即发生了故障。

    我的问题是:

    1. 如果我只是在elf二进制文件中移动文件偏移量而不修改vm_addresses,那么在运行二进制文件时是否会导致任何错误?
    2. 我可以做我正在尝试的事情吗?有人试过吗?

1 个答案:

答案 0 :(得分:5)

您尝试的内容无法以任何自动方式进行。在静态链接时,所有重定位信息都将解析并删除标识对libc的调用作为对libc的调用。如果二进制文件中存在调试符号,则可以识别“文本段中的这个字节范围对应于这样的libc函数”,但是没有办法识别引用到函数中,它将嵌入指令字节流中,没有标记来识别它们。您可以使用基于反汇编的启发式方法,但它们不完整且不可靠(可能存在漏报和误报)。

就转移偏移而言,绝对无法改变静态链接二进制文件的加载地址。如果需要在加载段之前插入标题,则必须插入整个页面,并在程序标题表中更新文件偏移量(向它们添加1页),同时保持虚拟地址加载偏移量相同。但是,由于您要做的事情总体上是不可能的,因此抵消转移问题是您最不担心的问题。

也许,如果程序不需要高性能,你可以在qemu app-level仿真下运行它,qemu通过套接字仿真/包装器。