Eh bien, si vous voulez littéralement y parvenir, vous pouvez utiliser un hook LD_PRELOAD . L'idée de base est de réécrire une fonction de la bibliothèque C et de l'utiliser à la place de la normale.
Voici un exemple simple où nous remplaçons la fonction read () pour XOR le tampon de sortie avec 0x42.
#define _GNU_SOURCE
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <dlfcn.h>
#include <unistd.h>
static int dev_zero_fd = -1;
int open64(const char *pathname, int flags)
{
static int (*true_open64)(const char*, int) = NULL;
if (true_open64 == NULL) {
if ((true_open64 = dlsym(RTLD_NEXT, "open64")) == NULL) {
perror("dlsym");
return -1;
}
}
int ret = true_open64(pathname, flags);
if (strcmp(pathname, "/dev/zero") == 0) {
dev_zero_fd = ret;
}
return ret;
}
ssize_t read(int fd, void *buf, size_t count)
{
static ssize_t (*true_read)(int, void*, size_t) = NULL;
if (true_read == NULL) {
if ((true_read = dlsym(RTLD_NEXT, "read")) == NULL) {
perror("dlsym");
return -1;
}
}
if (fd == dev_zero_fd) {
int i;
ssize_t ret = true_read(fd, buf, count);
for (i = 0; i < ret; i++) {
*((char*)buf + i) ^= 0x42;
}
return ret;
}
return true_read(fd, buf, count);
}
Une implémentation naïve ferait XOR 0x42 sur chaque fichier lu, ce qui aurait des conséquences indésirables. Afin de résoudre ce problème, j'ai également accroché la fonction open () , ce qui lui permet de récupérer le descripteur de fichier associé à / dev / zero. Ensuite, nous n'effectuons le XOR dans notre fonction read () que si fd == dev_zero_fd
.
Usage:
$ gcc hook.c -ldl -shared -o hook.so
$ LD_PRELOAD=$(pwd)/hook.so bash #this spawns a hooked shell
$ cat /dev/zero
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB