据我了解,由于 KASLR ,该模块无法使用系统调用表地址。/boot/System.map-$(uname -r)
通过启动nokaslr
,模块工作。解决了这个问题后,我继续实际挂钩 kill 功能,但不能;insmod
再次在模块加载时返回“Killed”,而dmesg
现在记录写访问权限错误,该错误发生在强调的行上。
我认为取消控制寄存器上的写保护位的目的是“取消写保护”。除了那个(或我的代码)之外,还有什么能阻止内核模块覆盖系统调用表吗?
代码
#include <linux/module.h>
#include <linux/kernel.h>
typedef asmlinkage int (*sys_kill_ptr_t)(pid_t, int);
static sys_kill_ptr_t sys_kill_ptr;
static unsigned long *syscall_table;
static inline void set_cr0_wp_bit(void) { write_cr0(read_cr0() & ~0x1000); }
static inline void unset_cr0_wp_bit(void) { write_cr0(read_cr0() | 0x1000); }
asmlinkage int hooked_kill(pid_t pid, int sig)
{
printk(KERN_INFO "[+] LKM: hooked_kill called\n");
return sys_kill_ptr(pid, sig);
}
static int __init lkm_init(void)
{
printk("[+] LKM: init\n");
// System call table address in /boot/System.map-$(uname -r)
syscall_table = (unsigned long *)0xffffffff81c002a0;
printk(KERN_EMERG "[+] LKM: syscall_table @ 0x%lx\n",
(unsigned long)syscall_table);
sys_kill_ptr = (sys_kill_ptr_t)syscall_table[__NR_kill];
printk(KERN_EMERG "[+] LKM: syscall_table[__NR_kill] @ 0x%lx\n",
(unsigned long)sys_kill_ptr);
set_cr0_wp_bit();
/* Error */
syscall_table[__NR_kill] = (unsigned long)hooked_kill;
/* Error */
unset_cr0_wp_bit();
printk(KERN_EMERG "[+] LKM: syscall_table[__NR_kill] hooked @ %lx\n",
(unsigned long)hooked_kill);
return 0;
}
static void __exit lkm_exit(void)
{
set_cr0_wp_bit();
/* Error */
syscall_table[__NR_kill] = (unsigned long)sys_kill_ptr;
/* Error */
unset_cr0_wp_bit();
printk("[-] LKM: exit\n");
}
module_init(lkm_init);
module_exit(lkm_exit);
dmesg
[ 4218.114119] [+] LKM: init
[ 4218.115931] [+] LKM: syscall_table @ 0xffffffff81c002a0
[ 4218.117025] [+] LKM: syscall_table[__NR_kill] @ 0xffffffff81092fa0
[ 4218.118087] BUG: unable to handle page fault for address: ffffffff81c00490
[ 4218.119159] #PF: supervisor write access in kernel mode
[ 4218.120267] #PF: error_code(0x0003) - permissions violation