Drew Asked: 2018-11-27 21:55:11 +0800 CST2018-11-27 21:55:11 +0800 CST 2018-11-27 21:55:11 +0800 CST 运行程序并拦截和重定向系统调用 772 我想运行一个程序,当该程序尝试读取特定文件时,我希望它读取我选择的不同文件。 具体来说,该程序试图读取配置文件,并且设计不佳并且不允许用户指定配置文件的位置。我也无权在程序尝试读取的位置编辑文件。 我知道可以使用检测程序发出的系统调用strace,并且我可以open()通过在 下运行程序来查看程序发出的唯一系统调用strace。有什么方法可以拦截该系统调用并更改它的行为以打开我选择的不同文件? linux strace 1 个回答 Voted Best Answer thrig 2018-11-27T22:29:04+08:002018-11-27T22:29:04+08:00 LD_PRELOAD可以在linux上做到这一点;首先我们的应用程序进行修改,app.c #include <fcntl.h> #include <stdio.h> #include <unistd.h> int main(int argc, char *argv[]) { char c; int fd; fd = open(*++argv, O_RDONLY); read(fd, &c, 1); printf("%c\n", c); return 0; } 它用于从文件中读取字符: $ make app cc app.c -o app $ echo a > a $ echo b > b $ ./app a ; ./app b a b 改变它需要一个伪造的库open,fakeopen.c: #define _GNU_SOURCE #include <dlfcn.h> #include <fcntl.h> #include <stdarg.h> #include <stdlib.h> #include <string.h> typedef int (*orig_open) (const char *path, int oflag, ...); int open(const char *path, int oflag, ...) { orig_open fn; mode_t cmode = 0; va_list ap; if ((oflag & O_CREAT) == O_CREAT) { va_start(ap, oflag); cmode = (mode_t) va_arg(ap, int); va_end(ap); } if (strncmp(path, "a", 2) == 0) path = getenv("FAKE"); fn = (orig_open) dlsym(RTLD_NEXT, "open"); return fn(path, oflag, cmode); } 当通过编译和使用LD_PRELOAD时,当文件名是我们正在寻找并假设FAKE具有路径的东西时: $ cat Makefile fakeopen.so: fakeopen.c $(CC) $(CFLAGS) -shared -fPIC -ldl fakeopen.c -o fakeopen.so $ rm fakeopen.so $ cat Makefile fakeopen.so: fakeopen.c $(CC) $(CFLAGS) -shared -fPIC -ldl fakeopen.c -o fakeopen.so $ make fakeopen.so cc -shared -fPIC -ldl fakeopen.c -o fakeopen.so $ FAKE=b LD_PRELOAD=`pwd`/fakeopen.so ./app a b 我们可以./app a改为读取文件b。当然,需要更多的错误检查和其他可能会踩到的 rake,但这应该是修改open(2)调用的要点。
LD_PRELOAD
可以在linux上做到这一点;首先我们的应用程序进行修改,app.c
它用于从文件中读取字符:
改变它需要一个伪造的库
open
,fakeopen.c
:当通过编译和使用
LD_PRELOAD
时,当文件名是我们正在寻找并假设FAKE
具有路径的东西时:我们可以
./app a
改为读取文件b
。当然,需要更多的错误检查和其他可能会踩到的 rake,但这应该是修改open(2)
调用的要点。