linux - 拦截所有二进制文件的打开系统调用

标签 linux gcc ld-preload

我看到用 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/

相关文章:

linux - 如何可靠地跟踪 POSIX 系统上的子/孙进程?

python - 谷歌云 SDK : set environment variable_ python --> linux

c - SO_SNDBUF 的作用

c++ - 注入(inject)的类名编译器差异

c - 从 fgets() 输入中删除尾随换行符

python - 无法使用 LD_PRELOAD 拦截 PyDict_New

c - 使用 LD_PRELOAD 包装克隆系统调用

linux - bash 中文件列表的良好输出

c - 如何从源代码编译我自己的glibc C标准库并使用它?

python - 将 python 与 openssl 的自定义构建一起使用