我正在尝试通过将我的库注入到可执行文件中,来包装GLIBC fstat
函数(它也可以是其他任何函数:这只是一个概念证明)。我通过将我的库放置在可执行文件的RPATH
指向的位置,并以libc.so.6
命名的方式来实现这一点。
我的库的源代码如下:
#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);
}
我使用--version-script
进行编译(以添加符号版本控制),并将其静态链接到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
使用 wrapperlib.map
包含以下内容:
GLIBC_2.0 {
};
当我执行目标程序时,我的库被加载,但是我收到以下错误提示:
./target: relocation error: ./target: symbol __libc_start_main, version GLIBC_2.0 not defined in file libc.so.6 with link time reference
如果我提供自己的 __libc_start_main
实现,我就不会出现这个错误(但当然会崩溃)。
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;
}
为什么
__libc_start_main
会出现重定位错误,而 system
却不会呢?(顺便说一下,调用
system
可以成功执行,但是调用 printf
却没有输出。我有没有漏掉什么明显的问题?)谢谢。
编辑: 使用
LD_DEBUG=all
运行目标后输出如下:
http://pastebin.com/iVVbwf6n
-static-libgcc
,但目的正如您所提到的。谢谢。 - 0xdeda10