diff options
Diffstat (limited to 'toj/center/src/judgk_syscall.c')
-rwxr-xr-x | toj/center/src/judgk_syscall.c | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/toj/center/src/judgk_syscall.c b/toj/center/src/judgk_syscall.c new file mode 100755 index 0000000..370a3fe --- /dev/null +++ b/toj/center/src/judgk_syscall.c @@ -0,0 +1,240 @@ +#include<linux/fs.h> +#include<linux/slab.h> +#include<linux/sched.h> +#include<linux/sort.h> +#include<asm/msr.h> +#include<asm/unistd.h> +#include<asm/uaccess.h> + +#include"judge_def.h" +#include"judgk.h" +#include"judgk_com.h" +#include"judgk_syscall.h" + +int judgk_syscall_hook(){ + int i; + int j; + + unsigned int size; + unsigned int restore; + + syscall_init_hook(); + + syscall_addr_write((unsigned long)syscall_table,&size,&restore); + for(i = 0,j = 0;i < syscall_max;i++){ + if(size == 0){ + syscall_addr_restore((unsigned long)(syscall_table + i - 1),restore); + syscall_addr_write((unsigned long)(syscall_table + i),&size,&restore); + } + size -= sizeof(unsigned long); + + if(i == syscall_whitelist[j]){ + j++; + continue; + } + syscall_table[i] = (unsigned long)hook_sys_block; + } + syscall_addr_restore((unsigned long)(&syscall_table[i - 1]),restore); + + return 0; +} +int judgk_syscall_unhook(){ + int i; + + unsigned int size; + unsigned int restore; + + syscall_addr_write((unsigned long)syscall_table,&size,&restore); + for(i = 0;i < syscall_max;i++){ + if(size == 0){ + syscall_addr_restore((unsigned long)(&syscall_table[i - 1]),restore); + syscall_addr_write((unsigned long)(&syscall_table[i]),&size,&restore); + } + size -= sizeof(unsigned long); + + syscall_table[i] = (unsigned long)judgk_syscall_ori_table[i]; + } + syscall_addr_restore((unsigned long)(&syscall_table[i - 1]),restore); + + kfree(judgk_syscall_ori_table); + return 0; +} +static int syscall_init_hook(){ + ssize_t ret; + int i; + int j; + + struct file *f; + char line[128]; + unsigned char code[3] = {0xff,0x14,0xc5}; + unsigned long addr; + + f = filp_open("/proc/kallsyms",O_RDONLY,0); + set_fs(KERNEL_DS); + + i = 0; + addr = 0; + while(true){ + ret = f->f_op->read(f,&line[i],1,&f->f_pos); + + if(line[i] == '\n' || ret <= 0){ + line[i] = '\0'; + + addr = 0; + for(j = 0;j < i;j++){ + if(line[j] == ' '){ + j++; + break; + } + + addr *= 16UL; + if(line[j] >= '0' && line[j] <= '9'){ + addr += (unsigned long)(line[j] - '0'); + }else{ + addr += (unsigned long)(line[j] - 'a' + 10); + } + } + for(;j < i;j++){ + if(line[j] == ' '){ + j++; + break; + } + } + if(j < i){ + if(strcmp("system_call",line + j) == 0){ + break; + } + } + + i = 0; + }else{ + i++; + } + + if(ret <= 0){ + break; + } + } + + set_fs(USER_DS); + filp_close(f,NULL); + + while(true){ + for(i = 0;i < 3;i++){ + if(*(unsigned char*)addr != code[i]){ + addr++; + break; + } + addr++; + } + if(i == 3){ + break; + } + } + syscall_table = (unsigned long*)(0xffffffff00000000 + *((unsigned int*)addr)); + + addr -= 4L; + while(true){ + if(*(unsigned char*)addr == 0x3d){ + addr++; + break; + } + addr--; + } + syscall_max = *(unsigned int*)addr; + + judgk_syscall_ori_table = kmalloc(sizeof(unsigned long) * (syscall_max + 1),GFP_KERNEL); + memcpy(judgk_syscall_ori_table,syscall_table,sizeof(unsigned long) * syscall_max); + + sort(syscall_whitelist,SYSCALL_WHITELIST_SIZE,sizeof(unsigned int),syscall_whitelist_cmp,NULL); + + return 0; +} +static int syscall_whitelist_cmp(const void *a,const void *b){ + if(*(unsigned int*)a < *(unsigned int*)b){ + return -1; + }else if(*(unsigned int*)a == *(unsigned int*)b){ + return 0; + }else{ + return 1; + } +} +static int syscall_addr_write(unsigned long addr,unsigned int *size,int *restore){ + unsigned int level; + pte_t *pte; + + pte = lookup_address(addr,&level); + if(pte->pte & _PAGE_RW){ + *restore = 0; + }else{ + pte->pte |= _PAGE_RW; + *restore = 1; + } + + switch(level){ + case PG_LEVEL_4K: + *size = 4096; + break; + case PG_LEVEL_2M: + *size = 2097152; + break; + case PG_LEVEL_1G: + *size = 1073741824; + break; + } + *size -= (((unsigned int)addr) & (*size - 1)); + + return 0; +} +static int syscall_addr_restore(unsigned long addr,int restore){ + unsigned int level; + pte_t *pte; + + if(restore){ + pte = lookup_address(addr,&level); + pte->pte ^= _PAGE_RW; + } + + return 0; +} + +int judgk_syscall_check(){ + if(judgk_proc_task_lookup(current)){ + return 1; + } + return 0; +} +int judgk_syscall_block(){ + struct judgk_proc_info *info; + + if((info = judgk_proc_task_lookup(current)) == NULL){ + return 0; + } + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return 0; +} + +/*asmlinkage long hook_sys_nanosleep(struct timespec __user *rqtp,struct timespec __user *rmtp){ + long ret; + + struct judgm_proc_info *info; + + atomic64_inc(&syscall_pending); + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + ret = ori_sys_nanosleep(rqtp,rmtp); + atomic64_dec(&syscall_pending); + return ret; + } + + pr_alert("judgm:PID %d nanosleep\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + + atomic64_dec(&syscall_pending); + return -EACCES; +}*/ |