# HG changeset patch # User Heiko Schlittermann # Date 1293061567 -3600 # Node ID 7d3c07f8acfb71327352a1be4ba85869ecc7d273 initial version diff -r 000000000000 -r 7d3c07f8acfb Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Thu Dec 23 00:46:07 2010 +0100 @@ -0,0 +1,24 @@ +ALL = hallo myhallo libmy.so.1.0.1 + +CFLAGS = -fPIC -O2 -Wall $(shell getconf LFS_CFLAGS) +LDFLAGS = -ldl + +CLEANFILES = $(wildcard *.o) + +.PHONY: all clean + +all: $(ALL) +clean: ; -rm -f $(CLEANFILES) 2>/dev/null +distclean: clean ; -rm $(ALL) 2>/dev/null + + +hallo: hallo.o + +myhallo: hallo.o puts.o readdir.o dl.o + $(CC) -o $@ -ldl $^ + +puts.o: puts.c dl.h +readdir.o: readdir.c dl.h + +libmy.so.1.0.1: puts.o readdir.o dl.o + $(CC) -shared -ldl -Wl,-soname=libmy.so.1 -o $@ $^ diff -r 000000000000 -r 7d3c07f8acfb README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Thu Dec 23 00:46:07 2010 +0100 @@ -0,0 +1,21 @@ +This should demonstrate the use of LD_PRELOAD. + + hallo: uses virgin puts(3) and readdir(3) + myhallo: uses modified puts(3) and readdir(3) + +If you set the environment + + LD_PRELOAD=`pwd`/libmy.so.1.0.1 + +the "hallo" should use the modified versions of the above +funtions too. + +The modification is visibable, as puts(3) prints an +extra string before the real output, and readdir(3) skips +any directory entry starting with 'M'. + +No considerations done about race conditions and other nice things. +It is just an nice example… + +-- +Heiko Schlittermann diff -r 000000000000 -r 7d3c07f8acfb dl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dl.c Thu Dec 23 00:46:07 2010 +0100 @@ -0,0 +1,26 @@ +#include +#include +#include +#include "dl.h" + +void *get_original_function(const char *soname, const char *name) +{ + const char* error; + void *handle = dlopen(soname, RTLD_LAZY); + void *rc; + + if (!handle) { + fprintf(stderr, "dlopen on %s: %s\n", soname, dlerror()); + exit(1); + } + + dlerror(); + rc = dlsym(handle, name); + if ((error = dlerror())) { + fprintf(stderr, "dlsym for %s: %s\n", name, error); + exit(1); + } + dlclose(handle); + + return rc; +} diff -r 000000000000 -r 7d3c07f8acfb dl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dl.h Thu Dec 23 00:46:07 2010 +0100 @@ -0,0 +1,4 @@ +#ifndef _DL_H_ +#define _DL_H_ +void *get_original_function(const char *soname, const char *name); +#endif diff -r 000000000000 -r 7d3c07f8acfb hallo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hallo.c Thu Dec 23 00:46:07 2010 +0100 @@ -0,0 +1,17 @@ +#include +#include + +int main(int argc, char** argv) +{ + + DIR *d = opendir("."); + struct dirent *dent; + + puts("-- DIRECTORY LISTING --"); + + while ((dent = readdir(d))) { + printf("%8u %20s\n", (unsigned int)dent->d_ino, dent->d_name); + } + + return 0; +} diff -r 000000000000 -r 7d3c07f8acfb puts.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/puts.c Thu Dec 23 00:46:07 2010 +0100 @@ -0,0 +1,21 @@ +#include "dl.h" + +/* shameless stolen from + * http://uberhip.com/people/godber/interception/html/slide_6.html + * and of course from the manpage of dlopen(3) + */ + + +int puts(const char* s) +{ + static int (*orig)(const char*); + int rc; + + if (!orig) + orig = get_original_function("libc.so.6", "puts"); + + (*orig)(""); + rc = (*orig)(s); + (*orig)(""); + return rc; +} diff -r 000000000000 -r 7d3c07f8acfb readdir.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/readdir.c Thu Dec 23 00:46:07 2010 +0100 @@ -0,0 +1,26 @@ +#include +#include "dl.h" + +/* shameless stolen from + * http://uberhip.com/people/godber/interception/html/slide_6.html + * and of course from the manpage of dlopen(3) + */ + + +struct dirent* readdir(DIR *dirp) +{ + + static struct dirent* (*orig)(DIR *); + struct dirent *dent; + + if (!orig) + orig = get_original_function("libc.so.6", "readdir64"); + + dent = (*orig)(dirp); + + /* skip selected entries */ + if (dent && dent->d_name[0] == 'M') + dent = (*orig)(dirp); + + return dent; +}