├── src ├── board_generator.py ├── schk_ioctl.h ├── Makefile ├── debug.h ├── test.c ├── syscall_hook.c └── asm.h └── README.md /src/board_generator.py: -------------------------------------------------------------------------------- 1 | for i in range(310): 2 | print " LANDING_SYSCALL(%d)\\"%i -------------------------------------------------------------------------------- /src/schk_ioctl.h: -------------------------------------------------------------------------------- 1 | #define SCHK_MAGIC_NUMBER 's' 2 | #define SCHK_CMD_SET_FLAG _IOW(SCHK_MAGIC_NUMBER,0,unsigned long long) 3 | #define SCHK_CMD_GET_FLAG _IOW(SCHK_MAGIC_NUMBER,1,unsigned long long) 4 | 5 | #define SCHK_FLAG_INHERIT 2 6 | #define SCHK_FLAG_ENABLE 1 7 | #define SCHK_FLAG_ENABLE_ON_EXEC 4 -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += schk.o 2 | schk-objs += syscall_hook.o base64.o 3 | KERNELDR := /usr/src/linux-headers-$(shell uname -r) 4 | 5 | PWD := $(shell pwd) 6 | 7 | modules: 8 | $(MAKE) -C $(KERNELDR) M=$(PWD) modules 9 | 10 | moduels_install: 11 | $(MAKE) -C $(KERNELDR) M=$(PWD) modules_install 12 | 13 | test: 14 | gcc --static -otest test.c -lpthread 15 | clean: 16 | rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.symvers *.o.ur-detected *.order .cache.mk test 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Linux system call hook framework 2 | 3 | ## How it works 4 | The framework hook system call by rewriting system call table(for pre-syscall hooking) and return address of system call(for post-syscall hooking). 5 | 6 | The framework is well tested unber ubuntu, imagine that the newest commit is made under the newest ubuntu18.04 with this system call hook framework installed 7 | 8 | ## Usage 9 | put your own thing into do_something_enable/do_something_disable/do_something_pre/do_something_post function to perform pre&post system call hooking. 10 | 11 | ## knwon issue 12 | Kernel crash if you remove the kernel module while a system call is ungoing. 13 | This is due to the return address of system call has been modified for hooking, if the module unload, the return address of ungoing system call will be a unmapped address which will lead to a crash. This bug will not affect the usage of the framework, so I decide to work out this issue in the future. -------------------------------------------------------------------------------- /src/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEBUG_H__ 2 | #define __DEBUG_H__ 3 | 4 | 5 | #define ULL unsigned long long 6 | #define SYSNO unsigned int 7 | 8 | 9 | #define KERNEL 10 | 11 | #ifdef KERNEL 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #else 18 | #include 19 | #endif 20 | 21 | 22 | /********** Finished Handle Debug info **********/ 23 | #define DBG 24 | #ifdef DBG 25 | #ifdef KERNEL 26 | #define dbg_err(msg...) do { \ 27 | printk(KERN_INFO "\033[1;31m"); \ 28 | printk(KERN_INFO msg); \ 29 | printk(KERN_INFO "\033[0m\n"); \ 30 | } while(0) 31 | #define dbg_info(msg...) do { \ 32 | printk(KERN_INFO "\033[1;32m"); \ 33 | printk(KERN_INFO msg); \ 34 | printk(KERN_INFO "\033[0m\n"); \ 35 | } while(0) 36 | #else 37 | #define dbg_err(msg...) do { \ 38 | printf("\033[1;31m"); \ 39 | printf(msg); \ 40 | printf("\033[0m\n"); \ 41 | } while(0) 42 | #define dbg_info(msg...) do { \ 43 | printf("\033[1;32m"); \ 44 | printf(msg); \ 45 | printf("\033[0m\n"); \ 46 | } while(0) 47 | #endif 48 | #else 49 | #define dbg_err(msg...) do{} while(0) 50 | #define dbg_info(msg...) do{} while(0) 51 | #endif 52 | 53 | #ifdef KERNEL 54 | #define SRC char 55 | #define DST unsigned char 56 | #define COPY(src, dst, size) (memcpy(src, dst, size)) 57 | #define malloc(sz) (kmalloc(sz, GFP_KERNEL)) 58 | #define realloc(ptr, sz) (krealloc(ptr, sz, GFP_KERNEL)) 59 | #define FREE(sz) kfree(sz) 60 | #else 61 | #include 62 | #include 63 | #define SRC unsigned char 64 | #define DST unsigned char 65 | #define COPY(src, dst, size) (memcpy(src, dst, size)) 66 | #define FREE(sz) free(sz) 67 | #endif 68 | 69 | #endif // end define __DEBUG_H__ 70 | -------------------------------------------------------------------------------- /src/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include "schk_ioctl.h" 10 | 11 | 12 | #if defined(__i386__) 13 | 14 | static __inline__ unsigned long long rdtsc(void) 15 | { 16 | unsigned long long int x; 17 | __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); 18 | return x; 19 | } 20 | #elif defined(__x86_64__) 21 | 22 | 23 | static __inline__ unsigned long long rdtsc(void) 24 | { 25 | unsigned hi, lo; 26 | __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); 27 | return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 ); 28 | } 29 | 30 | #elif defined(__powerpc__) 31 | 32 | 33 | static __inline__ unsigned long long rdtsc(void) 34 | { 35 | unsigned long long int result=0; 36 | unsigned long int upper, lower,tmp; 37 | __asm__ volatile( 38 | "0: \n" 39 | "\tmftbu %0 \n" 40 | "\tmftb %1 \n" 41 | "\tmftbu %2 \n" 42 | "\tcmpw %2,%0 \n" 43 | "\tbne 0b \n" 44 | : "=r"(upper),"=r"(lower),"=r"(tmp) 45 | ); 46 | result = upper; 47 | result = result<<32; 48 | result = result|lower; 49 | 50 | return(result); 51 | } 52 | 53 | #endif 54 | int has_debugger() 55 | { 56 | char buff1[24], buff2[16]; 57 | FILE* f; 58 | 59 | snprintf(buff1, 24, "/proc/%d/status", getppid()); 60 | f = fopen(buff1, "r"); 61 | // the first line in status is name 62 | fgets(buff2, 16, f); 63 | fclose(f); 64 | 65 | int has_gdb = (strstr(buff2, "gdb") || strstr(buff2, "rr") || strstr(buff2, "strace")); 66 | if (has_gdb == 0) { 67 | printf("no debugger is attached\n"); 68 | } else { 69 | printf("debugger attached!\n"); 70 | } 71 | return has_gdb; 72 | } 73 | 74 | void * print_a(void *a){ 75 | char buf[100]; 76 | 77 | int fr=open("/dev/urandom",O_RDONLY); 78 | read(fr,buf,100); 79 | close(fr); 80 | for(int i = 0;i < 10; i++){ 81 | 82 | if(has_debugger()) 83 | puts("thread_a: debugger found"); 84 | else 85 | puts("thread_a: good job"); 86 | printf("thread_a: time = %llx\n",rdtsc()); 87 | } 88 | return NULL; 89 | 90 | } 91 | 92 | // 线程B 方法 93 | void * print_b(void *b){ 94 | char buf[100]; 95 | int fr=open("/dev/urandom",O_RDONLY); 96 | read(fr,buf,100); 97 | close(fr); 98 | for(int i=0;i<10;i++){ 99 | 100 | if(has_debugger()) 101 | puts("thread_b: debugger found"); 102 | else 103 | puts("thread_b: good job"); 104 | printf("thread_b time = %llx\n",rdtsc()); 105 | } 106 | return NULL; 107 | } 108 | int main(){ 109 | char buf[100]; 110 | int fd=open("/dev/schk",O_RDONLY); 111 | if(fd<0) 112 | perror("open"); 113 | int pid=getpid(); 114 | printf("%d %d\n",fd,pid); 115 | unsigned long long config=(SCHK_FLAG_INHERIT|SCHK_FLAG_ENABLE)<<16 | pid; 116 | if(ioctl(fd,SCHK_CMD_SET_FLAG,&config)) 117 | perror("ioctl1"); 118 | int fr=open("/dev/urandom",O_RDONLY); 119 | read(fr,buf,100); 120 | 121 | pthread_t t0; 122 | pthread_t t1; 123 | // cpu_set_t set; 124 | // CPU_SET(0,&set); 125 | // if (sched_setaffinity(getpid(), sizeof(set), &set) == -1) 126 | // perror("sched_setaffinity"); 127 | // 128 | // 创建线程A 129 | if(pthread_create(&t0, NULL, print_a, NULL) == -1){ 130 | puts("fail to create pthread t0"); 131 | exit(1); 132 | } 133 | 134 | if(pthread_create(&t1, NULL, print_b, NULL) == -1){ 135 | puts("fail to create pthread t1"); 136 | exit(1); 137 | } 138 | 139 | // 等待线程结束 140 | void * result; 141 | if(pthread_join(t0, &result) == -1){ 142 | puts("fail to recollect t0"); 143 | exit(1); 144 | } 145 | 146 | if(pthread_join(t1, &result) == -1){ 147 | puts("fail to recollect t1"); 148 | exit(1); 149 | } 150 | 151 | 152 | 153 | puts("hello world"); 154 | config=pid; 155 | if(ioctl(fd,SCHK_CMD_SET_FLAG,&config)) 156 | perror("ioctl2"); 157 | return 0; 158 | } 159 | 160 | /* 161 | / # insmod syscall_hook.ko 162 | [ 6.401017] syscall_hook: loading out-of-tree module taints kernel. 163 | [ 6.405587] syscall_hook: module verification failed: signature and/or required key missing - tainting kernel 164 | [ 6.413057] 165 | [ 6.413058] schk reigistered, minor 55 166 | [ 6.416447] 167 | [ 6.417535] 168 | [ 6.417536] prepare hooking 169 | [ 6.420714] 170 | [ 6.423289] 171 | [ 6.423290] kernel version found: 4.15.0-43-generic 172 | [ 6.427783] 173 | [ 6.429013] 174 | [ 6.429014] 175 | [ 6.429014] Path /proc/kallsyms 176 | [ 6.432904] 177 | [ 6.711773] 178 | [ 6.711774] syscall table found: ffffffff878001a0 179 | [ 6.715132] 180 | [ 6.715974] 181 | [ 6.715975] pte 182 | [ 6.718716] 183 | [ 6.719615] 184 | [ 6.719616] pte 185 | [ 6.722563] 186 | [ 6.723790] 187 | [ 6.723791] syscall hooked 188 | [ 6.725171] 189 | / # ./test 190 | [ 8.659927] 191 | [ 8.659929] syscall hook enabled at pid 123 192 | [ 8.661545] 193 | [ 8.665216] 194 | [ 8.665218] post-syscall: 16 195 | [ 8.666509] 196 | [ 8.670673] 197 | [ 8.670675] pre-syscall: 257 198 | [ 8.672980] 199 | [ 8.677343] 200 | [ 8.677345] post-syscall: 257 201 | [ 8.678425] 202 | [ 8.681005] 203 | [ 8.681006] pre-syscall: 0 204 | [ 8.682062] 205 | [ 8.684639] random: test: uninitialized urandom read (100 bytes read) 206 | [ 8.690408] 207 | [ 8.690410] post-syscall: 0 208 | [ 8.692296] 209 | [ 8.698876] 210 | [ 8.709584] pre-syscall: 1 211 | [ 8.710733] 212 | hello world 213 | [ 8.713972] 214 | [ 8.713973] post-syscall: 1 215 | [ 8.715102] 216 | [ 8.718263] 217 | [ 8.718268] pre-syscall: 16 218 | [ 8.720754] 219 | [ 8.724030] 220 | [ 8.724032] syscall hook disabled at pid 123 221 | [ 8.725843] 222 | / # 223 | */ 224 | -------------------------------------------------------------------------------- /src/syscall_hook.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "asm.h" 30 | #include "debug.h" 31 | #include "schk_ioctl.h" 32 | 33 | void *syscall_table; 34 | void *syscall_table_backup; 35 | int sys_found = 0; 36 | void *(g_ret_addr[65537]); 37 | int g_syscall_num[65537]; 38 | unsigned long g_syscall_argv[65537][7]; 39 | int g_schk_flag[65537]; 40 | unsigned long g_retval[65537]; 41 | void* presyscall_hook_addr; 42 | void* postsyscall_hook_addr; 43 | int make_rw(void* address) { 44 | unsigned int level; 45 | pte_t *pte = lookup_address((long unsigned int)address, &level); 46 | dbg_info("pte <%lx>\n", (unsigned long)pte); 47 | 48 | if (!pte) { /* NULL pointer error. */ 49 | return 1; 50 | } 51 | 52 | if (pte->pte & ~_PAGE_RW) 53 | pte->pte |= _PAGE_RW; 54 | 55 | return 0; 56 | } 57 | 58 | int make_ro(void* address) { 59 | unsigned int level; 60 | pte_t *pte = lookup_address((long unsigned int)address, &level); 61 | 62 | if (!pte) { /* NULL pointer error. */ 63 | return 1; 64 | } 65 | 66 | dbg_info("pte <%lx>\n", (unsigned long)pte); 67 | 68 | pte->pte &= ~_PAGE_RW; 69 | 70 | return 0; 71 | } 72 | 73 | char *search_file(char *buf) { 74 | 75 | struct file *f; 76 | char *ver; 77 | mm_segment_t oldfs; 78 | 79 | oldfs = get_fs(); 80 | set_fs (KERNEL_DS); 81 | 82 | f = filp_open(PROC_V, O_RDONLY, 0); 83 | 84 | if ( IS_ERR(f) || ( f == NULL )) { 85 | 86 | return NULL; 87 | 88 | } 89 | 90 | memset(buf, 0, MAX_LEN); 91 | 92 | vfs_read(f, buf, MAX_LEN, &f->f_pos); 93 | 94 | ver = strsep(&buf, " "); 95 | ver = strsep(&buf, " "); 96 | ver = strsep(&buf, " "); 97 | 98 | filp_close(f, 0); 99 | set_fs(oldfs); 100 | 101 | return ver; 102 | 103 | } 104 | 105 | static int find_sys_call_table (char *kern_ver) { 106 | 107 | char buf[MAX_LEN]; 108 | int i = 0; 109 | char *filename; 110 | char *p; 111 | struct file *f = NULL; 112 | 113 | mm_segment_t oldfs; 114 | 115 | oldfs = get_fs(); 116 | set_fs (KERNEL_DS); 117 | 118 | 119 | #ifdef BOOT_PATH 120 | filename = kmalloc(strlen(kern_ver)+strlen(BOOT_PATH)+1, GFP_KERNEL); 121 | if ( filename == NULL ) { 122 | return -1; 123 | } 124 | 125 | memset(filename, 0, strlen(BOOT_PATH)+strlen(kern_ver)+1); 126 | strncpy(filename, BOOT_PATH, strlen(BOOT_PATH)); 127 | strncat(filename, kern_ver, strlen(kern_ver)); 128 | #else 129 | filename = KALLSYMS; 130 | #endif 131 | 132 | dbg_info("\nPath %s\n", filename); 133 | 134 | f = filp_open(filename, O_RDONLY, 0); 135 | 136 | if ( IS_ERR(f) || ( f == NULL )) { 137 | return -1; 138 | } 139 | 140 | memset(buf, 0x0, MAX_LEN); 141 | 142 | p = buf; 143 | while (vfs_read(f, p+i, 1, &f->f_pos) == 1) { 144 | if ( p[i] == '\n' || i == 255 ) { 145 | i = 0; 146 | if ( (strstr(p, "sys_call_table")) != NULL ) { 147 | char *sys_string; 148 | sys_string = kmalloc(MAX_LEN, GFP_KERNEL); 149 | if ( sys_string == NULL ) { 150 | filp_close(f, 0); 151 | set_fs(oldfs); 152 | kfree(filename); 153 | return -1; 154 | } 155 | memset(sys_string, 0, MAX_LEN); 156 | strncpy(sys_string, strsep(&p, " "), MAX_LEN); 157 | syscall_table = (void *) simple_strtoll(sys_string, NULL, 16); 158 | kfree(sys_string); 159 | break; 160 | } 161 | memset(buf, 0x0, MAX_LEN); 162 | continue; 163 | } 164 | i++; 165 | } 166 | 167 | filp_close(f, 0); 168 | set_fs(oldfs); 169 | 170 | #ifdef BOOT_PATH 171 | kfree(filename); 172 | #endif 173 | 174 | return 0; 175 | } 176 | int do_something_enable(pid_t pid){ 177 | //do something here 178 | dbg_info("syscall hook enabled at pid %d",pid); 179 | return 0; 180 | } 181 | int do_something_disable(pid_t pid){ 182 | //do something here 183 | dbg_info("syscall hook disabled at pid %d",pid); 184 | return 0; 185 | } 186 | int do_something_pre(void){ 187 | //do something here 188 | dbg_info("pre-syscall: %d ", g_syscall_num[current->pid]); 189 | return 0; 190 | } 191 | int do_something_post(void){ 192 | //do something here 193 | dbg_info("post-syscall: %d ", g_syscall_num[current->pid]); 194 | if((g_syscall_num[current->pid]==__NR_exit || g_syscall_num[current->pid]==__NR_exit)){ 195 | g_schk_flag[current->pid]=0; 196 | do_something_disable(current->pid); 197 | } 198 | else if((g_syscall_num[current->pid]==__NR_fork || g_syscall_num[current->pid]==__NR_vfork|| g_syscall_num[current->pid]==__NR_clone)){ 199 | if((int)g_retval[current->pid]>0&&g_schk_flag[current->pid]&SCHK_FLAG_INHERIT){ 200 | g_schk_flag[g_retval[current->pid]]|=SCHK_FLAG_ENABLE; 201 | g_schk_flag[g_retval[current->pid]]|=SCHK_FLAG_INHERIT; 202 | do_something_enable(g_retval[current->pid]); 203 | } 204 | } 205 | else if((g_syscall_num[current->pid]==__NR_execve&&g_schk_flag[current->pid]&SCHK_FLAG_ENABLE_ON_EXEC)){ 206 | g_schk_flag[current->pid]|=SCHK_FLAG_ENABLE; 207 | do_something_enable(g_retval[current->pid]); 208 | 209 | } 210 | return 0; 211 | } 212 | asmlinkage void syscall_landingboard(void){ 213 | LANDING_BOARD 214 | } 215 | 216 | asmlinkage void postsyscall_hook(void){ 217 | unsigned long retval; 218 | void* ret_addr; 219 | HOOK_START_POSTSYSCALL 220 | g_retval[current->pid]=retval; 221 | if(g_schk_flag[current->pid]){ 222 | do_something_post(); 223 | } 224 | ret_addr=g_ret_addr[current->pid]; 225 | g_ret_addr[current->pid]=0; 226 | HOOK_END_POSTSYSCALL 227 | } 228 | asmlinkage void presyscall_hook(void){ 229 | int syscall_num; 230 | void* syscall_addr; 231 | void* ret_addr; 232 | unsigned long syscall_argv[7]; 233 | HOOK_START_PRESYSCALL 234 | memcpy(g_syscall_argv[current->pid],syscall_argv,sizeof(syscall_argv)); 235 | if(g_schk_flag[current->pid]){ 236 | g_ret_addr[current->pid]=ret_addr; 237 | g_syscall_num[current->pid]=syscall_num; 238 | ret_addr=postsyscall_hook_addr; 239 | do_something_pre(); 240 | } 241 | HOOK_END_PRESYSCALL 242 | 243 | } 244 | 245 | static int install_hook(void){ 246 | 247 | char *kern_ver; 248 | char *buf; 249 | int i,tmp; 250 | unsigned entry_index[SYSCALL_MAX]; 251 | 252 | 253 | buf = kmalloc(MAX_LEN, GFP_KERNEL); 254 | if ( buf == NULL ) { 255 | sys_found = 1; 256 | return -1; 257 | } 258 | 259 | dbg_info("prepare hooking\n"); 260 | 261 | kern_ver = search_file(buf); 262 | 263 | if ( kern_ver == NULL ) { 264 | sys_found = 1; 265 | return -1; 266 | } 267 | 268 | dbg_info("kernel version found: %s\n", kern_ver); 269 | 270 | if ( find_sys_call_table(kern_ver) == -1 ) { 271 | sys_found = 1; 272 | return -1; 273 | } 274 | 275 | sys_found = 0; 276 | dbg_info("syscall table found: %lx\n", (unsigned long)syscall_table); 277 | 278 | make_rw(syscall_table); 279 | 280 | syscall_table_backup = (void*) kmalloc(SYSCALL_MAX*sizeof(void*), GFP_KERNEL); 281 | 282 | memcpy(syscall_table_backup, syscall_table, SYSCALL_MAX*sizeof(void*)); 283 | 284 | tmp=0; 285 | for(i = 0 ; tmp < SYSCALL_MAX; i++){ 286 | if(!memcmp((char *)syscall_landingboard+i,"\x90\x90\x90\x90",4)){ 287 | entry_index[tmp++] = i + 4; 288 | i += 4; 289 | } 290 | } 291 | for (i = 0; i < SYSCALL_MAX; i++) { 292 | ((void **)syscall_table)[i] = (void *)((char *)syscall_landingboard+entry_index[i]); 293 | } 294 | 295 | presyscall_hook_addr=presyscall_hook; 296 | postsyscall_hook_addr=postsyscall_hook; 297 | while(memcmp(presyscall_hook_addr,"\x90\x90\x90\x90",4)) presyscall_hook_addr=(char*)presyscall_hook_addr+4; 298 | while(memcmp(postsyscall_hook_addr,"\x90\x90\x90\x90",4)) postsyscall_hook_addr=(char*)postsyscall_hook_addr+4; 299 | dbg_info("presyscall_hook_addr = %lx %lx" ,(unsigned long)presyscall_hook_addr,(unsigned long)presyscall_hook); 300 | dbg_info("postsyscall_hook_addr = %lx %lx" ,(unsigned long)postsyscall_hook_addr,(unsigned long)postsyscall_hook); 301 | 302 | make_ro(syscall_table); 303 | dbg_info("syscall hooked"); 304 | kfree(buf); 305 | return 0; 306 | } 307 | 308 | 309 | static long schk_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 310 | { 311 | unsigned long long config=0; 312 | unsigned long long flag=0; 313 | pid_t pid=0; 314 | 315 | switch(cmd){ 316 | case SCHK_CMD_SET_FLAG: 317 | copy_from_user(&config,(void*)arg,sizeof(unsigned long long)); 318 | pid=config&0xffff; 319 | flag=config>>16; 320 | if(pid>65536) 321 | return EINVAL; 322 | if((g_schk_flag[pid]&1)==0&&(flag&1)){ 323 | g_schk_flag[pid]=flag; 324 | do_something_enable(pid); 325 | } 326 | else if((g_schk_flag[pid]&1)&&(flag&1==0)){ 327 | g_schk_flag[pid]=flag; 328 | do_something_disable(pid); 329 | } 330 | break; 331 | case SCHK_CMD_GET_FLAG: 332 | copy_from_user(&config,(void*)arg,sizeof(unsigned long long)); 333 | pid=config&0xffff; 334 | if(pid>65536) 335 | return EINVAL; 336 | config=(g_schk_flag[pid]<<16|pid); 337 | copy_to_user((void*)arg,&config,sizeof(unsigned long long)); 338 | break; 339 | default: 340 | dbg_err("unknown ioctl command"); 341 | } 342 | return 0; 343 | } 344 | 345 | static int schk_open(struct inode *inode, struct file *filp) 346 | { 347 | return 0; 348 | } 349 | static int schk_release(struct inode *inode, struct file *filp) 350 | { 351 | return 0; 352 | } 353 | 354 | static struct file_operations schk_fops = { 355 | 356 | .owner = THIS_MODULE, 357 | .unlocked_ioctl = schk_ioctl, 358 | .open = schk_open, 359 | .release = schk_release 360 | }; 361 | static struct miscdevice schk = { 362 | .minor = MISC_DYNAMIC_MINOR, 363 | .name = "schk", 364 | .fops = &schk_fops, 365 | }; 366 | 367 | static int __init syscall_hook_init(void) { 368 | int retval; 369 | retval = misc_register(&schk); 370 | if(retval) 371 | return retval; 372 | dbg_info("schk reigistered, minor %i\n",schk.minor); 373 | retval = install_hook(); 374 | if(retval){ 375 | misc_deregister(&schk); 376 | return retval; 377 | } 378 | return 0; 379 | 380 | } 381 | 382 | 383 | static void __exit syscall_hook_exit(void) { 384 | misc_deregister(&schk); 385 | if ( sys_found == 0 ) { 386 | make_rw(syscall_table); 387 | memcpy(syscall_table, syscall_table_backup, SYSCALL_MAX*sizeof(void*)); 388 | dbg_info("syscall table restored."); 389 | kfree(syscall_table_backup); 390 | dbg_info("backup syscall table freed."); 391 | make_ro(syscall_table); 392 | } 393 | dbg_info("\nsyscall unhooked\n"); 394 | return; 395 | } 396 | 397 | 398 | module_init(syscall_hook_init); 399 | module_exit(syscall_hook_exit); 400 | 401 | MODULE_LICENSE("GPL"); 402 | 403 | -------------------------------------------------------------------------------- /src/asm.h: -------------------------------------------------------------------------------- 1 | 2 | #define PROC_V "/proc/version" 3 | #define KALLSYMS "/proc/kallsyms" 4 | 5 | #define MAX_LEN (256) 6 | #define SYSCALL_MAX (310) 7 | 8 | #define LANDING_SYSCALL(x) \ 9 | __asm__ __volatile__ (\ 10 | "nop\n\t"\ 11 | "nop\n\t"\ 12 | "nop\n\t"\ 13 | "nop\n\t"\ 14 | "push %0\n\t"\ 15 | "movq (presyscall_hook_addr), %%rax\n\t"\ 16 | "push %%rax\n\t"\ 17 | "ret\n\t"\ 18 | :\ 19 | :"i"(x)\ 20 | :\ 21 | ); 22 | #define LANDING_BOARD\ 23 | LANDING_SYSCALL(0)\ 24 | LANDING_SYSCALL(1)\ 25 | LANDING_SYSCALL(2)\ 26 | LANDING_SYSCALL(3)\ 27 | LANDING_SYSCALL(4)\ 28 | LANDING_SYSCALL(5)\ 29 | LANDING_SYSCALL(6)\ 30 | LANDING_SYSCALL(7)\ 31 | LANDING_SYSCALL(8)\ 32 | LANDING_SYSCALL(9)\ 33 | LANDING_SYSCALL(10)\ 34 | LANDING_SYSCALL(11)\ 35 | LANDING_SYSCALL(12)\ 36 | LANDING_SYSCALL(13)\ 37 | LANDING_SYSCALL(14)\ 38 | LANDING_SYSCALL(15)\ 39 | LANDING_SYSCALL(16)\ 40 | LANDING_SYSCALL(17)\ 41 | LANDING_SYSCALL(18)\ 42 | LANDING_SYSCALL(19)\ 43 | LANDING_SYSCALL(20)\ 44 | LANDING_SYSCALL(21)\ 45 | LANDING_SYSCALL(22)\ 46 | LANDING_SYSCALL(23)\ 47 | LANDING_SYSCALL(24)\ 48 | LANDING_SYSCALL(25)\ 49 | LANDING_SYSCALL(26)\ 50 | LANDING_SYSCALL(27)\ 51 | LANDING_SYSCALL(28)\ 52 | LANDING_SYSCALL(29)\ 53 | LANDING_SYSCALL(30)\ 54 | LANDING_SYSCALL(31)\ 55 | LANDING_SYSCALL(32)\ 56 | LANDING_SYSCALL(33)\ 57 | LANDING_SYSCALL(34)\ 58 | LANDING_SYSCALL(35)\ 59 | LANDING_SYSCALL(36)\ 60 | LANDING_SYSCALL(37)\ 61 | LANDING_SYSCALL(38)\ 62 | LANDING_SYSCALL(39)\ 63 | LANDING_SYSCALL(40)\ 64 | LANDING_SYSCALL(41)\ 65 | LANDING_SYSCALL(42)\ 66 | LANDING_SYSCALL(43)\ 67 | LANDING_SYSCALL(44)\ 68 | LANDING_SYSCALL(45)\ 69 | LANDING_SYSCALL(46)\ 70 | LANDING_SYSCALL(47)\ 71 | LANDING_SYSCALL(48)\ 72 | LANDING_SYSCALL(49)\ 73 | LANDING_SYSCALL(50)\ 74 | LANDING_SYSCALL(51)\ 75 | LANDING_SYSCALL(52)\ 76 | LANDING_SYSCALL(53)\ 77 | LANDING_SYSCALL(54)\ 78 | LANDING_SYSCALL(55)\ 79 | LANDING_SYSCALL(56)\ 80 | LANDING_SYSCALL(57)\ 81 | LANDING_SYSCALL(58)\ 82 | LANDING_SYSCALL(59)\ 83 | LANDING_SYSCALL(60)\ 84 | LANDING_SYSCALL(61)\ 85 | LANDING_SYSCALL(62)\ 86 | LANDING_SYSCALL(63)\ 87 | LANDING_SYSCALL(64)\ 88 | LANDING_SYSCALL(65)\ 89 | LANDING_SYSCALL(66)\ 90 | LANDING_SYSCALL(67)\ 91 | LANDING_SYSCALL(68)\ 92 | LANDING_SYSCALL(69)\ 93 | LANDING_SYSCALL(70)\ 94 | LANDING_SYSCALL(71)\ 95 | LANDING_SYSCALL(72)\ 96 | LANDING_SYSCALL(73)\ 97 | LANDING_SYSCALL(74)\ 98 | LANDING_SYSCALL(75)\ 99 | LANDING_SYSCALL(76)\ 100 | LANDING_SYSCALL(77)\ 101 | LANDING_SYSCALL(78)\ 102 | LANDING_SYSCALL(79)\ 103 | LANDING_SYSCALL(80)\ 104 | LANDING_SYSCALL(81)\ 105 | LANDING_SYSCALL(82)\ 106 | LANDING_SYSCALL(83)\ 107 | LANDING_SYSCALL(84)\ 108 | LANDING_SYSCALL(85)\ 109 | LANDING_SYSCALL(86)\ 110 | LANDING_SYSCALL(87)\ 111 | LANDING_SYSCALL(88)\ 112 | LANDING_SYSCALL(89)\ 113 | LANDING_SYSCALL(90)\ 114 | LANDING_SYSCALL(91)\ 115 | LANDING_SYSCALL(92)\ 116 | LANDING_SYSCALL(93)\ 117 | LANDING_SYSCALL(94)\ 118 | LANDING_SYSCALL(95)\ 119 | LANDING_SYSCALL(96)\ 120 | LANDING_SYSCALL(97)\ 121 | LANDING_SYSCALL(98)\ 122 | LANDING_SYSCALL(99)\ 123 | LANDING_SYSCALL(100)\ 124 | LANDING_SYSCALL(101)\ 125 | LANDING_SYSCALL(102)\ 126 | LANDING_SYSCALL(103)\ 127 | LANDING_SYSCALL(104)\ 128 | LANDING_SYSCALL(105)\ 129 | LANDING_SYSCALL(106)\ 130 | LANDING_SYSCALL(107)\ 131 | LANDING_SYSCALL(108)\ 132 | LANDING_SYSCALL(109)\ 133 | LANDING_SYSCALL(110)\ 134 | LANDING_SYSCALL(111)\ 135 | LANDING_SYSCALL(112)\ 136 | LANDING_SYSCALL(113)\ 137 | LANDING_SYSCALL(114)\ 138 | LANDING_SYSCALL(115)\ 139 | LANDING_SYSCALL(116)\ 140 | LANDING_SYSCALL(117)\ 141 | LANDING_SYSCALL(118)\ 142 | LANDING_SYSCALL(119)\ 143 | LANDING_SYSCALL(120)\ 144 | LANDING_SYSCALL(121)\ 145 | LANDING_SYSCALL(122)\ 146 | LANDING_SYSCALL(123)\ 147 | LANDING_SYSCALL(124)\ 148 | LANDING_SYSCALL(125)\ 149 | LANDING_SYSCALL(126)\ 150 | LANDING_SYSCALL(127)\ 151 | LANDING_SYSCALL(128)\ 152 | LANDING_SYSCALL(129)\ 153 | LANDING_SYSCALL(130)\ 154 | LANDING_SYSCALL(131)\ 155 | LANDING_SYSCALL(132)\ 156 | LANDING_SYSCALL(133)\ 157 | LANDING_SYSCALL(134)\ 158 | LANDING_SYSCALL(135)\ 159 | LANDING_SYSCALL(136)\ 160 | LANDING_SYSCALL(137)\ 161 | LANDING_SYSCALL(138)\ 162 | LANDING_SYSCALL(139)\ 163 | LANDING_SYSCALL(140)\ 164 | LANDING_SYSCALL(141)\ 165 | LANDING_SYSCALL(142)\ 166 | LANDING_SYSCALL(143)\ 167 | LANDING_SYSCALL(144)\ 168 | LANDING_SYSCALL(145)\ 169 | LANDING_SYSCALL(146)\ 170 | LANDING_SYSCALL(147)\ 171 | LANDING_SYSCALL(148)\ 172 | LANDING_SYSCALL(149)\ 173 | LANDING_SYSCALL(150)\ 174 | LANDING_SYSCALL(151)\ 175 | LANDING_SYSCALL(152)\ 176 | LANDING_SYSCALL(153)\ 177 | LANDING_SYSCALL(154)\ 178 | LANDING_SYSCALL(155)\ 179 | LANDING_SYSCALL(156)\ 180 | LANDING_SYSCALL(157)\ 181 | LANDING_SYSCALL(158)\ 182 | LANDING_SYSCALL(159)\ 183 | LANDING_SYSCALL(160)\ 184 | LANDING_SYSCALL(161)\ 185 | LANDING_SYSCALL(162)\ 186 | LANDING_SYSCALL(163)\ 187 | LANDING_SYSCALL(164)\ 188 | LANDING_SYSCALL(165)\ 189 | LANDING_SYSCALL(166)\ 190 | LANDING_SYSCALL(167)\ 191 | LANDING_SYSCALL(168)\ 192 | LANDING_SYSCALL(169)\ 193 | LANDING_SYSCALL(170)\ 194 | LANDING_SYSCALL(171)\ 195 | LANDING_SYSCALL(172)\ 196 | LANDING_SYSCALL(173)\ 197 | LANDING_SYSCALL(174)\ 198 | LANDING_SYSCALL(175)\ 199 | LANDING_SYSCALL(176)\ 200 | LANDING_SYSCALL(177)\ 201 | LANDING_SYSCALL(178)\ 202 | LANDING_SYSCALL(179)\ 203 | LANDING_SYSCALL(180)\ 204 | LANDING_SYSCALL(181)\ 205 | LANDING_SYSCALL(182)\ 206 | LANDING_SYSCALL(183)\ 207 | LANDING_SYSCALL(184)\ 208 | LANDING_SYSCALL(185)\ 209 | LANDING_SYSCALL(186)\ 210 | LANDING_SYSCALL(187)\ 211 | LANDING_SYSCALL(188)\ 212 | LANDING_SYSCALL(189)\ 213 | LANDING_SYSCALL(190)\ 214 | LANDING_SYSCALL(191)\ 215 | LANDING_SYSCALL(192)\ 216 | LANDING_SYSCALL(193)\ 217 | LANDING_SYSCALL(194)\ 218 | LANDING_SYSCALL(195)\ 219 | LANDING_SYSCALL(196)\ 220 | LANDING_SYSCALL(197)\ 221 | LANDING_SYSCALL(198)\ 222 | LANDING_SYSCALL(199)\ 223 | LANDING_SYSCALL(200)\ 224 | LANDING_SYSCALL(201)\ 225 | LANDING_SYSCALL(202)\ 226 | LANDING_SYSCALL(203)\ 227 | LANDING_SYSCALL(204)\ 228 | LANDING_SYSCALL(205)\ 229 | LANDING_SYSCALL(206)\ 230 | LANDING_SYSCALL(207)\ 231 | LANDING_SYSCALL(208)\ 232 | LANDING_SYSCALL(209)\ 233 | LANDING_SYSCALL(210)\ 234 | LANDING_SYSCALL(211)\ 235 | LANDING_SYSCALL(212)\ 236 | LANDING_SYSCALL(213)\ 237 | LANDING_SYSCALL(214)\ 238 | LANDING_SYSCALL(215)\ 239 | LANDING_SYSCALL(216)\ 240 | LANDING_SYSCALL(217)\ 241 | LANDING_SYSCALL(218)\ 242 | LANDING_SYSCALL(219)\ 243 | LANDING_SYSCALL(220)\ 244 | LANDING_SYSCALL(221)\ 245 | LANDING_SYSCALL(222)\ 246 | LANDING_SYSCALL(223)\ 247 | LANDING_SYSCALL(224)\ 248 | LANDING_SYSCALL(225)\ 249 | LANDING_SYSCALL(226)\ 250 | LANDING_SYSCALL(227)\ 251 | LANDING_SYSCALL(228)\ 252 | LANDING_SYSCALL(229)\ 253 | LANDING_SYSCALL(230)\ 254 | LANDING_SYSCALL(231)\ 255 | LANDING_SYSCALL(232)\ 256 | LANDING_SYSCALL(233)\ 257 | LANDING_SYSCALL(234)\ 258 | LANDING_SYSCALL(235)\ 259 | LANDING_SYSCALL(236)\ 260 | LANDING_SYSCALL(237)\ 261 | LANDING_SYSCALL(238)\ 262 | LANDING_SYSCALL(239)\ 263 | LANDING_SYSCALL(240)\ 264 | LANDING_SYSCALL(241)\ 265 | LANDING_SYSCALL(242)\ 266 | LANDING_SYSCALL(243)\ 267 | LANDING_SYSCALL(244)\ 268 | LANDING_SYSCALL(245)\ 269 | LANDING_SYSCALL(246)\ 270 | LANDING_SYSCALL(247)\ 271 | LANDING_SYSCALL(248)\ 272 | LANDING_SYSCALL(249)\ 273 | LANDING_SYSCALL(250)\ 274 | LANDING_SYSCALL(251)\ 275 | LANDING_SYSCALL(252)\ 276 | LANDING_SYSCALL(253)\ 277 | LANDING_SYSCALL(254)\ 278 | LANDING_SYSCALL(255)\ 279 | LANDING_SYSCALL(256)\ 280 | LANDING_SYSCALL(257)\ 281 | LANDING_SYSCALL(258)\ 282 | LANDING_SYSCALL(259)\ 283 | LANDING_SYSCALL(260)\ 284 | LANDING_SYSCALL(261)\ 285 | LANDING_SYSCALL(262)\ 286 | LANDING_SYSCALL(263)\ 287 | LANDING_SYSCALL(264)\ 288 | LANDING_SYSCALL(265)\ 289 | LANDING_SYSCALL(266)\ 290 | LANDING_SYSCALL(267)\ 291 | LANDING_SYSCALL(268)\ 292 | LANDING_SYSCALL(269)\ 293 | LANDING_SYSCALL(270)\ 294 | LANDING_SYSCALL(271)\ 295 | LANDING_SYSCALL(272)\ 296 | LANDING_SYSCALL(273)\ 297 | LANDING_SYSCALL(274)\ 298 | LANDING_SYSCALL(275)\ 299 | LANDING_SYSCALL(276)\ 300 | LANDING_SYSCALL(277)\ 301 | LANDING_SYSCALL(278)\ 302 | LANDING_SYSCALL(279)\ 303 | LANDING_SYSCALL(280)\ 304 | LANDING_SYSCALL(281)\ 305 | LANDING_SYSCALL(282)\ 306 | LANDING_SYSCALL(283)\ 307 | LANDING_SYSCALL(284)\ 308 | LANDING_SYSCALL(285)\ 309 | LANDING_SYSCALL(286)\ 310 | LANDING_SYSCALL(287)\ 311 | LANDING_SYSCALL(288)\ 312 | LANDING_SYSCALL(289)\ 313 | LANDING_SYSCALL(290)\ 314 | LANDING_SYSCALL(291)\ 315 | LANDING_SYSCALL(292)\ 316 | LANDING_SYSCALL(293)\ 317 | LANDING_SYSCALL(294)\ 318 | LANDING_SYSCALL(295)\ 319 | LANDING_SYSCALL(296)\ 320 | LANDING_SYSCALL(297)\ 321 | LANDING_SYSCALL(298)\ 322 | LANDING_SYSCALL(299)\ 323 | LANDING_SYSCALL(300)\ 324 | LANDING_SYSCALL(301)\ 325 | LANDING_SYSCALL(302)\ 326 | LANDING_SYSCALL(303)\ 327 | LANDING_SYSCALL(304)\ 328 | LANDING_SYSCALL(305)\ 329 | LANDING_SYSCALL(306)\ 330 | LANDING_SYSCALL(307)\ 331 | LANDING_SYSCALL(308)\ 332 | LANDING_SYSCALL(309)\ 333 | 334 | 335 | #define HOOK_START_PRESYSCALL \ 336 | __asm__ __volatile__ (\ 337 | "nop\n\t"\ 338 | "nop\n\t"\ 339 | "nop\n\t"\ 340 | "nop\n\t"\ 341 | "nop\n\t"\ 342 | "nop\n\t"\ 343 | "nop\n\t"\ 344 | "nop\n\t"\ 345 | "nop\n\t"\ 346 | "nop\n\t"\ 347 | "nop\n\t"\ 348 | "nop\n\t"\ 349 | "nop\n\t"\ 350 | "pop %%rax\n\t"\ 351 | "push %%rbp\n\t"\ 352 | "mov %%rsp, %%rbp\n\t"\ 353 | "sub $0xa0, %%rsp\n\t"\ 354 | "mov %%rax,%0\n\t"\ 355 | "mov 0xa8(%%rsp),%%rax\n\t"\ 356 | "mov %%rax,%1\n\t"\ 357 | "push %%rbx\n\t"\ 358 | "push %%rcx\n\t"\ 359 | "push %%rdx\n\t"\ 360 | "push %%rsi\n\t"\ 361 | "push %%rdi\n\t"\ 362 | "push %%r8\n\t"\ 363 | "push %%r9\n\t"\ 364 | "push %%r10\n\t"\ 365 | "push %%r11\n\t"\ 366 | "push %%r12\n\t"\ 367 | "push %%r13\n\t"\ 368 | "push %%r14\n\t"\ 369 | "push %%r15\n\t"\ 370 | "mov %%rdi,%2\n\t"\ 371 | "mov %%rsi,%3\n\t"\ 372 | "mov %%rdx,%4\n\t"\ 373 | "mov %%r10,%5\n\t"\ 374 | "mov %%r8,%6\n\t"\ 375 | "mov %%r9,%7\n\t"\ 376 | : "=m"(syscall_num),"=m"(ret_addr),\ 377 | "=m"(syscall_argv[0]),"=m"(syscall_argv[1]),\ 378 | "=m"(syscall_argv[2]),"=m"(syscall_argv[3]),\ 379 | "=m"(syscall_argv[4]),"=m"(syscall_argv[5])\ 380 | ); 381 | 382 | #define HOOK_END_PRESYSCALL \ 383 | syscall_addr=((void**)syscall_table_backup)[syscall_num];\ 384 | __asm__ __volatile__ (\ 385 | "pop %%r15\n\t"\ 386 | "pop %%r14\n\t"\ 387 | "pop %%r13\n\t"\ 388 | "pop %%r12\n\t"\ 389 | "pop %%r11\n\t"\ 390 | "pop %%r10\n\t"\ 391 | "pop %%r9\n\t"\ 392 | "pop %%r8\n\t"\ 393 | "pop %%rdi\n\t"\ 394 | "pop %%rsi\n\t"\ 395 | "pop %%rdx\n\t"\ 396 | "pop %%rcx\n\t"\ 397 | "pop %%rbx\n\t"\ 398 | "xor %%rax, %%rax\n\t"\ 399 | "mov %0, %%rax\n\t"\ 400 | "mov %%rax, 0xa8(%%rsp)\n\t"\ 401 | "mov %1, %%rax\n\t"\ 402 | "mov %%rbp, %%rsp\n\t"\ 403 | "pop %%rbp\n\t"\ 404 | "jmp *%%rax\n\t"\ 405 | :\ 406 | :"m"(ret_addr),"m"(syscall_addr)\ 407 | ); 408 | #define HOOK_START_POSTSYSCALL \ 409 | __asm__ __volatile__ (\ 410 | "nop\n\t"\ 411 | "nop\n\t"\ 412 | "nop\n\t"\ 413 | "nop\n\t"\ 414 | "nop\n\t"\ 415 | "nop\n\t"\ 416 | "nop\n\t"\ 417 | "nop\n\t"\ 418 | "nop\n\t"\ 419 | "nop\n\t"\ 420 | "nop\n\t"\ 421 | "nop\n\t"\ 422 | "nop\n\t"\ 423 | "push %%rbp\n\t"\ 424 | "push %%rbp\n\t"\ 425 | "mov %%rsp, %%rbp\n\t"\ 426 | "sub $0x40, %%rsp\n\t"\ 427 | "push %%rax\n\t"\ 428 | "push %%rbx\n\t"\ 429 | "push %%rcx\n\t"\ 430 | "push %%rdx\n\t"\ 431 | "push %%rsi\n\t"\ 432 | "push %%rdi\n\t"\ 433 | "push %%r8\n\t"\ 434 | "push %%r9\n\t"\ 435 | "push %%r10\n\t"\ 436 | "push %%r11\n\t"\ 437 | "push %%r12\n\t"\ 438 | "push %%r13\n\t"\ 439 | "push %%r14\n\t"\ 440 | "push %%r15\n\t"\ 441 | "mov %%rax, %0\n\t"\ 442 | :"=m"(retval)\ 443 | ); 444 | 445 | #define HOOK_END_POSTSYSCALL \ 446 | __asm__ __volatile__ (\ 447 | "pop %%r15\n\t"\ 448 | "pop %%r14\n\t"\ 449 | "pop %%r13\n\t"\ 450 | "pop %%r12\n\t"\ 451 | "pop %%r11\n\t"\ 452 | "pop %%r10\n\t"\ 453 | "pop %%r9\n\t"\ 454 | "pop %%r8\n\t"\ 455 | "pop %%rdi\n\t"\ 456 | "pop %%rsi\n\t"\ 457 | "pop %%rdx\n\t"\ 458 | "pop %%rcx\n\t"\ 459 | "pop %%rbx\n\t"\ 460 | "mov %0, %%rax\n\t"\ 461 | "mov %%rax,0x50(%%rsp)\n\t"\ 462 | "pop %%rax\n\t"\ 463 | "mov %%rbp, %%rsp\n\t"\ 464 | "pop %%rbp\n\t"\ 465 | "ret\n\t"\ 466 | :\ 467 | :"m"(ret_addr)\ 468 | ); 469 | --------------------------------------------------------------------------------