#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);