Dynamic linker tricks: Using LD_PRELOAD to cheat, inject features and investigate programs

This post assumes some basic C skills.

Linux puts you in full control. This is not always seen from everyone’s perspective, but a power user loves to be in control. I’m going to show you a basic trick that lets you heavily influence the behavior of most applications, which is not only fun, but also, at times, useful.

A motivational example

Let us begin with a simple example. Fun first, science later.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(){
  srand(time(NULL));
  int i = 10;
  while(i--) printf("%d\n",rand()%100);
  return 0;
}

Simple enough, I believe. I compiled it with no special flags, just

gcc random_num.c -o random_num

I hope the resulting output is obvious – ten randomly selected numbers 0-99, hopefully different each time you run this program.

Now let’s pretend we don’t really have the source of this executable. Either delete the source file, or move it somewhere – we won’t need it. We will significantly modify this programs behavior, yet without touching it’s source code nor recompiling it.

For this, lets create another simple C file:

int rand(){
    return 42; //the most random number in the universe
}

We’ll compile it into a shared library.

gcc -shared -fPIC unrandom.c -o unrandom.so

So what we have now is an application that outputs some random data, and a custom library, which implements the rand() function as a constant value of 42.  Now… just run random_num this way, and watch the result:

LD_PRELOAD=$PWD/unrandom.so ./random_nums

If you are lazy and did not do it yourself (and somehow fail to guess what might have happened), I’ll let you know – the output consists of ten 42’s.

Read the rest of this entry »

Advertisements