574 views
首页 > 内核编程, 技术心得 > Sfilter 在 Win2000 下动态加载的实现

Sfilter 在 Win2000 下动态加载的实现

2008年4月17日

Sfilter 是 MS 提供的一个例子文件系统过滤驱动程序. 在 IFS Kit 中可以找到源代码. 在系统安全等相关方面等用得很多了,例如 文件的透明加密解密,只允许特定的进程访问特定的文件。Sfilter可以在XP,20003中动态加载, 在 2000 下却不可以. 通过如下的代码可以实现在 2000 下的动态加载。

有两种方法可以实现。第一种是首先获得文件系统驱动 DRIVER_OBJECT 的指针,然后通过,然后通过遍历 DRIVER_OBJECT 中保存的设备对象的链表,得到已经被文件系统驱动 MOUNT 的卷设备对象指针。代码如下

// 声明未公开的变量的函数原型
extern POBJECT_TYPE *IoDriverObjectType;
extern
NTKERNELAPI
NTSTATUS
ObReferenceObjectByName(
       IN PUNICODE_STRING ObjectName,
       IN ULONG Attributes,
       IN PACCESS_STATE PassedAccessState OPTIONAL,
       IN ACCESS_MASK DesiredAccess OPTIONAL,
       IN POBJECT_TYPE ObjectType,
       IN KPROCESSOR_MODE AccessMode,
       IN OUT PVOID ParseContext OPTIONAL,
       OUT PVOID *Object  ); 

VOID
SfAttachToVolumeDevice(  )
{
 UNICODE_STRING         szLinkPath;
 PDRIVER_OBJECT         lpDriverObject;
 NTSTATUS               Status;
 OBJECT_ATTRIBUTES      ObjectAttributes;
 PDEVICE_OBJECT         currentDevice  = NULL;

 RtlInitUnicodeString(&szLinkPath, L"\\FileSystem\\FastFat");
 InitializeObjectAttributes(&ObjectAttributes,
                            &szLinkPath,
                            OBJ_CASE_INSENSITIVE,
                            NULL,
                             NULL);
 Status = ObReferenceObjectByName( &szLinkPath,
                                   OBJ_CASE_INSENSITIVE,
                                   NULL,
                                   0,
                                   *IoDriverObjectType,
                                   KernelMode,
                                   NULL,
                                   &lpDriverObject );
 currentDevice = lpDriverObject->DeviceObject;
 while( currentDevice != NULL )
 {
    SfFsNotification( currentDevice, TRUE );
    currentDevice = currentDevice->NextDevice;
 }
 RtlInitUnicodeString(&szLinkPath, L"\\FileSystem\\Ntfs");
 InitializeObjectAttributes(&ObjectAttributes,
                            &szLinkPath,
                            OBJ_CASE_INSENSITIVE,
                            NULL,
                            NULL
                            );
 Status = ObReferenceObjectByName( &szLinkPath,
                                   OBJ_CASE_INSENSITIVE,
                                   NULL,
                                   0,
                                   *IoDriverObjectType,
                                   KernelMode,
                                   NULL,
                                   &lpDriverObject);
 currentDevice = lpDriverObject->DeviceObject;
 while( currentDevice != NULL ){
   SfFsNotification( currentDevice, TRUE );
   currentDevice = currentDevice->NextDevice;
 }

}

 }
}

第二种是 像FileMonitor一样。从卷A: 到卷Z:都尝试挂接一遍

VOID
SfAttachToMountedVolume( )
{
 WCHAR            filename[] = L"\\DosDevices\\A:\\";
 UCHAR            index = 2;
 UNICODE_STRING   fileNameUnicodeString;
 NTSTATUS         ntStatus;
 for( ;index < 26 ; index ++ )
 {
  OBJECT_ATTRIBUTES   objectAttributes;
  IO_STATUS_BLOCK     ioStatus;
  HANDLE              ntFileHandle;
  PFILE_OBJECT        f ileObject;
  PDEVICE_OBJECT      volumeDevice;
  filename[12] = (CHAR) ('A'+index);
  RtlInitUnicodeString( &fileNameUnicodeString, filename );
  InitializeObjectAttributes( &objectAttributes,
                              &fileNameUnicodeString,
                              OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE ,
                              NULL,
                              NULL
                              );
  ntStatus = ZwCreateFile( &ntFileHandle,
                           SYNCHRONIZE|FILE_ANY_ACCESS,
                           &objectAttributes,
                           &ioStatus, NULL,
                           0,
                           FILE_SHARE_READ|FILE_SHARE_WRITE,
                           F ILE_OPEN,
                           FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE,
                           NULL,
                           0 );
 if( !NT_SUCCESS( ntStatus )  )
 {
   continue;
  }
  ntStatus = ObReferenceObjectByHandle( ntFileHandle,
                                        FILE_READ_DATA,
                                        NULL,
                                        KernelMode,
                                        &fileObject,
                                        NULL );
if( !NT_SUCCESS( ntStatus ))
{
    ZwClose( ntFileHandle );
    continue;
}
volumeDevice = IoGetRelatedDeviceObject( fileObject );
if( !volumeDevice )
{
    ObDereferenceObject( fileObject );

    ZwClose( ntFileHandle );
    continue;
}
if( volumeDevice->DeviceType != FILE_DEVICE_DISK_FILE_SYSTEM )
{
   continue;
}
  SfFsNotification( volumeDevice, TRUE );

最后。如果想控制插入U盘,移动硬盘,光盘,别忘了把过滤器挂接到文件系统设备对象上哦!

VOID
SfAttachToFileSystem( )
{
 PFILE_OBJECT      fileObject;
 PDEVICE_OBJECT    deviceObject;
 NTSTATUS          status;
 UNICODE_STRING    strDeviceName;
 RtlInitUnicodeString( &strDeviceName, L"\\Fat" );
 status = IoGetDeviceObjectPointer( &strDeviceName,
                                     FILE_READ_ATTRIBUTES,
                                     &fileObject,
                                     &deviceObject
                                     );
if( NT_SUCCESS( status ) )
{
  ObDereferenceObject( fileObject );
  SfFsNotification( deviceObject, TRUE);
}
 RtlInitUnicodeString( &strDeviceName, L"\\Ntfs" );
 status = IoGetDeviceObjectPointer( &strDeviceName,
                                    FILE_READ_ATTRIBUTES,
                                    &fileObject,
                                    &deviceObject
                                    );
if( NT_SUCCESS( status ) )
{
  ObDereferenceObject( fileObject );
  SfFsNotification( deviceObject, TRUE);
 }
 RtlInitUnicodeString( &strDeviceName, L"\\Cdfs" );

 status = IoGetDeviceObjectPointer( &strDeviceName,
                                    FILE_READ_ATTRIBUTES,
                                    &fileObject,
                                    &deviceObject
                                     );

if( NT_SUCCESS( status ) )
{
  ObDereferenceObject( fileObject );
  SfFsNotification( deviceObject, TRUE);
 }
}

内核编程, 技术心得 ,

  1. 目前还没有任何评论.
  1. 目前还没有任何 trackbacks 和 pingbacks.