Eğer buysa, tam anlamıyla bunu başarmak istiyorum, bir kullanabilirsiniz LD_PRELOAD kanca . Temel fikir, bir işlevi C kütüphanesinden yeniden yazmak ve normal işlev yerine kullanmaktır.
Burada, 0x42 ile çıktı arabelleğini XOR yapmak için read () işlevini geçersiz kıldığımız basit bir örnek .
#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);
}
Saf bir uygulama, okuduğumuz her dosyada XOR 0x42 olur ve bu da istenmeyen sonuçlara yol açar. Bu sorunu çözmek için, open () işlevini de bağladım ve / dev / zero ile ilişkili dosya tanımlayıcısını getirdim . Ardından, XOR komutunu yalnızca read () işlevimizde yaparız fd == dev_zero_fd
.
Kullanımı:
$ gcc hook.c -ldl -shared -o hook.so
$ LD_PRELOAD=$(pwd)/hook.so bash #this spawns a hooked shell
$ cat /dev/zero
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB