Cóż, jeśli dosłownie chcesz to osiągnąć, możesz użyć haka LD_PRELOAD . Podstawową ideą jest przepisanie funkcji z biblioteki C i użycie jej zamiast normalnej.
Oto prosty przykład, w którym nadpisujemy funkcję read () XOR bufora wyjściowego 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);
}
Naiwna implementacja spowodowałaby XOR 0x42 na każdym czytanym pliku, co miałoby niepożądane konsekwencje. Aby rozwiązać ten problem, podłączyłem również funkcję open () , dzięki czemu pobierała deskryptor pliku powiązany z / dev / zero. Następnie wykonujemy XOR w naszej funkcji read () if fd == dev_zero_fd
.
Stosowanie:
$ gcc hook.c -ldl -shared -o hook.so
$ LD_PRELOAD=$(pwd)/hook.so bash #this spawns a hooked shell
$ cat /dev/zero
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB