LD_PRELOAD and multiple libraries
October 8, 2011
Иногда нужно запустить какую-то конкретную программу так, чтобы одна конкретная функция работала в ней не так, как обычно.
Примеры, когда это может понадобиться:
- перегрузить функцию открытия файла (
open()
) так, чтобы вести отчёт открывавшихся программой файлов - перегрузить функцию открытия сокетов (
connect()
) так, чтобы прозрачно для программы авторизоваться наHTTP
(илиSCOKS
) прокси. Такие проги даже есть на свете:tsocks
иtransconnect
. Было время, когда я пользовался ими каждый день.
Попробуем перегрузить функцию 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");
(stderr, "<<<%s:Morning sir! I pass you to the %p function>>>\n", W, real_exit);
fprintf (status);
real_exit }
$ 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>>>
Работает!