我正在尝试重新定义sys_open的系统调用并以此跟踪用户行为。 我使用Linux Kernel 4.13.0-041300。 到目前为止,这是我的代码
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/syscalls.h>
MODULE_LICENSE ("GPL");
//this is where the original sys_open call position will be saved
asmlinkage long (*original_open)(const char __user *filename, int flags, umode_t mode);
unsigned long **sys_call_table;
//this is to track how often my replaced function was called...
static int zeug = 0;
//this is my open function that i want to be replaced in the sys_call_table
asmlinkage long replaced_open(const char __user *filename, int flags, umode_t mode)
{
printk ("replaced wurde aufgerufen...\n");
zeug++;
return original_open(filename, flags, mode);
}
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 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));
}
//the function to get the system_call_table
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 *);
}
return NULL;
}
static int __init minit (void)
{
printk ("minit: startet...\n");
if(!(sys_call_table = aquire_sys_call_table()))
return -1;
printk ("minit: sys_call_table ersetzt...\n");
disable_page_protection();
{
//here i print the function name of the current function in sys_call_table
printk ("minit: eintrag vor ersetzen:%pF\n", sys_call_table[__NR_open]);
//here i store the real sys_open function and change to my func
original_open =(void * )xchg(&sys_call_table[__NR_open],(unsigned long *)replaced_open);
}
enable_page_protection();
return 0;
}
static void mexit (void)
{
printk ("mexit gestartet.\n");
printk ("Open was called %d times...\n",zeug);
if(!sys_call_table) return;
//here i print the stored function again
printk ("bei exit:%pF\n", sys_call_table[__NR_open]);
disable_page_protection();
{
//change back to original sys_open function
xchg(&sys_call_table[__NR_open], (unsigned long *)original_open);
}
printk ("nach zurücksetzen:%pF\n", sys_call_table[__NR_open]);
enable_page_protection();
}
module_init(minit);
module_exit(mexit);
我的计划: 在将该模块插入内核之后,对sys_open的每个系统调用都会“重定向”到我的函数replace_open中。该函数将计算其调用次数,然后调用原始的open函数。
在模块的rmmod之后,将再次使用原始的system_call打开。
看来,替换有效。所以在insmmod之后,我得到的结果是replace_open + 0x0 / 0x40 [kroot]。 就是说,原来的函数sys_open被替换为我的replace_open了吗? 删除模块后,我收到消息SyS_open + 0x0 / 0x20。
因此,似乎替换了作品。
我的问题是:我的replace_open函数看不到任何打印的消息。而且似乎计数不起作用。
感觉功能未正确替换。
您对我有帮助吗?