我看到用 LD_PRELOAD
拦截 fopen
并不是 100% 有效(下面的演示)。是否有一种万能的方法来拦截打开的系统调用?
我的最终目标是呈现一个与请求的文件不同的文件(例如,当请求 /etc/hosts
时,将流返回到 /tmp/my-hosts
)。< br/>
宁愿不必使用 root,但如果必须,那就这样吧。
编辑:我想要一个适用于现有二进制文件的解决方案。我无权访问他们的来源。
bin.c
#include <stdio.h>
int main() {
int c;
FILE *file;
file = fopen("file", "r");
if (file) {
while ((c = getc(file)) != EOF)
putchar(c);
fclose(file);
}
}
覆盖.c
#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
FILE *fopen(const char *path, const char *mode) {
printf("INTERCEPTED\n");
FILE *(*original_fopen)(const char*, const char*);
original_fopen = dlsym(RTLD_NEXT, "fopen");
return (*original_fopen)(path, mode);
}
FILE *fopen64(const char *path, const char *mode) {
printf("INTERCEPTED64\n");
FILE *(*original_fopen64)(const char*, const char*);
original_fopen64 = dlsym(RTLD_NEXT, "fopen");
return (*original_fopen64)(path, mode);
}
生成文件
clean:
rm -f bin-stat bin-dyn override.so
bin-stat: bin.c
gcc -static -Wall -Werror -o bin-stat bin.c
bin-dyn: bin.c
gcc -Wall -Werror -o bin-dyn bin.c
override.so: override.c
gcc -Wall -fPIC -shared -o override.so override.c -ldl
test: clean bin-stat bin-dyn override.so
LD_PRELOAD=./override.so ./bin-dyn
LD_PRELOAD=./override.so ./bin-stat
如您所见,bin-stat
是在没有动态链接到 libc 的情况下编译的,而且您可以猜到,LD_PRELOAD
将不起作用:
nitz@mars:~/Desktop/test-ld (master %)$ make test
rm -f bin-stat bin-dyn override.so
gcc -static -Wall -Werror -o bin-stat bin.c
gcc -Wall -Werror -o bin-dyn bin.c
gcc -Wall -fPIC -shared -o override.so override.c -ldl
LD_PRELOAD=./override.so ./bin-dyn
INTERCEPTED
is file
LD_PRELOAD=./override.so ./bin-stat
is file
nitz@mars:~/Desktop/test-ld (master %)$
最佳答案
检查 kprobes 或 system tap 以拦截系统调用。
关于linux - 拦截所有二进制文件的打开系统调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39695838/