--- /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;
+}