使用PsSetCreateProcessNotifyRoutine检测隐藏进程

PsSetCreateProcessNotifyRoutine是DDK里的一个函数,“顾名思义”这个函数的功能是向系统注册一个回调函数(Call Back Function),每当有进程创建的时候,系统就会调用这个回调函数。这个回调函数执行的操作完全由程序员自己来决定。我们先看一下这个回调函数的函数签名

PsSetCreateProcessNotifyRoutine VOID(*PCREATE_PROCESS_NOTIFY_ROUTINE)
( IN HANDLE ParentId,
 
IN HANDLE ProcessId,
  IN BOOLEAN Create );
当系统调用已注册的回调函数时,会自动像这个函数传入三个参数ParentId,ProcessId,Create.
Create用来判断是否有新的进程被创建,ParentId,ProcessId这两个都是进程号,一个是父进程的,一个是当前被新创建的进程的。

《黑客防线》上有一篇文章介绍了如何使用这个函数来监视系统进程的创建,我借鉴参考学习剽窃其核心算法,想了一个查找那些在创建之初就被隐藏了的进程的方法。
大概思路是这样的:
1、将驱动加载入内核。
   在IRP_MJ_CREATE这个IRP派遣历程中调用PsSetCreateProcessNotifyRoutine,来注册一个回调函数
2、应用程序在UserMode通过DeviceIoControl函数来和驱动程序进行通信
应用程序和驱动程序之间通信,必须定义一些宏命令,在此我定义的两个宏命令是

//定义IOCTL_START宏,通知驱动程序开始监测进程的创建
define IOCTL_START CTL_CODE(\
                            FILE_DEVICE_UNKNOWN,\
                            0x800,\
                            METHOD_BUFFERED,\
                            FILE_ANY_ACCESS)
//定义I/O命令控制代码IOCTL_GET_PID 用来通知驱动程序将进程号返回
#define IOCTL_GET_PID CTL_CODE(\
                               FILE_DEVICE_UNKNOWN,\
                               0x801,\
                               METHOD_BUFFERED,\
                               FILE_ANY_ACCESS)
还需要说明的是,应用程序和驱动程序之间的同步机制。《黑防》上那篇文章给的办法是这样的,应用程序先创建一个事件对象,将这个事件对象的句柄通过调用DeviceIoControl给驱动程序发IOCTL_START命令,并将事件的句柄作为参数传递给驱动程序。在驱动层的IRP_MJ_DEVICE_CONTROL的派遣例程中,对I/O控制命令进行判断。如果是IOCTL_START 那么则从IRP的缓冲区里将事件对象的句柄取出,并通过函ObReferenceObjectByHandle获得用户态事件对象在内核态中事件对象的指针(这里需要说明一下,像事件,信号灯这些对象,在用户态用句柄HANDLE来标识,在内核用指针来标识)。这样驱动程序就可以通过事件对象的指针来操作事件对象以实现和应用程序的同步了。
应用程序在把事件句柄传递给驱动程序后,就在一个while循环中等待事件被激发(WaitForSingleObject)。
当有新进程被创建,回调函数就会被调用,在回调函数中将进程号和父进程号写入一个数据结构PROCESS_ID中,然后调用KeSetEvent激发事件对象。当事件对象被激发后,应用程序中WaitForSingleObject函数会返回,应用程序得以继续向下执行。接下来,应用程序调用DeviceIoControl向驱动程序发出IOCTL_GET_PID命令,并提供给驱动程序一块足够大的缓冲区。驱动程序在收到这个命令后,就会将PROCESS_PID结构体中的进程号写入应用程序提供的缓冲区中。DeviceIoControl返回之后,应用程序就可以从缓冲区中读取驱动程序传过来的新建进程的进程号何父进程号了。接下来,创建一个新线程,在线程函数中遍历当前系统的所有进程。并将每一个进程的进程号和新建进程的进程号相比较,如果匹配上,那么说明新建进程没有被隐藏。如果没有一个进程号和新建进程的进程号相同,那么说明这个新建的进程已经被隐藏!!

     说得比较混沌,还是直接看源码吧,我写了比较详实的注释。有什么问题再讨论吧。
     其实这种方法还是比较有局限性的,智能检测那些刚被创建就被隐藏的进程,对在监测程序运行之前就已经被隐藏的进程还是每一点办法的。但我觉得《黑防》给我们提供的很好的思路就是如何实现应用程序和驱动程序之间的同步通信!

你可能感兴趣的:(window系统内核编程,软件安全,file,access,数据结构,ddk,function,算法)