Depth of Code

Hani’s blog

Library preloading for reverse engineering

Oct 23, 2011

  Many times when reversing a dynamically linked executable, we could benefit from knowing when calls to certain functions are made or/and alter its behavior in a faster and more elegant way without modifying the executable.
Library preloading is a great feature that allows us to inject functions from our own libraries in a program and override the duplicated functions.

  Let’s take for example Wireshark. 

**  ldd** is a tool that outputs a program’s dynamically linked dependencies, known as shared objects (.so) on *nix systems.

hani@JustD:~$ ldd /usr/bin/wireshark  

    linux-vdso.so.1 =>  (0x00007fff3f7ff000)
    libwiretap.so.1 => /usr/lib/wireshark/libwiretap.so.1 (0x00007f4b095b5000)
    libwireshark.so.1 => /usr/lib/wireshark/libwireshark.so.1 (0x00007f4b060d9000)
    …
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4b03d57000)
    …

Better yet than replacing a whole library, we could override only one or certain functions.
Let’s replace getenv which is a function from stdlib.h that returns the value of an environment variable. We use the same original source code of getenv and only add a printf at the beginning to show us what variable is being looked for.

char *getenv(const char *name)
{
        printf("%s\n",name);
    …

We then compile it and explicitly specify that we want it to be a shared object.

hani@JustD:~/space$ **gcc -shared -fPIC mygetenv.c -o mygetenv.so **

hani@JustD:~/space$ file mygetenv.so

space/mygetenv.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped

and finally we use the environnement variable LD_PRELOAD to preload our shared object

hani@JustD:~/space$ LD_PRELOAD=mygetenv.so /usr/bin/wireshark

WIRESHARK_RUN_FROM_BUILD_DIRECTORY
G_DEBUG
G_SLICE
U3_HOST_EXEC_PATH
HOME  

That’s it! There are many variantes and uses to this technique that would could prove useful in many situations.