Syscall угон из ядра - PullRequest
       29

Syscall угон из ядра

0 голосов
/ 01 декабря 2018

Я хочу перехватить системный вызов open(), для проверки каждый раз, когда пользователь открывает файл, сообщение «OPEN IS!» Должно отображаться в dmesg.

Таблица системных вызовов иотображаются открытые вызовы в dmesg, но сообщение «ОТКРЫТЬ!» не отображается.Kernel v. 4.18

Хотелось бы узнать в чем проблема.Код:

unsigned long cr0;
static unsigned long *__sys_call_table;

typedef asmlinkage int (*orig_open_t)(const char *, int, int);

orig_open_t orig_open;

unsigned long *
get_syscall_table_bf(void)
{
    unsigned long *syscall_table;
    unsigned long int i;

    for (i = (unsigned long int)ksys_close; i < ULONG_MAX;
            i += sizeof(void *)) {
        syscall_table = (unsigned long *)i;

        if (syscall_table[__NR_close] == (unsigned long)ksys_close) {
            printk(KERN_INFO "syscall: %08lx\n", syscall_table);
            return syscall_table;
        }
    }
    return NULL;
}

asmlinkage int
hacked_open(const char *filename, int flags, int mode)
{
    printk(KERN_INFO "OPEN IS!\n");
    return 0;
}

static inline void
protect_memory(void)
{
    write_cr0(cr0);
}

static inline void
unprotect_memory(void)
{
    write_cr0(cr0 & ~0x00010000);
}

static int __init
diamorphine_init(void)
{
    __sys_call_table = get_syscall_table_bf();
    if (!__sys_call_table)
        return -1;

    cr0 = read_cr0();

    orig_open = (orig_open_t)__sys_call_table[__NR_open];

    unprotect_memory();
    __sys_call_table[__NR_open] = (unsigned long)hacked_open;
    printk(KERN_INFO "WE DO IT!\n");
    printk(KERN_INFO "hacked is: %08lx\n", hacked_open);
    protect_memory();

    return 0;
}

static void __exit
diamorphine_cleanup(void)
{
    unprotect_memory();
    __sys_call_table[__NR_open] = (unsigned long)orig_open;
    protect_memory();
}

module_init(diamorphine_init);
module_exit(diamorphine_cleanup);

MODULE_LICENSE("GPL");

1 Ответ

0 голосов
/ 04 декабря 2018

Полагаю, что-то не так в твоих зацепкахЛибо вы подключаете неправильное смещение таблицы системных вызовов, либо вы полностью выключены.Я не мог понять, почему явно вы начинаете поиск с помощью ksys_close (), особенно когда это встроенная функция.Вы должны попытаться найти символ таблицы системных вызовов следующим образом:

typedef void (*_syscall_ptr_t)(void); 
_syscall_ptr_t *_syscall_table = NULL; 
_syscall_table=(_syscall_ptr_t *)kallsyms_lookup_name("sys_call_table");

Другая (огромная) проблема, с которой я сталкиваюсь, это сброс CR0, который позволяет всему внутри вашей системы записывать в постоянную память навремя написания, вместо того, чтобы переходить по страницам и устанавливать бит W на конкретной странице, которую вы собираетесь редактировать.

Еще один небольшой совет: вам нужно завершить ловушку, чтобы перенаправить к открытому оригиналуСистемный вызов.В противном случае вы получите полное чтение системы из STDIN для каждого вновь открытого файлового дескриптора (который, в конечном итоге, убьет вашу систему)

...