프로그램을 실행하고 싶은데, 프로그램이 특정 파일을 읽으려고 할 때 내가 선택한 다른 파일을 읽도록 하고 싶습니다.
특히, 프로그램이 구성 파일을 읽으려고 시도하지만 설계가 잘못되어 사용자가 구성 파일의 위치를 지정할 수 없습니다. 또한 프로그램이 읽으려고 하는 위치에서 파일을 편집할 권한도 없습니다.
나는 그것이 가능하다는 것을 안다발각프로그램은 만들어진 시스템 호출을 사용하며 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)
호출을 수정하는 요점이어야 합니다.