This is my first module of Kernel Hacking, after several days reading the book named Professional kernel Architecture by Wolfgang Mauerer and some other documentation, I was able to write my first kernel module.
The only thing it does is to intercept the system call mkdir
/*********************************************/
/* Francisco Garcia Garcia */
/* kernel system call interception */
/* Written on Ubuntu 14.04 Jessie/Sid */
/* Kernel mod name little bunny.c */
/* ignore the module name it is just for educational purposes*/
/*********************************************/
/*********************Libraries*************************************/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/syscalls.h>
#include <asm/errno.h>
#include <asm/unistd.h>
#include <linux/mman.h>
#include <asm/proto.h>
#include <asm/delay.h>
#include <linux/init.h>
#include <linux/highmem.h>
#include <linux/sched.h>
#include <linux/cred.h>
/********************************************************************/
/*The kernel system call table is no longer shared, so I had to look it up */
/* cat /proc/kallsyms | grep -i table | grep -i system */
/* so the address is: ffffffff81801400 *//
/*********************************************************************/
void **syscall_table = (void *)0xffffffff81801400;
/***real mkdir system call **/
asmlinkage long (*real_mkdir)(const char __user *pathname, mode_t __user mode);
/*** Fake system call Implementation ***/
asmlinkage long mkdir_intercept(const char __user *pathname, mode_t __user mode) {
printk("mkdir intercepted!!!!!");
return 0;
}
/**** Module macro to tell the kernel to use it **********************/
static int __init mkdir_init(void)
{
unsigned int l;
pte_t *pte; /*page table entry kernel has direct mapping to memory it does not use vma conversion*/
pte = lookup_address((long unsigned int)syscall_table,&l); /* get me the address for system tables*/
pte->pte |= _PAGE_RW; /*change the memory bit to read write*/
real_mkdir = syscall_table[__NR_mkdir]; /*save the original system call*/
syscall_table[__NR_mkdir]=mkdir_intercept; /*insert my face system call */
return 0;
}
/*** let's clean up when the module is unloaded from the kernel ***/
static void __exit mkdir_cleanup(void)
{
unsigned int l;
pte_t *pte; /*page table entry kernel has direct mapping to memory it does not use vma conversion*/
syscall_table[__NR_mkdir]=real_mkdir; /*restore original system call */
pte = lookup_address((long unsigned int)syscall_table,&l); /*get the address */
pte->pte &= ~ _PAGE_RW; /*set read write mode bit*/
return;
}
module_init(mkdir_init);
module_exit(mkdir_cleanup);
Enjoy