进程隐藏系统调用

一、实验内容

实验3:Linux进程管理及其扩展

1、阅读并分析Linux内核源代码,了解进程控制块、进程队列等数据结构;

2. 实现一个系统调用,使得可以根据指定的参数隐藏进程,使用户无法使用ps或top观察到进程状态。具体要求如下:

(1)实现系统调用int hide(pid_t pid, int on),在进程pid有效的前提下,如果on置1,进程被隐藏,用户无法通过ps或top观察到进程状态;如果on置0且此前为隐藏状态,则恢复正常状态。

(2)考虑权限问题,只有根用户才能隐藏进程。

(3)设计一个新的系统调用int hide_user_processes(uid_t uid, char *binname),参数uid为用户ID号,当binname参数为NULL时,隐藏该用户的所有进程;否则,隐藏二进制映像名为binname的用户进程。该系统调用应与hide系统调用共存。

(4)在/proc目录下创建一个文件/proc/hidden,该文件可读可写,对应一个全局变量hidden_flag,当hidden_flag为0时,所有进程都无法隐藏,即便此前进程被hide系统调用要求隐藏。只有当hidden_flag为1时,此前通过hide调用要求被屏蔽的进程才隐藏起来。

(5)在/proc目录下创建一个文件/proc/hidden_process,该文件的内容包含所有被隐藏进程的pid,各pid之间用空格分开。

二、实验目的

通过实验,加深理解进程控制块、进程队列等概念,了解进程管理的具体实施方法。

三、设计思路和关键代码

特色功能:

1、进程按照pid、uid、进程名进行隐藏和恢复

2、实现了动态模块加载和内核静态编译两种方式生成proc文件

3、编写了测试程序

(1)修改进程控制块(相当于PCB)的数据结构,增加cloak参数,1表示该进程隐藏。在使用ps或者top指令的时候,事实上也就是系统调用,所以要在显示进程的系统调用的地方按照cloak参数进行过滤。

A、Include/linux/sched.h文件中存储进程控制块(struct task_struct)。

B、首先要在进程创建的时候对cloak进行初始化,这里默认初始化为0,表示不隐藏。

fork系统调用的实现代码在kernel/fork.c中,具体实现的主要函数为do_fork,do_fork中调用copy_process函数创建子进程,建议将初始化cloak的代码添加在copy_process函数中。

C、然后,创建hide系统调用,这里不再像实验2一样新建文件,而是直接在fs/proc/base.c中添加。通过pid获取进程task_struct的内核函数为find_task_by_pid。在隐藏后最好调用函数proc_flush_task来清空VFS层的缓冲,解除已有的dentry项。

修改proc_pid_readdir函数(在fs/proc/base.c文件中)。其中使用for循环遍历进程,在遍历过程中添加判断,过滤掉被隐藏的进程。

修改proc_pid_lookup函数,在进程查找完成前过滤掉被隐藏的进程。

(2)考虑权限时,需要修改cloak的hide系统调用中增加对权限的判断,使用全局变量current->uid获取当前用户权限,值为0代表root用户。

(3)int hide_user_processes(uid_t uid, char *binname),系统调用按照uid或者uid和进程名对进程进行隐藏的系统调用。在fs/proc/base.c添加系统调用。

(4)在/proc目录下创建一个文件/proc/hidden,该文件可读可写,对应一个全局变量hidden_flag,当hidden_flag为0时,所有进程都无法隐藏,即便此前进程被hide系统调用要求隐藏。只有当hidden_flag为1时,此前通过hide调用要求被屏蔽的进程才隐藏起来。

这个hidden_flag相当于更高级别的控制,当其为0时,仍然可以对cloak操作,但是隐藏的作用失效。

实现proc文件的创建和读写,可以直接写在内核中也可以通过动态加载模块的方式实现。这里两种都做介绍:

内核中创建proc文件方式:

A、 首先在fs/proc/proc_misc.c文件中声明全局变量,EXPORT_SYMBOL()函数可以使该变量在整个内核中可见。使用时只要extern int hidden_flag;即可访问同一变量。

B、 proc文件系统在初始化函数proc_root_init中会调用proc_misc_init函数,此函数用于创建/proc根目录下的文件,那么将创建hidden文件的代码插入到此函数中就可以在proc初始化时得到执行。(在fs/proc/proc_misc.c文件中)

其中proc_read_hidden和proc_write_hidden分别是对hidden文件读写时的回调函数。

即当用户读取hidden文件时,返回全局变量hidden_flag的值;

即当用户写入hidden文件时,修改全局变量hidden_flag的值;

这样就可以实现文件的值和全局变量实现同步。达到用户态对内核进行设置的目的。

C、 修改proc_pid_readdir函数和proc_pid_lookup函数(在fs/proc/base.c文件中),增加对hidden_flag的判断逻辑。

proc_pid_lookup:

proc_pid_readdir:

动态加载模块方式:

A、 只需要在内核fs/proc/proc_misc.c文件中,添加全局变量

B、 创建一个动态模块文件hide_module.c

在其初始化函数init_hide(void)中编写:

在其关闭函数exit_hide(void)中编写:

C、 将这两个函数绑定为初始化和退出函数

D、 读写文件的回调函数

(5)在/proc目录下创建一个文件/proc/hidden_process,该文件的内容包含所有被隐藏进程的pid,各pid之间用空格分开。那么也可以分为静态内核和动态模块两种实现方式。

内核中创建proc文件方式:

A、proc文件系统在初始化函数proc_root_init中会调用proc_misc_init函数,此函数用于创建/proc根目录下的文件,那么将创建hidden文件的代码插入到此函数中就可以在proc初始化时得到执行。(在fs/proc/proc_misc.c文件中)

B、由于这个文件只需要用户读取,所以只写读操作的回调函数即可:

这里需要注意的是,page即为返回给用户的字符串,这个回调函数的返回值,为这个字符串的长度。

动态加载模块方式:

A、 与hidden文件的动态加载模块方式相似

在其初始化函数init_hide(void)中编写:

在其关闭函数exit_hide(void)中编写:

B、 其读操作回调函数为:

四、主要数据结构及其说明

task_struct数据结构说明

源自:

http://www.baidu.com/link?url=SO-vtkUs6iRdOHI9se20ZDyI8zjNisNDVxeW7ccNtCfx3YZbVlQFptbKekoIcG9zyDe0PuRvvV7yNn-5zc46_q

proc文件操作说明

创建proc文件

struct proc_dir_entry * hidefile = create_proc_entry("hidden",0644,NULL);

1、  第一个参数是文件名

2、  第二个参数是文件的读写权限

3、  第三个参数是路径,因为在proc文件的根目录所以为NULL

然后绑定读写回调函数:

hidefile->read_proc = proc_read_hidden;// call back : read

hidefile->write_proc = proc_write_hidden;// call back : write

也可以采用以下方式创建并绑定回调函数:

struct proc_dir_entry * hideprocessfile = create_proc_read_entry("hidden_process",

0444,

NULL,

proc_read_hidden_process,

NULL);

读proc文件

proc文件不能像普通文件一样打开然后阅读,需使用如下指令

cat < hidden

使用如下指令写入文件

echo “1” > hidden

加载动态模块

在加载模块的目录下编写Makefile文件,然后编译

$ make

进入到root用户下,加载模块

# insmod hide_module.ko

卸载模块

# rmmod hide_module

五、源程序

动态加载模块hide_module.h

#include<linux/init.h>

#include<linux/module.h>

#include <linux/fs.h>

#include <asm/unistd.h>

#include <asm/uaccess.h>

#include<linux/proc_fs.h>

#include<linux/sched.h>

#include<linux/proc_fs.h>

#include<linux/slab.h>

#include <asm/uaccess.h>

MODULE_LICENSE("GPL");

extern int hidden_flag;

static int proc_read_hidden(char* page,char**start,off_t off,int count,int *eof,void *data){

         // hidden ‘s read callback function

         int length;

         length = sprintf(page,"%d",hidden_flag);//before user read this file, we write the ‘hidden_flag‘ to the file

         return length;

}

static int proc_write_hidden(struct file * file,const char *buffer,unsigned long count,void *data){

         // hidden ‘s write callback function

         hidden_flag = buffer[0]-‘0‘;//before user write this file , we catch the user‘s input and modify the ‘hidden_flag‘

         return count;

}

static int proc_read_hidden_process(char* page,char**start,off_t off,int count,int *eof,void *data){

         // hidden_process ‘s read callback function

         struct task_struct *task=NULL;

         int num = 0;

         for_each_process(task){

             if(task->cloak==1){

                   sprintf(page+num,"%-4d ",task->pid);

                   num+=5;

             }

         }

         return num-5;

}

static int init_hide(void){

         // init module -> create proc file (hidden and hidden_process)

         struct proc_dir_entry * hidefile = create_proc_entry("hidden",0644,NULL);// create hidden file and its privilage is read&write

         hidefile->read_proc = proc_read_hidden;// call back : read

         hidefile->write_proc = proc_write_hidden;// call back : write

         struct proc_dir_entry * hideprocessfile = create_proc_read_entry("hidden_process",

                                                                                    0444,

                                                                                    NULL,

                                                                                    proc_read_hidden_process,

                                                                                    NULL);     

         printk("<0>""hidden file ok\n");

         return 0;

}

static void exit_hide(void){

         // delete proc file

         remove_proc_entry("hidden",NULL);

         remove_proc_entry("hidden_process",NULL);

         printk("<0>""hidden file close\n");

         return;

}

module_init(init_hide);

module_exit(exit_hide);

  

动态加载模块的Makefile

ifneq ($(KERNELRELEASE),)

         obj-m:=hide_module.o

else

         KDIR:=/lib/modules/$(shell uname -r)/build

         PWD:=$(shell pwd)

default:

         $(MAKE) -C $(KDIR) M=$(PWD) modules

clean:

         $(MAKE) -C $(KDIR) M=$(PWD) clean

Endif

  

测试程序

#include<sys/syscall.h>

#include<unistd.h>

#include<stdio.h>

#include<stdlib.h>

int main(){

         int func=0;

         int pid;

         int on;

         char name[200];

         int uid;

         while(1){

         printf("###please select test function:\n0:my system call\n1:hide\n2hide_process by uid\n3hide_process by name&uid\n4:exit\n");

         scanf("%d",&func);

         switch(func){

         case 0:

                   syscall(320);

                   break;

         case 1:

                   printf("input: pid on\n");

                   scanf("%d %d",&pid,&on);

                   syscall(321,pid,on);

                  break;

         case 2:

                   printf("input: uid on\n");

                   scanf("%d %d",&uid,&on);

                   syscall(322,uid,NULL,on);

                   break;      

         case 3:

                   printf("input: uid on name\n");

                   scanf("%d %d %s",&uid,&on,&name);

                   syscall(322,uid,name,on);

                   break;

         default:

                   return 0;

         }

         }

         return 0;

}
时间: 2024-12-21 16:52:44

进程隐藏系统调用的相关文章

进程隐藏的各种方法 以及分析比较以及实现链接

典型进程隐藏技术1  基于系统服务的进程隐藏技术在 W I N 9X 系列操作系统中, 系统进程列表中不能看到任何系统服务进程, 因此只需要将指定进程注册为系统服务就能够使该进程从系统进程列表中隐形 在win9x下用RegisterServiceProcess函数隐藏进程,NT架构下用不了 即win2000  xp等什么的用不了此方法. 2  基于API HOOK的进程隐藏技术API HOOK指的是通过特殊的编程手段截获WINDOWS系统调用的API函数,并将其丢弃或者进行替换. 通过APIHO

c 进程和系统调用

这一篇博客讲解进程和系统调用相关的知识 有这样一个场景,我需要输入一串文字,然后把我输入的文字加上一个本地的时间戳 保存在一个文件中,可以初步理解为一个备忘录也行 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 5 /** 6 * 获取一个当前时间 7 */ 8 char *now() { 9 time_t t; 10 time(&t); 11 return asctime(loc

HOOK - 进程隐藏与进程保护(SSDT Hook 实现)(三)

进程隐藏与进程保护(SSDT Hook 实现)(三) 文章目录:                   1. 引子: 2. 获取当前系统下所有进程: 3. 服务管理(安装,启动,停止,卸载): 4. 应用程序和内核程序通信: 5. 小结: 1. 引子: 关于这个 SSDT Hook 实现进程隐藏和进程保护呢,这是最后一篇博文了, 在文章的结尾处呢你可以下载到整个项目的实例程序以及代码, 程序可以在 XP.Server.Win7 上运行的,当然我是说的 32 位操作系统.        <进程隐藏与

HOOK - 进程隐藏与进程保护(SSDT Hook 实现)(二)

进程隐藏与进程保护(SSDT Hook 实现)(二) 文章目录:                   1. 引子 – Demo 实现效果: 2. 进程隐藏与进程保护概念: 3. SSDT Hook 框架搭建: 4. Ring0 实现进程隐藏: 5. Ring0 实现进程保护: 6. 隐藏进程列表和保护进程列表的维护: 7. 小结: 1. 引子 – Demo 实现效果: 上一篇<进程隐藏与进程保护(SSDT Hook 实现)(一)>呢把 SSDT 说得差不多了, 博文地址: http://www

进程隐藏的方法

最基本的隐藏:不可见窗体+隐藏文件 木马程序无论如何神秘,但归根究底,仍是Win32平台下的一种程序.Windows下常见的程序有两种: 1.Win32应用程序(Win32 Application),比如QQ.Office等都属于此行列. 2.Win32控制台程序(Win32 Console),比如硬盘引导修复程序FixMBR. 其中,Win32应用程序通常会有应用程序界面,比如系统中自带的"计算器"就有提供各种数字按钮的应用程序界面.木马虽然属于Win32应用程序,但其一般不包含窗体

linux strace-跟踪进程的系统调用或是信号产生情况,lstrace-跟踪己丑年调用库函数情况,进程跟踪调试命令

本工具可以用来做大多数排除,比如mount一个NFS,很慢,找不出原因,我们可以使用strace命令来跟中mount这个经常所有的调用过程. strace 命令是一种强大的工具,它能够显示所有由用户空间程序发出的系统调用. strace 显示这些调用的参数并返回符号形式的值.strace 从内核接收信息,而且不需要以任何特殊的方式来构建内核. 下面记录几个常用 option . 1 -f -F选项告诉strace同时跟踪fork和vfork出来的进程 2 -o xxx.txt 输出到某个文件.

进程隐藏与进程保护(SSDT Hook 实现)(二)

文章目录:                   1. 引子 – Demo 实现效果: 2. 进程隐藏与进程保护概念: 3. SSDT Hook 框架搭建: 4. Ring0 实现进程隐藏: 5. Ring0 实现进程保护: 6. 隐藏进程列表和保护进程列表的维护: 7. 小结: 1. 引子 – Demo 实现效果: 上一篇<进程隐藏与进程保护(SSDT Hook 实现)(一)>呢把 SSDT 说得差不多了, 博文地址: http://www.cnblogs.com/BoyXiao/archiv

win8应用层进程隐藏工具

今天测试发现,进程大师(Jnc Process master)可以从应用层隐藏进程,还不错,不过由于win8防护能力比较强,只能隐藏个别进程, 到现在为止还没有发现win8内核级隐藏进程的.大家如有发现可以相互交流一下 版权声明:本文为博主原创文章,未经博主允许不得转载.

进程隐藏与进程保护(SSDT Hook 实现)(一)

读了这篇文章终于明白大致怎么回事了 文章目录:                   1. 引子 – Hook 技术: 2. SSDT 简介: 3. 应用层调用 Win32 API 的完整执行流程: 4. 详解 SSDT: 5. SSDT  Hook 原理: 6. 小结: 1. 引子 – Hook 技术: 前面一篇博文呢介绍了代码的注入技术(远程线程实现),博文地址如下: http://www.cnblogs.com/BoyXiao/archive/2011/08/11/2134367.html