【发布时间】:2016-12-14 14:28:39
【问题描述】:
我正在尝试通过将我的库注入可执行文件来包装 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
【问题讨论】:
标签: c gcc wrapper glibc dynamic-linking