Intercept dynamic library methods with LD PRELOAD
Introduction
Let's say you have a binary called 'main' which was compiled against a shared memory 'libprint1.so', which has a method called print_msg() which prints 'hello from print1'. This looks like this
main.c
#include "print.h" int main(int argc, char *argv[]) { print_msg(); return 0; }
print.h
#ifndef RR_PRINT_H #define RR_PRINT_H #include <stdio.h> void print_msg(); #endif
print1.c
#include "print.h" void print_msg(){ printf("hello from print1\n"); }
This library can be compiled as dynamic and linked to the main program with
gcc -shared -o libprint1.so print1.c gcc -o main main.c -L. -lprint1
As expected when executed the program will output
hello from print1
Lets say you don't want to recompile main, or you simply do not have that source code, but you want to replace print_msg with another functionality. Here is where the concept of LD_PRELOAD comes in handy. This is an environment variable that will instruct the dynamic linker the priority of the dynamic libraries when executing a binary.
Let's change the message of print_msg()
print2.c
#include "print.h" void print_msg(){ printf("hello from print2\n"); }
Again, compile with
gcc -shared -o libprint2.so print2.c
But now, execute main like this
LD_PRELOAD=libprint2.so ./main
The output will be
hello from print2
You can even replace calls to stdlib like malloc and free, to help you keep track of memory allocation.