当前位置:编程学习 > 网站相关 >>

内核监视进程创建的另一用处

作者:Cryin (http://hi.baidu.com/justear)

最近遇到个问题,当一个内核模块协同于应用层程序而共同工作时,那么试想如果应用程序意外没有运行或者运行失败,而驱动程序却老早就被加载了或者随机就启动了。那么这时存在一种可能驱动因为应用程序没有运行的原因致使某些操作错误导致计算机蓝屏。这个问题貌似并不多见,甚至一时都找不到蓝屏的原因。大多数情况不会想到是因为驱动本身之外的缘故。举一个比较极端的实例,之前我写过一个基于C/S模式的网络通信程序,其中服务端就是基于TDI实现的。因为系统网络设备没有加载或者还未初始化完成,这个时候这个TDI驱动就被加载并进行一些建立连接的操作。那么这时就可能导致蓝屏了!因为找不到设备L"\Device\Tcp",何谈TDI的操作呢。当然一般情况下系统的网络设备都早早的初始化好了。但是这里考虑一个极端的问题。假设我们在MBR中对磁盘读写、NTLDR及Ntoskrnl进行HOOK从而可以在Winlogon.exe运行之前就加载驱动程序。那么这个时候系统网络设备必然还未准备好,那么这时就出现蓝屏现象了!就像当时我选择监视explorer.exe进程的创建一样。这里同样可以监视特定的进程而开放驱动程序中的一些操做。这里使用函数PsSetLoadImageNotifyRoutine,当然也可以使用PsSetCreateProcessNotifyRoutine,只是貌似大家都在用这个,我就说一个不同的。函数原型如下:

NTSTATUS PsSetLoadImageNotifyRoutine(   __in  PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine ); 

MSDN里面是这样介绍的:

The PsSetLoadImageNotifyRoutine routine registers a driver-supplied callback that is subsequently notified whenever an image is loaded (or mapped into memory).

看一下还是和PsSetCreateProcessNotifyRoutine不一样的。显然这里只有一个参数呵呵,NotifyRoutine指定的回调例程。与其对应的可以使用PsRemoveLoadImageNotifyRoutine删除这个回调例程,两个函数的参数都是一样的。使用方法:

PsSetLoadImageNotifyRoutine(&NotifyRoutine);

这里要注意我们使用的是PsSetLoadImageNotifyRoutine而并非PsSetCreateThreadNotifyRoutine所以要自己在做一些判断处理,如下:

VOID NotifyRoutine

(IN PUNICODE_STRING ImageName, IN HANDLE ProcessId, IN PIMAGE_INFO  ImageInfo)

{

  //这里只假设C盘为系统盘了,你也可以多加一个判断

  if (_wcsnicmp(FullImageName->Buffer, L"\Device\HarddiskVolume1\Programme\Support Tools\explorer.exe", 58) == 0 

       ||_wcsnicmp(FullImageName->Buffer, L"\Device\HarddiskVolume1\Windows\explorer.exe", 51) == 0 )

     {

              ....

              //如果explorer.exe进程创建,那么在这里进行我们的操作,否则不做任何操作

              ....

     }

}

当然这个似乎简单的不能再简单了,但类似的问题并不是每个人都能想到这样的方法。因为学以致用大家总是只是说说而已呵呵

补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,