我尝试编写一个挂钩系统读取功能的内核模块。但是,一旦我尝试将函数的指针写入sys调用表,该模块就会被杀死。这是我的初始化函数:
int init_module(void)
{
// set rw/ro functions
patch_set_memory_rw = (void *) kallsyms_lookup_name("set_memory_rw");
patch_set_memory_ro = (void *) kallsyms_lookup_name("set_memory_ro");
if( patch_set_memory_rw == NULL ||
patch_set_memory_ro == NULL){
// something went wrong
printk(KERN_ALERT "ERROR WITH RW/RO!");
return 1;
}
// Inform that module is staring
//printk(KERN_INFO "Start Hook Read.");
syscall_table_pu64 = (void **)kallsyms_lookup_name("sys_call_table");
//for debugging
//printk(KERN_ALERT "syscall addr is %llx", syscall_table_pu64);
// swap read call with own read function
orig_read_p = syscall_table_pu64[__NR_read];
// set memory rw to change it
patch_set_memory_rw((uint64_t)syscall_table_pu64, 1);
syscall_table_pu64[__NR_read] = own_read_func;
return 0;
}
该错误发生在行中
syscall_table_pu64[__NR_read] = own_read_func;
有人知道我的问题是什么吗?我不知道。 错误消息是
RIP: init_module+0x76/0xa0 [hook_read] RSP: ffffa4ad46233c70
和
RIP: 0033:0x7f01920bb839
[ 3476.855557] RSP: 002b:00007fffcc925288 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
[ 3476.857431] RAX: ffffffffffffffda RBX: 0000559daa9f6790 RCX: 00007f01920bb839
[ 3476.858902] RDX: 0000000000000000 RSI: 0000559daa012c2e RDI: 0000000000000003
[ 3476.860550] RBP: 0000559daa012c2e R08: 0000000000000000 R09: 00007f019238e000
[ 3476.861959] R10: 0000000000000003 R11: 0000000000000246 R12: 0000000000000000
[ 3476.863399] R13: 0000559daa9f6760 R14: 0000000000000000 R15: 0000000000000000
[ 3476.864747] Code: 89 05 d7 22 00 00 48 8b 10 48 89 c7 be 01 00 00 00 48 8b 05 d5 22 00 00 48 89 15 b6 22 00 00 e8 71 3f 26 e2 48 8b 05 b2 22 00 00 <48> c7 00 00 f0 59 c0 31 c0 5d c3 48 c7 c7 40 00 5a c0 e8 f3 f1
答案 0 :(得分:0)
系统调用表是只读的。请勿尝试对其进行修改。
如果要挂接读/写操作,则需要选择另一种方式。您可能要研究的一种机制是kprobes系统。
答案 1 :(得分:-1)
我最终确定了我的问题。为了删除syscall的写保护,您可以(当然)不使用它的linux syscall:D让我花了3个小时才意识到这一点。而是使用
write_cr0 (read_cr0 () & (~ 0x10000));
启用写入和
write_cr0 (read_cr0 () | 0x10000);
使您的记忆再次只读。