您的位置:首页 > 其它

vista下扫描内存检测隐藏进程

2009-05-20 01:16 387 查看
以前看过一个牛人uty写的文章:搜索内存枚举进程http://www.cnxhacker.com/article/show/3412.html,他是在Windows
XP sp1上实现的这种方法,但是我却没能跑通,后来详细地考虑了这种方法的细节,在sp2上把它实现了,后来刚好做Vista下的隐形软件检测的小项目,我就把进程拿出来做了,经过一番努力,终于在Vista下面搞定了。现在,总结一下这个方法,防止我把它给忘了……
一.内核对象
在操作系统的运行过程中,需要维护一些数据结构,操作系统会在内存中存储这些信息,这些信息通常采用结构或对象的形式,这就是内核对象。在Windows里面,内核对象的结构是一个对象头紧接着一个对象体的方式组织的,这些对象体包括表示进程的nt!_EPROCESS、表示线程的nt!_ETHREAD、表示驱动的nt!_DRIVER_OBJECT、表示IRP的nt!_IRP等等等等。
二.EPROCESS
EPROCESS块是Windows操作系统管理进程所使用的内核对象。EPROCESS块包含了进程的PID、进程名、创建时间、PEB等属性。每一个进程都有一个EPROCESS块与之一一对应。(在WinDbg中输入命令dt nt!_EPROCESS可以查看其结构)。
三.检测方法的实现
检测方法是基于一种交叉视图的方法,其实就是分别从高层和底层获得列表,然后比较这两种列表,如果在底层有但是在高层没有的,就认为是被rootkit隐藏掉的对象了。
1.
获取高层进程列表
在高层的话有很多API可以用,在XP下做的使用我用的是使用CreateToolhelp32Snapshot、Process32First和Process32Next。后来在Vista下面用C#做,直接用Process.GetProcesses()就可以了:
Process[] processes =
Process.GetProcesses();
但是Process的ProcessName没有扩展名,这个问题比较麻烦,我的解决方法是去找进程在磁盘上的映像文件的扩展名,通过process.MainModule.FileName可以找到,但是里面有权限问题,参考这个网址可以解决:http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/3aa75320-0524-4c74-ac3b-2d8aca319c51
2.
获取底层列表
(1)
Vista的EPROCESS
首先用windbg看一下Vista下面的EPROCESS的结构,和XP下有一些差别。vista的EPROCSS后面跟了个_ALPC_PROCESS_CONTEXT,我还没看是怎么回事。主要看几个属性的位置:peb、id、exit time。然后看看内核对象头的结构(dt nt!_OBJECT_HEADER),这个结构跟XP下是一样的。
(2)
扫描内存
枚举MmSystemRangeStart(0x80000000,唉,跟linux不一样,写程序的时候千万别写成0xc0000000了)以上的虚拟地址,关键在于判断该虚拟地址是否有效,uty的方法是判断PDE和PTE的present位是否为1,我在XP下也是那样的,感觉很过瘾,有点无限接近系统底层的感觉,但是到了vista下面就不对了,我猜想可能是PAE的原因?所以我直接用了MmIsAddressValid()来判断。
(3)
判断EPROCESS的有效性
每个EPROCESS的对象头里的type是相同的,所以只需要获得System进程的对象头,然后和其它的对比就可以了,但是有一些已经停止运行的进程的EPROCESS还保留着内存中,所以扫描得到的结果会包含已经停止运行的进程。所以还需要判断EPROCESS是不是正在运行的进程的,判断EPROCESS里的exit time是不是0就可以了。
3.
通信
内核里得到的进程怎么传出来呢?找了找DeviceIoControl的介绍,设置了两个控制码:得到进程个数的和得到进程列表的。
4.
贴个图
做了一半的工具



四.一点想法
先记下来备忘吧!
1.
可以扩展到其他的内核对象,下一步试试扫描驱动对象
2.
EPROCESS里有很多可挖的东西,比如说导入的dll。现在dll注入很多,写个钩子能够实现隐藏进程导入的dll的rootkit,似乎还没有这样的rootkit,如果有的话,试试从EPROCESS里扫描得到真实的dll列表。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: