Sunday, October 23, 2011

Library preloading for reverse engineering

  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.

1 comment: