initial version
authorHeiko Schlittermann <hs@schlittermann.de>
Thu, 23 Dec 2010 00:46:07 +0100
changeset 0 7d3c07f8acfb
child 1 9ccc1574a367
initial version
Makefile
README
dl.c
dl.h
hallo.c
puts.c
readdir.c
--- /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 $@ $^
--- /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
--- /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 <stdio.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+#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;
+}
--- /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
--- /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 <dirent.h>
+#include <stdio.h>
+
+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;
+}
--- /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)("<puts>");
+    rc = (*orig)(s);
+    (*orig)("</puts>");
+    return rc;
+}
--- /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 <dirent.h>
+#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;
+}