Convert a statically linked elf binary to dynamically linked

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

I believe it is possible to convert this binary to a dynamic connection with OpenOnload with the following steps:

  • Add new program titles: PT_INTERP, PT_DYNAMIC and PT_LOAD.
  • Add entries to PT_DYNAMIC to determine libc dependency.
  • Add PLT stubs for the required libc functions to the new PT_LOAD section.
  • Modify the existing binary for libc functions to go to the corresponding PLT stubs.

As the first cut, I tried just adding 3 PT_LOAD segments. New segment headers have been added after existing PT_LOAD segment headers. In addition, vm_addr of existing segments has not been changed. The file offset of existing segments was shifted lower to the next aligned address based on p_align. New PT_LOAD segments have been added to the file at the end of the file.

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

My questions:

  • If I just shift the file offset in the elf binary without changing vm_addresses, can it cause any error when the binary is launched?
  • Can I do what I'm trying to do? Has anyone tried to do this?
+8
c linux elf openonload
source share
1 answer

What you are trying is not possible in automatic mode. During static binding, all movement information that identifies libc calls as libc calls has been eliminated and deleted. If debug symbols exist in binary format, you can define "this range of bytes in the text segment corresponds to such and such a libc function", but there is no way to identify function references that will be built into the instruction byte stream without markup to identify them. You can use disassembly-based heuristics, but they would be incomplete and unreliable (the possibility of both false negatives and false positives).

As for the offset bias, you can absolutely not change anything about the download addresses for a static linked binary. If you need to insert headers before the load segments, you will need to insert the whole page and update the file offsets in the program header table (adding 1 page to them), leaving the virtual address load offsets the same. However, since what you are trying to do is not possible in general, the bias bias problem is the least of your problems.

Perhaps if the program does not require high performance, you can run it under qemu application level emulation, qemu will go through the socket emulation / shell.

+4
source share

All Articles