我需要用自己的实现替换标准系统调用(例如SYS_mkdir).
正如我在一些来源中读到的,包括Stackoverflow上的this question,自内核版本2.6以来,sys_call_table不是导出符号.
我尝试了以下代码:
#include <linux/module.h> #include <linux/kernel.h> #include <linux/unistd.h> #include <asm/syscall.h> int (*orig_mkdir)(const char *path); .... int init_module(void) { orig_mkdir=sys_call_table[__NR_mkdir]; sys_call_table[__NR_mkdir]=own_mkdir; printk("sys_mkdir replaced\n"); return(0); } ....
不幸的是我收到编译错误:
error: assignment of read-only location ‘sys_call_table[83]’
如何更换系统调用?
编辑:有没有内核修补的解决方案?
解决方法
这对我有用.
看到
Linux Kernel: System call hooking example
和
https://bbs.archlinux.org/viewtopic.php?id=139406
asmlinkage long (*ref_sys_open)(const char __user *filename,int flags,umode_t mode); asmlinkage long new_sys_open(const char __user *filename,umode_t mode) { return ref_sys_open(filename,flags,mode); } static unsigned long **aquire_sys_call_table(void) { unsigned long int offset = PAGE_OFFSET; unsigned long **sct; while (offset < ULLONG_MAX) { sct = (unsigned long **)offset; if (sct[__NR_close] == (unsigned long *) sys_close) return sct; offset += sizeof(void *); } print("Getting syscall table Failed. :("); return NULL; } // Crazy copypasted asm stuff. Could use linux function as well... // but this works and will work in the future they say. static void disable_page_protection(void) { unsigned long value; asm volatile("mov %%cr0,%0" : "=r" (value)); if(!(value & 0x00010000)) return; asm volatile("mov %0,%%cr0" : : "r" (value & ~0x00010000)); } static void enable_page_protection(void) { unsigned long value; asm volatile("mov %%cr0,%0" : "=r" (value)); if((value & 0x00010000)) return; asm volatile("mov %0,%%cr0" : : "r" (value | 0x00010000)); } static int __init rootkit_start(void) { //Hide me print("loaded"); if(!(sys_call_table = aquire_sys_call_table())) return -1; disable_page_protection(); { ref_sys_open = (void *)sys_call_table[__NR_open]; sys_call_table[__NR_open] = (unsigned long *)new_sys_open; } enable_page_protection(); return 0; } static void __exit rootkit_end(void) { print("exiting"); if(!sys_call_table) { return; } disable_page_protection(); { sys_call_table[__NR_open] = (unsigned long *)ref_sys_open; } enable_page_protection(); }