为了拦截现有的系统调用,我们必须编写自己的假系统调用,然后让内核调用我们的假退出函数而不是原始的exit函数。为此,我们必须操纵系统调用表数组(sys_call_table)。使用sys_call_table数组,我们可以操纵它以使原始系统调用入口指向我们新的假系统调用。我们必须存储一个指向原始系统调用的指针,并在完成将消息打印到控制台后调用它。 interception.c包含拦截写系统调用的代码。请注意,伪写系统调用会调用原始的写系统调用。
****修改interception.c以计算调用写入系统调用的次数。
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/syscalls.h>
int counter = 0;
unsigned long **sys_call_table;
asmlinkage long (*ref_sys_write)(unsigned int fd, const char __user *buf, size_t count);
// fake write system call that calls the original write system call
asmlinkage long new_sys_write(unsigned int fd, const char __user *buf, size_t count)
{
return ref_sys_write(fd,buf ,count);
}
// this function returns the pointer of 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;
}
// This function disable the memory protection so that you can access any memory address
// This is done by modifying the value of the register cr0
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));
}
// This function enable the memory protection
// This is done by modifying the value of the register cr0
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));
}
// This function is executed when the module is loaded.
// 1. It gets the pointer of system call table
// 2. It disables page protection
// 3. It modifies the entry of the write system call
// 4. It enables page protection
static int __init interceptor_start(void)
{
if(!(sys_call_table = aquire_sys_call_table())) {
return -1;
}
disable_page_protection();
ref_sys_write = (void *)sys_call_table[__NR_write];
sys_call_table[__NR_write] = (unsigned long *)new_sys_write;
enable_page_protection();
return 0;
}
// This method is executed when the module is removed/unloaded
// 1. It disables page protection
// 2. It restores the entry of the write system call
// 3. It enables page protection
static void __exit interceptor_end(void)
{
if(!sys_call_table)
return;
disable_page_protection();
sys_call_table[__NR_write] = (unsigned long *)ref_sys_write;
enable_page_protection();
}
module_init(interceptor_start);
module_exit(interceptor_end);
也许这很容易,但我是系统调用和模块的初学者。 感谢您的帮助。