Linux
執行程序並攔截和重定向系統呼叫
我想執行一個程序,當該程序嘗試讀取特定文件時,我希望它讀取我選擇的不同文件。
具體來說,該程序試圖讀取配置文件,並且設計不佳並且不允許使用者指定配置文件的位置。我也無權在程序嘗試讀取的位置編輯文件。
我知道可以使用檢測程序發出的系統呼叫
strace
,並且我可以open()
通過在 下執行程序來查看程序發出的唯一系統呼叫strace
。有什麼方法可以攔截該系統呼叫並更改它的行為以打開我選擇的不同文件?
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)
呼叫的要點。