Tag Archives: LD_PRELOAD

LD_PRELOAD magic

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. 😉