将静态链接的elf二进制文件转换为动态链接的 [英] Convert a statically linked elf binary to dynamically linked

查看:107
本文介绍了将静态链接的elf二进制文件转换为动态链接的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a elf binary which has been statically linked to libc. I do not have access to its C code. I would like to use OpenOnload library, which has implementation of sockets in user-space and therefore provides lower latency compared to standard libc versions. OpenOnload implements standard socket api, and overrides libc version using LD_PRELOAD. But, since this elf binary is statically linked, it cannot use the OpenOnload version of the socket API.

我相信将其转换为动态链接可以通过以下步骤进行OpenOnload:

I believe that converting this binary to dynamically link with OpenOnload is possible, with the following steps:


  1. 添加新程序头:PT_INTERP,PT_DYNAMIC和PT_LOAD。

  2. 在PT_DYNAMIC中添加条目以列出与libc的依赖关系。

  3. 在新的PT_LOAD部分中为所需的libc函数添加PLT存根。

  4. 修改现有的libc函数的二进制代码跳转到相应的PLT存根。

  1. Add new Program headers: PT_INTERP, PT_DYNAMIC and PT_LOAD.
  2. Add entries in PT_DYNAMIC to list dependency with libc.
  3. Add PLT stubs for required libc functions in the new PT_LOAD section.
  4. Modify existing binary code for libc functions to jump to corresponding PLT stubs.

首先,我尝试仅添加3个PT_LOAD段。在现有的PT_LOAD段头之后添加新的段头。此外,现有段的vm_addr未被修改。现有段的文件偏移量根据p_align移至下一个对齐的地址。
在文件末尾的文件中添加了新的PT_LOAD段。

As a first cut, I tried just adding 3 PT_LOAD segments. New segment headers were added after existing PT_LOAD segment headers. Also, vm_addr of existing segments was not modified. File offsets of existing segments were shifted below to next aligned address based on p_align. New PT_LOAD segments were added in the file at end of the file.

重写文件后,当我运行该文件时,

After re-writing the file, when I ran it, it was loaded properly by the kernel, but then it immediately seg-faulted.

我的问题是:


  1. 如果我只是移动elf二进制文件中的文件偏移而未修改vm_addresses,运行二进制文件时会导致任何错误吗?

  2. 是否有可能做我尝试的事情?有人尝试过吗?


推荐答案

您要尝试的操作不可能以任何自动化方式实现。在静态链接时,已解决并删除了所有将对libc的调用标识为对libc的调用的重定位信息。如果二进制文件中存在调试符号,则可以识别该文本段中的字节范围与某某类libc函数相对应,但是无法识别对该函数的引用 ,它将被嵌入到指令字节流中,并且没有标记来标识它们。您可以使用基于分解的启发式方法,但是它们将是不完整且不可靠的(可能出现假阴性和假阳性)。

What you are attempting is not possible in any automated way. At the time of static linking, all relocation information identifying calls to libc as calls to libc has been resolved and removed. If debugging symbols exist in the binary, it's possible to identify "this range of bytes in the text segment corresponds to such-and-such libc function", but there is no way to identify references to the function, which will be embedded in the instruction byte stream with no markup to identify them. You could use heuristics based on disassembly, but they would be incomplete and unreliable (possibility of both false negatives and false positives).

就转移偏移量而言,您绝对不能更改有关静态链接二进制文件的加载地址的任何信息。如果您需要在加载分段之前插入标头,则必须插入整个页面,并更新程序标头表中的文件偏移量(向其添加1页),同时保持虚拟地址加载偏移量不变。但是,由于您尝试做的事情总体上是不可能的,因此偏移移位问题是您的后顾之忧。

As far as shifting offsets, you absolutely cannot change anything about the load addresses for a static linked binary. If you need to insert headers before the load segments, you'd have to insert a whole page, and update the file offsets in the program header table (adding 1 page to them) while leaving the virtual address load offsets the same. However, since what you're trying to do is not possible overall, the offset-shifting issue is the least of your worries.

也许,如果程序没有需要高性能,则可以在qemu应用程序级仿真下运行它,而qemu则通过套接字仿真/包装器运行。

Perhaps, if the program doesn't require high performance, you could run it under qemu app-level emulation, with qemu going through the sockets emulation/wrapper.

这篇关于将静态链接的elf二进制文件转换为动态链接的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆