CONTENTS

Home
Updates
Software
Electronics
Android / iOS
Videos
Music
Resume
Contact

HTTPS VERSION


magic_elf (ELF File Format Analyzer)

Posted: April 4, 2009
Updated: May 12, 2019

The ELF File Format

Here's a program for dumping out the contents of ELF files. There are lots of other ELF dumping programs around, but this has been very useful to me for several projects, including analyzing core dumps when a lot of information was missing.

One of the original reasons I wrote this was to see if it's possible to get a function in a library compiled on Linux (with no calls to other libraries) to execute on Windows. In 32 bit mode, since the ABI is the same this works.

At my job this tool has been very useful in analyzing core files when the only thing I had is the core and a version of the library I needed to debug that had symbols in it. I gave magic_elf the ability to change registers in the core file to point the stack and instruction pointer to the library (past code that I didn't have symbols for which caused gdb to not be able to show a proper stack trace). I wrote up an example of this below using a forced crash in Java.

I also used this to debug creating ELF files with naken_asm and to modify libraries to force certain functions in other libraries to not execute but to return a specified value instead.

Related Projects @mikekohn.net

File Parsers: print_pe, magic_elf, dump_fat, amiga_recovery, dump_d64

Key Features (from the version below)

  • BSD License
  • Ability to parse elf out of memory
  • Ability to return pointers to functions - for replacing dlopen()
  • Ability to run on Windows so that Linux libraries can be loaded and functions can be called (limited.. see below)
  • Ability to modify a function to just return a set value.
  • Ability to print to the screen the value of a string symbol.
  • Ability to modify registers in core files which can be useful for getting stack traces from core files when some libraries are missing (see below).

Building

At the bottom of the page is a link to the git repository. After cloning just type: make

Analyzing A Java Core File

I added a Java/JNI program in the samples directory of the repository that forces a crash / core file that can be analyzed with magic_elf. I put a small tutorial up: Analyzing Core Files. It shows how to reset the stack pointer using magic_elf so that gdb can pull up a stack trace even if the orginal java executable is missing.

Loading an ELF On Windows

Currently this program only compiles on Unix due to the mmap stuff, although I do plan on fixing this when I get a chance. But just out of curiousity, I made some changes to magic_elf so it would compile on Windows temporarily so I could test the test_lib.c program to see if I could load a UNIX ELF library on Windows and call a function.

So I updated test_lib.c so instead of calling elf_open() it mallocs a chunk of memory the size of test32.so, dumps the entire library into a memory buffer, and calls elf_open_from_mem() on the buffer. Because I was running this on Windows XP with a CPU that doesn't support the NX bit, it's possible to run code out of malloc()'d RAM. Had this been done on a CPU with the NX bit and Windows supports NX, the memory would have to had been allocated using VirtualAlloc() or CreateFileMapping() with execute permission on the memory pages. So, after doing an elf_open_from_mem() I could find the address of my int add_nums(int,int) function using the same find_symbol_address() call and since the library was compiled as position independant code (-fPIC) I was able to call this function on Windows. Cool eh? :). The only thing left is to replace external libraries with Windows libraries. For example if printf() is on rh library import list, i could automatically replace it with a LoadLibrary to msvcrt.dll's printf().

How To Use

So actually there are other ELF tools out there that are much more useful such as objdump and readelf, but I made this one mostly to learn stuff and I have a couple features these don't have. First of all (as stated above) magic_elf can be built into a library so that a .so file can be loaded into memory and functions can be called into the .so file from another program without using dlopen() giving the option to call into Linux .so libraries on Windows. Secondly I added a -modify_function option to the magic_elf program so that functions can be changed to just return some set value.

So after typing "make" in the magic_elf directory, 3 things will be built: magic_elf, test.so, and test32.so. The magic_elf program is just a simple program to parse out sections from an elf file and display them similar to objdump and readelf. So to test this, type:

./magic_elf test.so

A bunch of headers will come out of that. So really this isn't much more interesting than what objdump/readelf can do, but I have a command line option -modify_function. Knowing that test.so has a function defined as: int return10_32(); and that this function will simply return 10 when I call it, if I do:

./magic_elf -modify_function return10_32 9293 test.so

Then this function is changed to be simply: int return10_32() { return 9293; }. Interesting eh? :)

As of October 15, 2011 I added a feature that if your library or standard executable has something like: char *version = "10.1"; for example, magic_elf can find these symbols and display their value to the screen with:

./magic_elf -show version test.so

.. after typing that magic_elf will show: version="10.1"

So lastly, magic_elf can be compiled as a library and used in other programs also. Typing "make lib" will create a libmagic_elf.so that can be linked into other programs. I included a sample program called test_lib.c that demonstrates simply opening up a library, returning a pointer to a function, and calling that function.

Download

GitHub: git clone https://github.com/mikeakohn/magic_elf.git

Copyright 1997-2019 - Michael Kohn