A Simple LD_PRELOAD Tutorial

来源:互联网 发布:深圳华强北现状知乎 编辑:程序博客网 时间:2024/05/29 10:49
his 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:

$ lsprog.c  test.txt$ gcc prog.c -o prog$ lsprog  prog.c  test.txt$ ./progCalling 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 ./progCalling the fopen() function...Always failing fopenfopen() 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.


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 usesdlsym with the RTLD_NEXT pseudohandle to find the originalfopen function. We must define the _GNU_SOURCE feature test macro in order to get theRTLD_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 thattest.txt was successfully opened:

$ LD_PRELOAD=./myfopen.so ./progCalling the fopen() function...In our own fopen, opening test.txtfopen() 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.


0 0
原创粉丝点击