3

I need to work with simple ELF files in my C program. I can't use any external libraries, but I can use elf.h.

Let's take hello.o file for source:

int Hello() { return 3; }

How could I access to Hello in ohter C program having only hello.o file?

I should probably load it to memory using mmap or sth like this. At the end I need to work with much complicated ELF files, but I don't know now, how to start.

UPDATE: I need to do this the way I described it, because it is for learning purposes. Whole problem is more complex that what I described.

For this question assume I need to write method:

int HelloFromElfO(const char* helloFile);

which would execute Hello function implemented in helloFile.

I don't want full answer. I don't need any code. I need something to start with.

I have basic knowledge about ELF file structure, but I have no idea how to work in C with binary file without any parser or sth like this.

UPDATE2: OK, apps like readelf are very complicated. So maybe I try this way: lets say again I have hello.o mapped to memory at ptr. How can I get pointer to Hello function?

How can I get any structured data from hello.o? I mean, not pure bytes but something I can work with.

Ari
  • 3,101
  • 2
  • 27
  • 49
  • 2
    You don't have the option of simply making them into shared objects, and relying on the dynamic loader? – NPE Mar 23 '13 at 12:01
  • @npe This is academic problem. I need to do this that way. – Ari Mar 23 '13 at 12:33
  • 1
    Try looking at the `readelf` command and its source code, it should show how to extract the info you need from the .o file. Perhaps also look at the `dlsym` source, as this does what you want, but in the C library. – teppic Mar 23 '13 at 13:00
  • @teppic Thanks! I thought about other more complex apps like linker, but I didn't think about ligheter, like readelf or objdump. – Ari Mar 23 '13 at 13:02

1 Answers1

5

This is way easier than you think. ELF has nothing to do with your problem (and mmap() is even farther...). hello.o is not an ELF file, it's an object file.

You can just link the object file to your executable, then you will be able to access Hello(). Supposing you have compiled your program to an object file as yourCode.o, you link this yourCode.o with hello.o

cc yourCode.o hello.o -o yourExecutable

See here.

EDIT:

If you don't want to link the file but load it dynamically, then

  1. mmap() the object file
  2. Get Hello() address in memory. You can statically analyze hello.o for this (e.g. using objdump) and get Hello() entry point offset in the file.
  3. Add this offset to the address returned by mmap() to get Hello() address.
  4. Map Hello() address to a function pointer
  5. Call the function.
  6. ???
  7. Profit
Community
  • 1
  • 1
m0skit0
  • 25,268
  • 11
  • 79
  • 127
  • I know. The problem is that I don't want to link file, I want to load it dynamically (and I don't want to use .so). This is academic problem. I need to implement some "dynamic linking" myself. – Ari Mar 23 '13 at 12:32
  • Please state explicitly that you don't want to link in your question, otherwise we can't know ;) – m0skit0 Mar 23 '13 at 12:33
  • The answer here will work for the `Hello()` given, but not in general: if `Hello()` references other functions (e.g. libc ones), or global data, then you would have to apply relocations. Using `__thread` data would complicate things even more. – Employed Russian Mar 24 '13 at 03:14
  • @EmployedRussian you're totally right, this is for **this** example. For more complicated object files, it's way harder than this. In [this](http://code.google.com/p/valentine-hbl/source/browse/#svn%2Ftrunk%2FeLoader) project other devs and me successfully do so for the PSP console if you're interested in more advanced examples (although still PSP executables are way simpler than PC's). – m0skit0 Mar 24 '13 at 12:30
  • @m0skit0 I don't want analyze file outside the program. I don't want to handle all ELF files (with __thread and many more features), but I need to handle simple ELF without using objdump elfreader or so on. – Ari Mar 27 '13 at 08:34
  • **The analyze is only done once** to get the offset of the function, which you can then hardcode in your code. If you don't want to do it, then you have to include this same analysis dynamically in your code by opening the object file and searching for the function (for which you will need again to hardcode values in your code like the name of the function, so I really don't see the difference). And again, **an object file is not an ELF**. The ELF is created by the linker and contains way more information. You need no ELF manipulation for this. – m0skit0 Mar 27 '13 at 12:49