Linux

執行程序並攔截和重定向系統呼叫

  • November 27, 2018

我想執行一個程序,當該程序嘗試讀取特定文件時,我希望它讀取我選擇的不同文件。

具體來說,該程序試圖讀取配置文件,並且設計不佳並且不允許使用者指定配置文件的位置。我也無權在程序嘗試讀取的位置編輯文件。

我知道可以使用檢測程序發出的系統呼叫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

改變它需要一個偽造的庫openfakeopen.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)呼叫的要點。

引用自:https://unix.stackexchange.com/questions/484368