Wenn man z.B. ein Programm hat, dass prüft, ob man eine bestimmte CPU hat – z.B. weil es nicht unter qemu verwendet werden soll – kann es sinnvoll sein, den Check zu umgehen, bzw. dem Programm vorzugaukeln, dass alles OK ist. Hierfür kann man idealerweise LD_PRELOAD nutzen, welches einen bestehenden Library Call überlädt. Im Detail läuft das wie folgt ab:
– man findet die Adresse des originalen Library Calls per dlsym()
– man deklariert die Funktion, sie überlädt die originale Funktion (hier: open())
– man schreibt in der Funktion je nach übergebenem Parameter um, zurückliefert wird
– oder man führt die Originalfunktion aus
/* * open_preload.c */ #define _GNU_SOURCE #include <sys/syscall.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <dlfcn.h> #include <dirent.h> static void init (void) __attribute__ ((constructor)); int (*real_open)(__const char *name, int flags, mode_t mode); static void init (void) { real_open = dlsym(RTLD_NEXT,"open"); } int open(const char *pathname, int flags, mode_t mode) { if (strcmp(pathname,"/proc/cpuinfo") == 0) { return(real_open("/tmp/cpuinfo",flags,mode)); } else { return(real_open(pathname,flags,mode)); } } |
Das Ganze compiliert und testet man dann wie folgt:
[sb@machine ~]$ echo test > /tmp/cpuinfo [sb@machine ~]$ gcc -g -fpic -shared -ldl -o open_preload.so open_preload.c [sb@machine ~]$ LD_PRELOAD="./open_preload.so" cat /proc/cpuinfo test [sb@machine ~]$ |
Das fühlt sich schon ein wenig nach RootKit-Programmierung an. 😉
We diefnteily need more smart people like you around.
Wenn ein 64-bit Betriebssystem eingesetzt wird, muss die Kernel-Funktion “open64” überschrieben werden. “strace” zeigt seltsamerweise “open(…)” an, obwohl die Funktion eigentlich open64 ist.
Sicherheitshalber habe ich open() und open64() überschrieben.