LD_PRELOAD and multiple libraries

October 8, 2011

Иногда нужно запустить какую-то конкретную программу так, чтобы одна конкретная функция работала в ней не так, как обычно.

Примеры, когда это может понадобиться:

Попробуем перегрузить функцию exit() в glibc. Большинство UNIX позволяют принудительно вгрузить какую-то стороннюю библиотеку в адресное пространство запускаемой программы через глобальную переменную LD_PRELOAD.

Попробуем простой пример:

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
void exit(int status)
{
    void (*real_exit)(int status);
    *(void **)&real_exit = dlsym (RTLD_NEXT, "exit");
    fprintf (stderr, "<<<%s:Morning sir! I pass you to the %p function>>>\n", W, real_exit);
    real_exit (status);
}
$ cc -g -O0 -fPIC -DW='"w1"' main.c -o stat_wrapper1.so -shared -ldl
$ cc -g -O0 -fPIC -DW='"w2"' main.c -o stat_wrapper2.so -shared -ldl
$ LD_PRELOAD="./stat_wrapper1.so ./stat_wrapper2.so" ls .
    main.c  makefile  stat_wrapper1.so  stat_wrapper2.so
    <<<w1:Morning sir! I pass you to the 0x7fba1919a67c function>>>
    <<<w2:Morning sir! I pass you to the 0x7fba18a38150 function>>>

Работает!