Chà, nếu bạn thực sự muốn đạt được điều này, bạn có thể sử dụng móc LD_PRELOAD . Ý tưởng cơ bản là viết lại một hàm từ thư viện C và sử dụng nó thay vì hàm bình thường.
Dưới đây là một ví dụ đơn giản trong đó chúng ta ghi đè hàm read () thành XOR bộ đệm đầu ra với 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);
}
Một triển khai ngây thơ sẽ XOR 0x42 trên mỗi tệp chúng ta đọc, điều này sẽ có hậu quả không mong muốn. Để giải quyết vấn đề này, tôi cũng đã nối hàm open () , làm cho nó tìm nạp mô tả tệp được liên kết với / dev / zero. Sau đó, chúng tôi chỉ thực hiện XOR trong hàm read () nếu fd == dev_zero_fd
.
Sử dụng:
$ gcc hook.c -ldl -shared -o hook.so
$ LD_PRELOAD=$(pwd)/hook.so bash #this spawns a hooked shell
$ cat /dev/zero
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB