【windows内核驱动开发】文件系统微过滤驱动Minifilter——获取进程信息

【我的】文件系统微过滤驱动Minifilter——获取进程信息

作者:zcr214 时间:2016/4/22

 

在编写文件系统微过滤驱动minifilter的时候,除了绑定指定的磁盘分卷,对于指定的文件很可能还会有指定的应用程序,例如txt文件可以有很多编辑器可以使用,如wordpad,notepad,sublime,vim,notepad+等,doc文档可以使用office word或WPS,图片文件就更多了。虽然仅靠过滤进程名来筛选出指定程序的方式不太安全,黑客可以通过伪装进程名的方式绕过,但是获取进程信息(进程ID,进程名等)对于minifilter驱动所需的基本功能的开发有着重要的作用。

1.    设置加载进程通知PsSetCreateProcessNotifyRoutine()

可以使用PsSetCreateProcessNotifyRoutine()来设置一个通知回调函数。每当操作系统创建或者关闭一个进程的时候,回调都会被调用。

NTSTATUS

PsSetCreateProcessNotifyRoutine(

   _In_PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,

   _In_BOOLEAN Remove  );

返回状态值,表示设置通知回调是否成功,参数中包含一个设置的通知回调函数的指针和是否移除的标记,移除标记设为false表示设置通知回调,true表示卸载通知回调,当驱动启动时在DriverEntry中需要设置通知回调,驱动停止时当然也要在FilterUnload中卸载这个通知回调。

通知回调函数的原型为:

VOID

(*PCREATE_PROCESS_NOTIFY_ROUTINE)(

    _In_HANDLE ParentId,

    _In_HANDLE ProcessId,

    _In_BOOLEAN Create    );

显而易见的,可以在通知回调函数中获取到这个进程的ID和父进程ID,以及创建或关闭的标记。

2.    设置加载映像通知PsSetLoadImageNotifyRoutine()

可以使用PsSetLoadImageNotifyRoutine()设置一个通知回调函数,每当操作系统新加载一个映像文件的时候,设置的回调函数就会被调用。

PsSetLoadImageNotifyRoutine()函数原型如下:

NTSTATUS

PsSetLoadImageNotifyRoutine(

    _In_PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine

);

返回一个状态值,表示设置通知回调函数是否成功,参数只有一个,即通知回调函数的指针。在驱动启动时在DriverEntry设置通知回调,驱动停止时也需要在FilterUnload中卸载通知回调,使用另一个相对应的函数PsRemoveLoadImageNotifyRoutine(),函数原型和Set函数类似。

加载映像的通知回调函数的原型如下:

VOID

(*PLOAD_IMAGE_NOTIFY_ROUTINE)(

    _In_PUNICODE_STRING FullImageName,

    _In_HANDLE ProcessId,// pid into which image is being mapped

    _In_PIMAGE_INFO ImageInfo

);

显而易见的,可以在通知回调函数中得到完整的映像名称,进程ID,和其他的映像相关信息。

3.    实际使用一下

(1)   DriverEntry中,启动过滤之前,设置通知回调。

   //启动获取进程,映像信息的回调

   PsSetCreateProcessNotifyRoutine(ProcessNotify,FALSE);

   PsSetLoadImageNotifyRoutine(LoadImageNotify);

   // Start filtering i/o

(2)   FilterUnload中,停止过滤之前,取消通知回调。

   // 驱动关闭,移除进程和映像信息获取的回调

   PsSetCreateProcessNotifyRoutine(ProcessNotify,TRUE);

   PsRemoveLoadImageNotifyRoutine(LoadImageNotify);

// Unregister from FLT mgr

(3)   编写进程通知回调函数,打印进程信息。

VOID

ProcessNotify(

INHANDLE  ParentId,

INHANDLE  ProcessId,

INBOOLEAN  Create)

{

   DbgPrint("FilterProcessNotify,pid: %d, tid: %d, create: %d\n",ParentId,ProcessId,Create);

}

(4)   编写映像通知回调函数,保存进程ID和映像名称信息(这里事先已经定义了一个全局的ProcessList数组用于保存映像名)。

VOID

LoadImageNotify(

__in_optPUNICODE_STRINGFullImageName,

__inHANDLEProcessId,

__inPIMAGE_INFOImageInfo)

{

   UNREFERENCED_PARAMETER(ImageInfo);

      __try{

         ProcessList[(int)ProcessId]=FullImageName;

         DbgPrint("image name :%wZ pid is:%d",ProcessList[(int)ProcessId],ProcessId);

      }

      __except(EXCEPTION_EXECUTE_HANDLER){

         DbgPrint("pid:%d,cannot insert to ProcessList",ProcessId);

      }

}

当然上述的保存方法相对简单,在具体应用中应该视具体的需求而定,也可自定义一个表,将所有进程信息都保存起来,需要检查的时候再利用进程ID将具体信息取出来。

 

你可能感兴趣的:(windows内核驱动开发,驱动开发,文件系统,windows,进程)