miércoles, 27 de agosto de 2014

Kernel "Hax" (kernel hacks)

Hello
          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