Library interposition is a useful technique for tuning performance, collecting runtime statistics, or debugging applications. With dynamic linking, you can intercept any function call an application makes to any shared library. Once you intercept it, you can do whatever you want in that function, as well as call the real function the application originally intended to call.
However this feature may also be exploited for some malicious use.
In Linux, the environment variable LD_PRELOAD allows specified libraries to be loaded before any other code.
This variable if set to some code which has a function in it with the constructor attribute, then the control will always go the library code first and then to any other code.
lets look at an example,
The code which will be loaded dynamically :
//demo.c
void __attribute__((constructor)) init() {
printf("How did it come to me??? ;) ;) ");
}
//End of file demo.c
$ gcc -shared demo.c -o demo.so -fPIC
$ export LD_PRELOAD=$PWD/demo.so true
Now execute any command :
$ ls
How did it come to me??? ;) ;) a aj.c a.out arr.s demo.so demo.c
$ gcc a.c
How did it come to me??? ;) ;) How did it come to me??? ;) ;) How did it come to me??? ;) ;) How did it come to me??? ;) ;) How did it come to me??? ;) ;)
$ ps
How did it come to me??? ;) ;) PID TTY TIME CMD
24126 pts/61 00:00:00 ps
28996 pts/61 00:00:00 bash
It doesnt end here...There is something more to it.
As the man page for LD_PRELOAD states "This can be used to selectively override functions in other shared libraries."
see this :
// --- demo.c ---
int printf(char *s, ...) {
fprintf(stdout, "Where is ur printf??? ;) ;) ");
}
// End of demo.c
// --- a.c ----
int main()
{
printf("Hello world");
}
// End of a.c
$ gcc a.c
$ ./a.out
Where is ur printf??? ;) ;)
One way out is.... using static-linking.....
eg :
For the above printf wala code
$ gcc -static a.c
$ ./a.out
Hello
This is because if static linking is done, the control never goes to the dynamic linker as u see below :
$ readelf -d a.out
There is no dynamic segment in this file.