This is going to be a super short and super simple tutorial for beginners about LD_PRELOAD. If you're familiar with LD_PRELOAD, you'll learn nothing new. Otherwise keep reading!

Did you know you could override the C standard library's functions (such as printf, fopen, etc) with your own version of these functions in any program? In this article I'll teach you how this can be done through the LD_PRELOAD environment variable.

Let's start with a simple C program (prog.c):

#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;
}

The code above simply makes a call to the standard fopen function and then checks its return value. Now, let's compile and execute it:

$ ls
prog.c  test.txt

$ gcc prog.c -o prog

$ ls
prog  prog.c  test.txt

$ ./prog
Calling the fopen() function...
fopen() succeeded

Now let's write our own version of fopen and compile it as a shared library:

#include <stdio.h>

FILE *fopen(const char *path, const char *mode) {
    printf("Always failing fopen\n");
    return NULL;
}

Let's call this file myfopen.c, and let's compile it as a shared library:

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

Now we can simply modify LD_PRELOAD:

$ LD_PRELOAD=./myfopen.so ./prog
Calling the fopen() function...
Always failing fopen
fopen() returned NULL

As you can see the fopen got replaced with our own version that is always failing. This is really handy if you've to debug or replace certain parts of libc or any other shared library.

Next time I'll write about how the LD_PRELOAD works internally.

Comments

Bradley Meck Permalink
April 02, 2013, 17:22

Example with all the pragmas for Mac OS X, Solaris, and Linux C code we are using:

https://github.com/bmeck/interposed/blob/master/fixtures/nix.c

Example simple build script for the file:

https://github.com/bmeck/interposed/blob/master/fixtures/build.sh

April 02, 2013, 18:10

That is awesome!

July 29, 2013, 04:18

I am using C, but I really didn't know about that. Thanks, Nice Share.

Grzeg Permalink
July 29, 2013, 20:12

now continuing with our example, is it possible to still call the standard libc function fopen from your own version?

Albob Permalink
September 05, 2013, 13:45

Very cool :)
Any idea on how to make it work with Objective c++? My program is writing file on the disk and I can't find what line of code is doing it... Overriding fopen() would really solve my problem.

sharath Permalink
March 26, 2014, 18:08

I have overridden open() which is provided by glibc in my library & I have set LD_PRELOAD with my library first, so when the process calls open(), the open which is defined in my library gets called.

THE PROBLEM:- There are several other functions within glibc which calls open() once such example is getpt(), when getpt() calls open(), the open() which is defined in glibc gets called, how would I make getpt() to invoke the open() which is defined in my library().

markys Permalink
November 11, 2014, 05:58

I followed your example but something going wrong. Here is the output. Please explain me this.
"ERROR: ld.so: object 'myfopen.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored."

markys Permalink
November 11, 2014, 06:16

found my mistake. thank you for clear explain.

Walter P. Dahl Permalink
January 26, 2015, 20:27

I always suggest my students to get professional assistance for their tough assignments. When you are making research to choose someone, try to find best essay writing services instead of cheap prices. There are many fraudulent people online who may deceive you in the name of low price.

Leave a new comment

(why do I need your e-mail?)

(Your twitter name, if you have one. (I'm @pkrumins, btw.))

Type the word "halflife3_381": (just to make sure you're a human)

Please preview the comment before submitting to make sure it's OK.

Advertisements