Wenn Sie dies im wahrsten Sinne des Wortes erreichen möchten, können Sie einen LD_PRELOAD-Hook verwenden . Die Grundidee ist, eine Funktion aus der C-Bibliothek neu zu schreiben und anstelle der normalen zu verwenden.
Hier ist ein einfaches Beispiel, in dem wir die Funktion read () überschreiben, um den Ausgabepuffer mit 0x42 zu XOR zu verknüpfen.
#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);
}
Eine naive Implementierung würde XOR 0x42 für jede gelesene Datei bedeuten, was unerwünschte Konsequenzen hätte. Um dieses Problem zu lösen, habe ich auch die open () - Funktion eingebunden, sodass sie den Dateideskriptor abruft, der mit / dev / zero verknüpft ist. Dann führen wir das XOR in unserer read () - Funktion nur aus, wenn fd == dev_zero_fd
.
Verwendung:
$ gcc hook.c -ldl -shared -o hook.so
$ LD_PRELOAD=$(pwd)/hook.so bash #this spawns a hooked shell
$ cat /dev/zero
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB