
/path/to/file
이 질문의 목적을 위해 파일 시스템에 다음과 같은 특정 내용을 포함하는 파일( )이 있다고 가정해 보겠습니다 .
$> cat /path/to/file
this is the content of the
file /path/to/file
이 콘텐츠를 읽는 거의 모든 프로세스가 실행되고(및 이 파일에 대한 읽기 액세스 권한이 있음) 만족합니다.
그러나 거기에는 (그리고 이것이 질문의 핵심이다)는 특정 프로세스여야 하며, 읽을 때 /path/to/file
다른 파일 콘텐츠가 제공되어야 합니다.
$> cat /path/to/file
this is the DIFFERNT content of the
file /path/to/file
특정 프로세스의 파일 콘텐츠를 어떻게 스푸핑할 수 있나요?
내가 취해야 할 길은 다음과 관련된 해결책이 될 것이라고 추측합니다.
- 심볼릭 링크 트릭
- (리눅스) 네임스페이스 (파일 시스템 네임스페이스) 트릭
chroot
장난$LD_PRELOAD
후킹 트릭- 오버레이
내 플랫폼은 GNU/Linux이지만 이를 달성하는 POSIX 방법이 있다면 훨씬 더 좋을 것입니다. :)
업데이트
좋은 해결책/대답은 무엇입니까?
좋은 솔루션/답변의 기준은 이상적으로는 스푸핑된 파일이 애초에 사용자가 쓸 수 없어야 하지만 루트 사용자의 상호 작용 없이 "특정 프로세스에 대해 다른 파일 콘텐츠"를 얻을 수 있다는 것입니다.
또 다른 좋은 기준은 프로세스에 표시되는 파일 프로세스의 수정이 구체적이고 이상적으로는 일종의 경쟁 조건이 없다는 것입니다.
배경
Mozilla firefox는 2개의 zip 아카이브 /usr/lib/firefox/omni.ja
와 /usr/lib/firefox/browser/omni.ja
상당한 양의 firefox 코드(대부분 Javascript로 작성된 항목)가 포함된 파일을 스푸핑하여 내 Firefox 버전을 수정할 수 있습니다(더 이상 구현할 수 없는 일부 기능 포함). 확장 프로그램, XPCOM 지원 중단 및 애드온 서명 강제를 싫어함)
답변1
예, 마운트 네임스페이스는 한 가지 접근 방식입니다.
$ cat file
foo
$ cat other-file
bar
$ sudo unshare -m zsh -c 'mount --bind other-file file; USERNAME=$SUDO_USER; cat file'
bar
$ cat file
foo
위의 방법은 zsh
하이재킹된 cat 명령에 대해 원래 사용자의 uid/gid를 복원하는 데 사용됩니다.
답변2
이를 수행하는 방법은 다음과 같습니다.미리 로드 중작은 코드 조각으로 프로그램과 시스템 라이브러리 사이에 일부 코드를 고정합니다. 이는 프로그램이 동적으로 링크된 바이너리이거나 동적으로 링크된 바이너리에 의해 실행되는 스크립트(즉, 정적으로 링크되지 않음)라고 가정합니다. 파일에 다음 코드를 작성합니다 override_fopen.c
.
#include <dlfcn.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#ifndef FROM
#error "Define FROM to the path to override in double quotes, e.g. -DFROM='\"/bad\"'"
#endif
#ifndef TO
#error "Define TO to the path to use instead in double quotes, e.g. -DFROM='\"/good\"'"
#endif
FILE *fopen(const char *path, const char *mode) {
void *(*original_fopen)(const char *, const char *) = dlsym(RTLD_NEXT, "fopen");
if (!strcmp(path, FROM)) {
path = TO;
}
return original_fopen(path, mode);
}
int open(const char *path, int oflag, ...) {
int (*original_open)(const char *, int, ...) = dlsym(RTLD_NEXT, "open");
int ret;
va_list args;
if (!strcmp(path, FROM)) {
path = TO;
}
va_start(args, oflag);
if (oflag & O_CREAT) {
ret = original_open(path, oflag, (mode_t)va_arg(args, mode_t));
} else {
ret = original_open(path, oflag);
}
va_end(args);
return ret;
}
다음 명령을 사용하여 컴파일하십시오(Linux의 경우 다른 Unix 변형에는 다른 옵션이 필요할 수 있음). 재정의하려는 경로 주위에 따옴표를 적어 두십시오.
gcc -DFROM='"/path/to/file"' -DTO='"/path/to/alternate/content"' -D_GNU_SOURCE -O -Wall -fPIC -shared -o override_fopen.so override_fopen.c -ldl
다음과 같이 프로그램을 실행합니다(OSX에서는 DYLD_PRELOAD
대신 사용 LD_PRELOAD
).
LD_PRELOAD=./override_fopen.so ./myexe
이는 프로그램이 fopen
또는 open
라이브러리 함수를 호출하는 경우에만 작동합니다. 다른 함수를 호출하는 경우 해당 함수를 재정의해야 합니다. 당신이 사용할 수있는ltrace
프로그램이 어떤 라이브러리 호출을 하는지 확인합니다.