Quando um programa abre um arquivo, esse arquivo termina em um descritor de arquivo que é gratuito no momento. Ao abrir um arquivo antes do início do programa, você só estará fazendo mais um descritor de arquivo ocupado, para que o arquivo em que você está interessado possa acabar em um descritor diferente. Se você quiser que o programa abra um arquivo diferente, você precisará modificar a operação de abertura quando ocorrer, ou intervir depois.
Uma maneira de modificar a operação é colocar algum código entre o programa e a biblioteca do sistema, por pré-carregando um pequeno pedaço de código. Isso pressupõe que o programa é um binário vinculado dinamicamente, ou um script executado por um binário vinculado dinamicamente (ou seja, ele não está vinculado estaticamente). Escreva o seguinte código em um arquivo 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;
}
Compile com o seguinte comando (para o Linux, outras variantes do Unix podem exigir opções diferentes). Observe as aspas ao redor do caminho que você deseja substituir.
gcc -DFROM='"/some/path"' -DTO='"/dev/null"' -D_GNU_SOURCE -O -Wall -fPIC -shared -o override_fopen.so override_fopen.c -ldl
Execute o programa da seguinte maneira (no OSX, use DYLD_PRELOAD
em vez de LD_PRELOAD
):
LD_PRELOAD=./override_fopen.so ./myexe
Isso só funciona se o programa estiver chamando a função de biblioteca fopen
ou open
. Se ele chamar outra função, você precisará substituir essa. Você pode usar ltrace
para ver que biblioteca chama o programa.