당신은 아래의 예제에서 수정 된 코드에서 일부 문제가 (나는 또한 관련 헤더를 추가하고 완벽한 프로그램을 제공하기 위해 main
를 제공 한) : 어떤에서
#include <stdio.h>
#include <dlfcn.h>
FILE* (*my_fopen)(const char *filename, const char* mode);
void* libc_handle;
void __attribute__ ((constructor)) init(void){
libc_handle = dlopen("libc.so.6", RTLD_LAZY);
my_fopen = dlsym(libc_handle,"fopen");
}
FILE* fopen(const char* filename, const char* mode){
printf("Hello, Pax\n");
return my_fopen(filename, mode);
}
int main (void) {
FILE *fout = fopen ("xyzzy.txt","w");
fclose (fout);
return 0;
}
변경을 당신은 다음과 같습니다 :
my_fopen
함수 포인터는 정확히 포인터이어야합니다. 나는 당신이 FILE*
을 그렇게 만들었다 고 생각할지도 모른다고 생각합니다. 그러나 실제로는 정확하지 않습니다. FILE
포인터를 반환하는 ffunction 포인터를 지정하려면 FILE * (*fn)(blah, blah)
이 필요합니다.
마찬가지로 함수의 첫 번째 인수는 const char *
, 포인터이어야합니다. 당신은 단순히 const char
으로 그것을 가지고있었습니다.
my_fopen
포인터 (캐스팅, 주소 지정, 참조 해제)를 설정하는 데 실제로 복잡한 형식이 필요하지 않습니다. 훨씬 단순한 my_fopen = ...
을 사용할 수 있습니다. 사실, 캐스팅이 실제로 어떤 일을하는지 알기 때문에 캐스팅이 실제로는 gcc
이 오류를보고하는 것을 막을 수 있다고 생각합니다.
아마도 dlopen
의 반환 값을 확인해야합니다. 나는이 코드에서 그렇게하지 않았지만, 어떤 이유로 라이브러리를 찾지 못하거나로드 할 수 없다면 그 이후의 행은 아마도 슬픔을 일으킬 것이다. 내가 컴파일하고 Red Hat Enterprise Linux Workstation release 6.4 (Santiago)
에서이 프로그램을 실행하면
, 나는 Hello, Pax
및 파일 xyzzy.txt
의 출력 생성을 얻는다.
그리고, 여담이 다른 파일 시스템에 액세스하기 위해 사용될 수있다 기능, 상황이 open
이 opendir
, freopen
, creat
, mkfifo
(나는 생각한다)와 같은있다 것처럼.
필요에 따라 추가 작업이 필요할 수 있습니다.
하나는 을 고려하는 것이 좋습니다 점은 ls
수도조차 사용fopen
입니다. 실제로는 opendir/readdir
및 stat
으로 만들 수 있습니다.
그럼 은을 알고있는 프로그램을 사용하여 fopen
으로 전화를 걸자. 다음을 실행
#include <stdio.h>
int main (void) {
FILE *fh = fopen ("xyzzy.txt", "w");
fclose (fh);
return 0;
}
및 gcc -o qqtest qqtest.c
로 컴파일 다음 프로그램 qqtest.c
를 입력합니다. 출력이 표시되지 않지만 xyzzy.txt
파일을 만들어야합니다.
#include <stdio.h>
#include <dlfcn.h>
FILE* (*my_fopen)(const char *filename, const char* mode);
void* libc_handle;
void __attribute__ ((constructor)) init(void){
libc_handle = dlopen("libc.so.6", RTLD_LAZY);
my_fopen = dlsym(libc_handle,"fopen");
}
FILE* fopen(const char* filename, const char* mode){
printf("Hello, Pax\n");
return my_fopen(filename, mode);
}
gcc -shared -o qq.so qq.c -ldl
이것을 컴파일 한 다음 qqtest
프로그램 (물론 자신의 디렉토리에 공유 객체의 경로를 변경)를 실행 : 당신이 xyzzy.txt
파일을 삭제 있음을 확인하면, 다음 프로그램 qq.c
를 입력 : xyzzy.txt
파일이 생성되기 전에
LD_PRELOAD=/home/pax/qq.so ./qqtest
이 시간, 당신은 그것을 다시 원래 fopen
호출 래퍼 함수를 부르고 있다는 증거를 Hello, Pax
문자열 출력을 볼 수 있습니다.
자, 당신이이 비트는 작업을 진행하더라도 일단, 아주 잘 전부지만, 당신은 당신이 모든 변경 사항을 잡을 수 있도록하는 것은 매우 몇 가지 다른 호출을 차단해야합니다.
Chris Stratton이 주석에서 지적한대로 Linux 커널이 이미 일 때에 파일 시스템 변경 사항을보고 할 수있는 기능이 있습니다.
당신의 목표는 단지 바퀴를 다시 발명에 필요없이 을 수행하는 방법을 볼 수 inotify로 보면, 파일 시스템 변경 사항을 추적하기보다는 그것을 할 수있는 방법에 자신을 교육하는 것입니다 경우.
나는'fopen'보다는'open'을 걸 수 있습니다. –
inotify 고려하셨습니까? –
@MatteoItalia, 나는 열어 보았지만 파일을 여는 데 익숙하지 않았습니다. 나는 fopen()과 같은 것들이 개인적인 방법을 사용한다고 생각한다. 나는 훅 (open)을 – user1734905