Mike Kwan
Mike Kwan

Reputation: 24447

How to convert from binary to relocatable object file and back?

I wish to inject an object file into an existing binary. The method I am attempting is:

Given the source:

#include <stdlib.h>
#include <stdio.h>

int main(void)
{
    puts("main");
    return EXIT_SUCCESS;
}

I compile this to host with the following:

gcc -Wall host.c -o host

I do the conversion to relocatable object file with:

objcopy -B i386 -I binary -O elf64-x86-64 host host.o

I then attempt a link with:

gcc host.o -o host

Ideally, this would relink the relocatable object file back to a binary. This would also give a chance to link in any extra object files. Unfortunately the command gives the following error:

/usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status

My question is why is this error appearing and how would I go about properly relinking?

Something I tried was to link in another object file at this point which contained a dummy main (because I figured I could manually patch up the entry point later anyway), but what happened was that the new binary seemed to relocate the old code in a weird way with the symbol table completely messed up.

Extra Information

readelf on the binary yields the following:

mike@mike-ubuntu:~/Desktop/inject-obj$ readelf -h host
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x400410
  Start of program headers:          64 (bytes into file)
  Start of section headers:          4424 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         9
  Size of section headers:           64 (bytes)
  Number of section headers:         30
  Section header string table index: 27

And on the relocatable object file:

mike@mike-ubuntu:~/Desktop/inject-obj$ readelf -h host.o
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          8480 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           64 (bytes)
  Number of section headers:         5
  Section header string table index: 2

Rationale

For those interested, the rationale can be found here.

Upvotes: 6

Views: 5845

Answers (1)

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215287

An executable file that is not PIE is impossible to make relocatable. Relocations have already been performed and the record of those relocations was thrown away. That is, relocating it would require finding all addresses of objects or functions inside the code and data of the binary, but it's impossible to determine whether a sequence of bytes is an address or some other sort of data or code.

There should be a way to do what you originally wanted to do (adding in new code), but the approach you're taking is doomed to failure.

Upvotes: 3

Related Questions