WEB开发网
开发学院软件开发VC 文件过滤系统驱动开发Filemon学习笔 阅读

文件过滤系统驱动开发Filemon学习笔

 2007-12-30 21:37:20 来源:WEB开发网   
核心提示:本文示例源代码或素材下载 WINDOWS文件过滤系统驱动开发,可用于硬盘还原,文件过滤系统驱动开发Filemon学习笔,防病毒,文件安全防护,比如应用层向驱动传递需要挂接或者监控的分区盘符,或者是否挂接盘符,文件加密等诸多领域,而掌握核心层的理论及实践

本文示例源代码或素材下载

WINDOWS文件过滤系统驱动开发,可用于硬盘还原,防病毒,文件安全防护,文件加密等诸多领域。而掌握核心层的理论及实践,对于成为一名优秀的开发人员不可或缺。

WINDOWS文件过滤系统驱动开发的两个经典例子,Filemon与SFilter,初学者在经过一定的理论积累后,对此两个例子代码的研究分析,会是步入驱动开发殿堂的重要一步,相信一定的理论积累以及贯穿剖析理解此两个例程后,就有能力开始进行文件过滤系统驱动开发的实际工作了。

对于SFilter例子的讲解,楚狂人的教程已经比较流行,而Filemon例子也许因框架结构相对明晰,易于剖析理解,无人贴出教程,本人在剖析Filemon的过程中积累的一些笔记资料,陆续贴出希望对初学者有所帮助,并通过和大家的交流而互相提高。

Filemon学习笔记 第一篇:

Filemon的大致架构为,在此驱动程序中,创建了两类设备对象。

一类设备对象用于和Filemon对应的exe程序通信,以接收用户输入信息,比如挂接或监控哪个分区,是否要挂接,是否要监控,监控何种操作等。此设备对象只创建了一个,在驱动程序的入口函数DriverEntry中。此类设备对象一般称为控制设备对象,并有名字,以方便应用层与其通信操作。

第二类设备对象用于挂接到所须监控的分区,比如c:,d:或e:,f:,以便拦截到引应用层对该分区所执行的读,写等操作。此类设备对象为安全起见,一般不予命名,可根据须监控多少分区而创建一个或多个。

驱动入口函数大致如下:

NTSTATUS
DriverEntry(
  IN PDRIVER_OBJECT DriverObject,
  IN PUNICODE_STRING RegistryPath
  )
{
  NTSTATUS        ntStatus;
  PDEVICE_OBJECT     guiDevice;
  WCHAR          deviceNameBuffer[] = L"DeviceFilemon";
  UNICODE_STRING     deviceNameUnicodeString;
  WCHAR          deviceLinkBuffer[] = L"DosDevicesFilemon";
  UNICODE_STRING     deviceLinkUnicodeString;
  ULONG          i;
  DbgPrint (("Filemon.SYS: entering DriverEntry
"));
  FilemonDriver = DriverObject;
  //  
  // Setup the device name
  //  
  RtlInitUnicodeString (&deviceNameUnicodeString,
             deviceNameBuffer );
  //
  // Create the device used for GUI communications
  //此设备对象用来和用户交互信息
  ntStatus = IoCreateDevice ( DriverObject,
                sizeof(HOOK_EXTENSION),
                &deviceNameUnicodeString,
                FILE_DEVICE_FILEMON,
                0,
                TRUE,
                &guiDevice );
  //
  // If successful, make a symbolic link that allows for the device
  // object's access from Win32 programs
  //
  if(NT_SUCCESS(ntStatus)) {
    //
    // Mark this as our GUI device
    //
    ((PHOOK_EXTENSION) guiDevice->DeviceExtension)->Type = GUIINTERFACE;
    //
    // Create a symbolic link that the GUI can specify to gain access
    // to this driver/device
    //
    RtlInitUnicodeString (&deviceLinkUnicodeString,
               deviceLinkBuffer );
    ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString,
                     &deviceNameUnicodeString );
    if(!NT_SUCCESS(ntStatus)) {
      DbgPrint (("Filemon.SYS: IoCreateSymbolicLink failed
"));
      IoDeleteDevice( guiDevice );
      return ntStatus;      
    }
    //
    // Create dispatch points for all routines that must be handled.
    // All entry points are registered since we might filter a
    // file system that processes all of them.
    //
    for( i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++ ) {
      DriverObject->MajorFunction[i] = FilemonDispatch;
    }
#if DBG    
    //
    // Driver unload is only set if we are debugging Filemon. This is
    // because unloading a filter is not really safe - threads could
    // be in our fastio routines (or about to enter them), for example,
    // and there is no way to tell. When debugging, we can risk the
    // occasional unload crash as a trade-off for not having to
    // reboot as often.
    //
    // DriverObject->DriverUnload = FilemonUnload;
#endif // DBG
    //
    // Set up the Fast I/O dispatch table
    //
    DriverObject->FastIoDispatch = &FastIOHook;
  } else {
    //
    // If something went wrong, cleanup the device object and don't load
    //
    DbgPrint(("Filemon: Failed to create our device!
"));
    return ntStatus;
  }
  //
  // Initialize the name hash table
  //
  for(i = 0; i < NUMHASH; i++ ) HashTable[i] = NULL;
  //
  // Find the process name offset
  //
  ProcessNameOffset = FilemonGetProcessNameOffset();//为了得到当前进程名字
  //
  // Initialize the synchronization objects
  //
#if DBG
  KeInitializeSpinLock( &CountMutex );
#endif
  ExInitializeFastMutex( &LogMutex );
  ExInitializeResourceLite( &FilterResource );
  ExInitializeResourceLite( &HashResource );
  //
  // Initialize a lookaside for file names
  //
  ExInitializeNPagedLookasideList( &FullPathLookaside, NULL, NULL,
           0, MAXPATHLEN, 'mliF', 256 );
  //
  // Allocate the first output buffer
  //
  CurrentLog = ExAllocatePool( NonPagedPool, sizeof(*CurrentLog) );
  if( !CurrentLog ) {
    //
    // Oops - we can't do anything without at least one buffer
    //
    IoDeleteSymbolicLink( &deviceLinkUnicodeString );
    IoDeleteDevice( guiDevice );
    return STATUS_INSUFFICIENT_RESOURCES;
  }
  //
  // Set the buffer pointer to the start of the buffer just allocated
  //
  CurrentLog->Len = 0;
  CurrentLog->Next = NULL;
  NumLog = 1;
  return STATUS_SUCCESS;
}
在此驱动入口点函数中,主要做了生成新的设备对象,此设备对象用来和应用层信息交互,比如应用层向驱动传递需要挂接或者监控的分区盘符,或者是否挂接盘符,是否监控操作等。

1 2 3 4 5 6  下一页

Tags:文件 过滤

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接