linux 隐藏进程 - crux实现

    本文在不修改pstop命令的任何代码与采用将进程号置0的方法的前提下,实现隐藏进程,本程序在CRUX 2.2上实现

 

1、原理

   Linux中,可以通过/proc文件系统访问到许多内核的内部信息。/proc文件系统最初的设计也是用于方便地访问进程相关的信息,因此命名为proc。现在这个文件系统已用于反映系统中方方面面的信息,例如/proc/modules是模块的列表,/proc/meminfo则是内存使用的统计。/proc文件系统中的目录并非持久存储的信息,也就是说,其目录并不“真实”地存在于磁盘,而是在访问时动态生成。

     本项目中我们感兴趣的是/proc文件系统中关于进程的信息。每一个进程在/proc文件系统中有一个目录即(/proc/<pid>),目录名即进程号。self目录是一个链接,指向当前进程。

     ps命令和top命令从/proc文件系统中读取进程信息并显示出来。因此,如果一个进程的进程号没有在/proc文件系统中反映出来,则这个进程被“隐藏”了,“隐藏”进程在pstop命令的输出不出现。

 

2、实现

2.1 为task_struct添加变量hide如下:(include/linux/sched.h)

 

     

 

2.2 哪里修改proc代码

     在linux代码树中,所有文件系统的代码都放在linux/fs/目录中,其中,proc文件系统的原始码在linux/fs/proc中,下面我简单介绍一下proc目录中的源文件。 

     在目录中共有11个相关文件,他们是:
     procfs_syms.c inode.c generic.c base.c
     array.c root.c proc_tty.c proc_misc.c
     kmsg.c kcore.c proc_devtree.c

     这么多的文件我们如何去找呢,借鉴网上的资料,对各个文件进行查找可知:
     其中,procfs_syms.c,generic.c及inode.c和proc文件系统的管理相关,包括proc文件系统的注册,及向内核其他子系统提供的例程等等。
     源文件root.c和proc文件系统的根结点的管理相关。
     而base.c,array.c则用来处理/proc目录中进程的信息,包括命令行,进程状态,内存状态等等和进程相关的内容。proc_tty.c用来处理/proc/tty信息,proc_misc.c则用来管理和/proc目录中的大多数文件。
     除此之外,更有两个非常重要的头文件proc_fs.h,proc_fs_i.h,我们能在/linux/include/linux/目录中找到。

     同时,最重要的是,我们确定了我们所要需要的相关信息在base.c文件中,主要是在这2个函数之间:proc_pid_readdir,proc_task_readdir,但是是哪个函数呢?由于网上的资料很少,没办法一个一个试。通过查看着2个看书的源代码:

 

     

 

     

 

    通过观察,我们可以大胆的猜测,filldir()函数 就是往/proc添加<pid>目录的函数,我们可以做个实验,即,在filldir()下面再添加一个filldir()函数,这样的话,一个进程在/proc目录下就会有2个目录,同时,ps -ax显示的同一个进程也会有2个。

    修改完后编译内核:

    cd /usr/src/linux-<版本号>

    make bzImage

    cp arch/i386/boot/bzImage /boot/vmlinuz-0.1

    cp System.map /boot/System.map-0.1

    修改grub,为修改的内核添加相应的启动项

    vim /boot/grub/menu.lst

    

    reboot重新启动,在启动后选择CRUX_TEST选项,使用我们修改完的内核,

    输入ps -ax或者查看/proc文件便会出现我们预先猜测的结果,同时,经过验证可知,ps, top命令调用的是proc_pid_readdir函数,而不是proc_task_readdir函数。嘿,在这,我们就发现新大陆了!

 

 

2.3 怎么修改proc

     由2.2可知,我们需要修改在函数为proc_pid_readdir,仔细阅读相关代码可知,我们只需在if (filldir(dirent, buf+j, PROC_NUMBUF-j, filp->f_pos, ino, DT_DIR) < 0) 前判断进程是否是否有设置为隐藏,而在之前,我们要先获取该进程的task_struct,具体代码如下(注释处即为添加的代码):

 

      

 

     另外需要在kernel/fork.c的copy_process()函数中添加初始化hide代码(虽可不用,但为了保证逻辑,还是添加吧)

      

     重新编译内核

 

2.4 添加系统调用

     为了验证我们2.3所修改的内核代码,我们需添加相应的系统调用,设置task_struct的hide,为此,我们添加2个系统调用,修改如下

     2.4.1 kernel/sys.c添加源代码

    

 

    2.4.2 include/asm-i386/unistd.h添加系统调用号及系统的调用总数

     

     2.4.3 arch/i386/kernel/syscall_table.S在系统调用表中添加相应项,在最后一行添加

      

     2.4.4 在include/linux/syscalls.h添加函数声明(貌似这个可有可无)

      

 

     至此,添加系统调用完成,重新编译内核

 

3 测试

    我们编写了一个测试函数,用来我们修改的内核是否成功,代码hide.c如下:

 

    

 

     gcc hide.c -o hide后,执行 ./hide  ,查看结果如图

 

    

 

 

      测试成功,成功隐藏进程!

 

4、结束语

     这只是实现隐藏的一种方式,网上看到的一个是拦截系统调用,我之前想的是拦截中断,直接在中断里面修改,这个有待验证,以后有机会实现的话也会贴出来和大家分享。

     这个程序从开始到完成大概花了我6,7个小时的时间,说起来难度也不大,内核代码的修改量很小,问题的关键处是找到在何处修改代码,这个俺也是边查资料边做实验才找到的。

     [2011-2-25]现已实现通过拦截系统调用隐藏进程的方式,分享与大家:http://blog.csdn.net/billpig/archive/2011/02/20/6196163.aspx

 

     版权所有,转载请出明出处!

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页