简体   繁体   English

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

[英]Convert a statically linked elf binary to dynamically linked

I have a elf binary which has been statically linked to libc.我有一个 elf 二进制文件,它已静态链接到 libc。 I do not have access to its C code.我无权访问它的 C 代码。 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 库,它在用户空间中实现了套接字,因此与标准 libc 版本相比提供了更低的延迟。 OpenOnload implements standard socket api, and overrides libc version using LD_PRELOAD. OpenOnload 实现标准套接字 API,并使用 LD_PRELOAD 覆盖 libc 版本。 But, since this elf binary is statically linked, it cannot use the OpenOnload version of the socket API.但是,由于这个 elf 二进制文件是静态链接的,它不能使用套接字 API 的 OpenOnload 版本。

I believe that converting this binary to dynamically link with OpenOnload is possible, with the following steps:我相信可以通过以下步骤将此二进制文件转换为与 OpenOnload 动态链接:

  1. Add new Program headers: PT_INTERP, PT_DYNAMIC and PT_LOAD.添加新的程序头:PT_INTERP、PT_DYNAMIC 和 PT_LOAD。
  2. Add entries in PT_DYNAMIC to list dependency with libc.在 PT_DYNAMIC 中添加条目以列出与 libc 的依赖关系。
  3. Add PLT stubs for required libc functions in the new PT_LOAD section.在新的 PT_LOAD 部分中为所需的 libc 函数添加 PLT 存根。
  4. Modify existing binary code for libc functions to jump to corresponding PLT stubs.修改 libc 函数的现有二进制代码以跳转到相应的 PLT 存根。

As a first cut, I tried just adding 3 PT_LOAD segments.作为第一次剪辑,我尝试只添加 3 个 PT_LOAD 段。 New segment headers were added after existing PT_LOAD segment headers.在现有的 PT_LOAD 段头之后添加了新的段头。 Also, vm_addr of existing segments was not modified.此外,现有段的 vm_addr 未修改。 File offsets of existing segments were shifted below to next aligned address based on p_align.现有段的文件偏移量根据 p_align 向下移动到下一个对齐的地址。 New PT_LOAD segments were added in the file at end of the file.在文件末尾的文件中添加了新的 PT_LOAD 段。

After re-writing the file, when I ran it, it was loaded properly by the kernel, but then it immediately seg-faulted.重写文件后,当我运行它时,内核正确加载了它,但它立即出现了段错误。

My questions are:我的问题是:

  1. If I just shift the file-offsets in the elf binary, without modifying the vm_addresses, can it cause any error while running the binary?如果我只是在 elf 二进制文件中移动文件偏移量,而不修改 vm_addresses,它会在运行二进制文件时导致任何错误吗?
  2. Is it possible to do what I am attempting?有可能做我正在尝试的事情吗? Has anybody attempted it?有人尝试过吗?

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. 在静态链接时,所有重定位信息都将解析并删除标识对libc的调用作为对libc的调用。 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. 如果二进制文件中存在调试符号,则可以识别“文本段中的这个字节范围对应于这样的libc函数”,但是没有办法识别对该函数的引用 ,该函数将嵌入到指令字节流没有标记来识别它们。 You could use heuristics based on disassembly, but they would be incomplete and unreliable (possibility of both false negatives and false positives). 您可以使用基于反汇编的启发式方法,但它们将是不完整且不可靠的(错误否定和误报的可能性)。

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. 如果需要在加载段之前插入标题,则必须插入整个页面,并在程序标题表中更新文件偏移量(向它们添加1页),同时保持虚拟地址加载偏移量相同。 However, since what you're trying to do is not possible overall, the offset-shifting issue is the least of your worries. 但是,由于您要做的事情总体上是不可能的,因此偏移转移问题是您最不担心的问题。

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. 也许,如果程序不需要高性能,您可以在qemu app-level仿真下运行它,qemu通过套接字仿真/包装器。

OpenOnload ... overrides libc version using LD_PRELOAD. OpenOnload ... 使用 LD_PRELOAD 覆盖 libc 版本。 But, since this elf binary is statically linked ...但是,由于这个精灵二进制文件是静态链接的......

also answered in intercept system calls of statically linked executable还回答了拦截静态链接可执行文件的系统调用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM