#include<linux/init.h>

#include<linux/module.h>

#include<linux/moduleparam.h>

#include<linux/unistd.h>

#include<linux/sched.h>

#include<linux/syscalls.h>

#include<linux/string.h>

#include<linux/fs.h>

#include<linux/fdtable.h>

#include<linux/uaccess.h>

#include <linux/kallsyms.h>

#include<linux/rtc.h>

#include<linux/vmalloc.h>

#include <linux/slab.h>

//module macros

MODULE_LICENSE("GPL");

MODULE_DESCRIPTION("hook sys_mkdir");

unsigned long _sys_call_table = 0;

static void*

get_lstar_dosys_addr(void){

unsigned long lstar;

// temp variables for scan

unsigned int i;

unsigned char *off;

rdmsrl(MSR_LSTAR, lstar);

// print out int 0x80 handler

printk("[+] entry_SYSCALL_64 is at 0x%lx\n", lstar);

// scan for known pattern(0xff14c5xx)

// pattern is just before sys_call_table address

for(i = 0; i <= PAGE_SIZE; i++) {

off = (char*)lstar + i;

if(*(off) == 0x48 && *(off+1) == 0x89 && *(off+2) == 0xe6) {

return (off + 3); //call do_syscall_64

}

}

return NULL;

}

static void*

get_lstar_dosys(void)

{

unsigned long* lstar_dosys_addr = get_lstar_dosys_addr();

if(lstar_dosys_addr != NULL) {

printk("[+] call_do_syscall_64 at: 0x%lx\n", lstar_dosys_addr);

unsigned int offset = *(unsigned int*)((char*)lstar_dosys_addr + 1);

printk("[+] offset is: 0x%08x\n", offset);

unsigned long base = 0xffffffff00000000;

return (void*)(base | ((unsigned long)lstar_dosys_addr + 5 + offset));

}

return NULL;

}

static void*

get_sys_sct_addr(unsigned long* do_syscall_64_addr)

{

unsigned char* off;

int i;

for(i = 0; i <= PAGE_SIZE; i++) {

off = (char*)do_syscall_64_addr + i;

if(*(off) == 0x48 && *(off+1) == 0x8b && *(off+2) == 0x04 && *(off+3) == 0xfd) {

return (off+4);

}

}

return NULL;

}

static void*

get_sys_sct(unsigned long* do_syscall_64_addr)

{

unsigned long* sct_addr = get_sys_sct_addr(do_syscall_64_addr);

if(!sct_addr){

return NULL;

}

unsigned int offset = *(unsigned int*)(sct_addr);

unsigned long base = 0xffffffff00000000;

return (void*)(base | offset);

}

//hooked execve

static int hook_execve_init(void){

printk("[+] Finding sys_call_table\n");

unsigned long* do_syscall_64_addr = 0;

do_syscall_64_addr = get_lstar_dosys();

if(!do_syscall_64_addr){

printk("[x] Failed to find do_syscall_64_addr\n");

return 0;

}

printk("[+] Found do_syscall_64_addr at: 0x%lx\n", do_syscall_64_addr);

_sys_call_table = get_sys_sct(do_syscall_64_addr);

if(!_sys_call_table) {

printk("[x] Failed to find sys_call_table\n");

return 0;

}

printk("[+] Found sys_call_table at: 0x%lx\n", _sys_call_table);

return 0;

}

// initialize the module

static int hooked_init(void) {

get_lstar_dosys_addr();

return 0;

}

static void hooked_exit(void) {

 

}

/*entry/exit macros*/

module_init(hooked_init);

module_exit(hooked_exit);