Pages

2013/06/02

A Simple LD_PRELOAD Tutorial, Part 2 - good coders code, great reuse

A Simple LD_PRELOAD Tutorial, Part 2 - good coders code, great reuse


A Simple LD_PRELOAD Tutorial, Part 2

Posted: 01 Jun 2013 01:31 PM PDT

Last time I stopped at showing how to override functions in shared libraries by compiling your own shared library and preloading it via the LD_PRELOAD environment variable. Today I'll show you how to call the original function from the overridden function.

First let's review the code example that we used in the previous article. We had a program called prog.c that simply used fopen:

#include <stdio.h>    int main(void) {      printf("Calling the fopen() function...\n");        FILE *fd = fopen("test.txt", "r");      if (!fd) {          printf("fopen() returned NULL\n");          return 1;      }        printf("fopen() succeeded\n");        return 0;  }  

Today let's write a shared library called myfopen.c that overrides fopen in prog.c and calls the original fopen from the c standard library:

#define _GNU_SOURCE    #include <stdio.h>  #include <dlfcn.h>    FILE *fopen(const char *path, const char *mode) {      printf("In our own fopen, opening %s\n", path);        FILE *(*original_fopen)(const char*, const char*);      original_fopen = dlsym(RTLD_NEXT, "fopen");      return (*original_fopen)(path, mode);  }  

This shared library exports the fopen function that prints the path and then uses dlsym with the RTLD_NEXT pseudohandle to find the original fopen function. We must define the _GNU_SOURCE feature test macro in order to get the RTLD_NEXT definition from <dlfcn.h>. RTLD_NEXT finds the next occurrence of a function in the search order after the current library.

We can compile this shared library this way:

  gcc -Wall -fPIC -shared -o myfopen.so myfopen.c -ldl  

Now when we preload it and run prog we get the following output that shows that test.txt was successfully opened:

  $ LD_PRELOAD=./myfopen.so ./prog  Calling the fopen() function...  In our own fopen, opening test.txt  fopen() succeeded  

This is really useful if you need to change how a part of a program works or do some advanced debugging. Next time we'll look at how LD_PRELOAD is implemented.

No comments:

Post a Comment

Keep a civil tongue.