I am trying to wrap the GLIBC fstat
function (it could be any other: it is just a proof of concept) by injecting my library to an executable. I do this by placing my library where the executable's RPATH
is pointing with the name libc.so.6
.
The source code of my library is the one below:
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>
int fstat(int fd, struct stat *buf){
typeof(fstat) *old_fstat;
// Try with a printf...
printf("HOOT! fstat wrapped!");
old_fstat = dlsym(RTLD_NEXT, "fstat");
return (*old_fstat)(fd, buf);
}
I compile it with --version-script
(to add symbol versioning) and statically link it to libgcc.
gcc -Wall -fPIC -c -o wrapperlib.o wrapperlib.c
gcc -shared -static-libgcc -fPIC -Wl,-soname -Wl,libc.so.6 -Wl,--version-script=wrapperlib.map,-Bstatic -o libc.so.6 wrapperlib.o
With wrapperlib.map
containing:
GLIBC_2.0 {
};
When I execute the target program my library gets loaded but I get the following error:
./target: relocation error: ./target: symbol __libc_start_main, version GLIBC_2.0 not defined in file libc.so.6 with link time reference
If I provide my own implementation of __libc_start_main
I don't get this error (but it crashes, of course).
int __libc_start_main(int (*main) (int, char **, char **), int argc, char *argv, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void *stack_end) {
system("echo I am in __libc_start_main");
printf("printf: I am in __libc_start_main");
fflush(stdin);
return 0;
}
Why is there a relocation error on __libc_start_main
and not on system
?
(By the way, the call to the system
does work but the call to printf
produces no output. Am I missing something obvious here?)
Thank you
Edit:
Running target with LD_DEBUG=all
outputs this:
http://pastebin.com/iVVbwf6n