magic_elf (ELF File Format Analyzer)
Posted: April 4, 2009
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
Key Features (from the version below)
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
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 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:
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:
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.
Copyright 1997-2021 - Michael Kohn