프로그램을 실행하고 시스템 호출을 가로채서 리디렉션합니다.

프로그램을 실행하고 시스템 호출을 가로채서 리디렉션합니다.

프로그램을 실행하고 싶은데, 프로그램이 특정 파일을 읽으려고 할 때 내가 선택한 다른 파일을 읽도록 하고 싶습니다.

특히, 프로그램이 구성 파일을 읽으려고 시도하지만 설계가 잘못되어 사용자가 구성 파일의 위치를 ​​지정할 수 없습니다. 또한 프로그램이 읽으려고 하는 위치에서 파일을 편집할 권한도 없습니다.

나는 그것이 가능하다는 것을 안다발각프로그램은 만들어진 시스템 호출을 사용하며 strace, open()에서 프로그램을 실행하면 프로그램이 만든 시스템 호출만 볼 수 있습니다 strace. 어떤 방법이 있나요?가로채기시스템 호출을 수행하고 내가 선택한 다른 파일을 열도록 동작을 변경합니까?

답변1

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. 물론 더 많은 오류 검사가 필요하고 다른 갈퀴를 밟을 수도 있지만 이것이 open(2)호출을 수정하는 요점이어야 합니다.

관련 정보