存档

文章标签 ‘sfilter’
3,487 views

在 VS 2008 内开发驱动程序的 “解决方案” 的编译链接选项的设置

2008年7月9日
    • General
      Additional Include Directories:
      C:\WINDDK\2600\inc\wxp
      C:\WINDDK\2600\inc\ddk\wxp
      C:\WINDDK\2600\inc\ddk\wdm\wxp
      C:\WINDDK\2600\inc\crt
      Debug Information Format : Program Database (/Zi)
    • Optimization
      Enable Intrinsic Functions: Yes (/Oi) … To avoid the memcmp compile error.
    • Preprocessor
      Preprocessor Definitions:
      _X86_=1
      i386=1
      _WIN32_WINNT=0×0501
      WINVER=0×0501
      WIN32_LEAN_AND_MEAN=1 … dont know if this does much for a device driver
      Ignore Standard Include Path:Yes (/X)
    • Code Generation
      Enable C++ Exceptions:No … no exception handling in the kernel!
      Buffer Security Check:No (/GS-) … linker error if set to Yes
      Basic runtime Checks: Default
    • Advanced
      Calling Convention:__stdcall (/Gz)
    • Language
      Enable Run-Time Type Info:No (/GR-) … linker error if set to Yes
    • Input
      Additional Dependencies:int64.lib ntoskrnl.lib hal.lib … etc.
      Ignore All Default Libraries:Yes (/NODEFAULTLIB)
    • Manifest File
      Generate Manifest:No
    • System
      SubSystem:Native (/SUBSYSTEM:NATIVE)
      Driver:Driver (/DRIVER)
    • Advanced
      Base address:0×10000
      Entry Point:DriverEntry
      Target Machine:MachineX86 (/MACHINE:X86)
      Randomized Base Address:Default
      Data Execution Prevention (DEP) : default
    • General
      Additional Library Directories:C:\WINDDK\2600\lib\wxp\i386
      Enable Incremental linking: No (/INCREMENTAL:NO)
      Output file: $(OutDir)\$(ProjectName).sys
    • Command line
      add there /safeseh:no option
  1. I’ll give you what I found, but all I can say is don’t do it.

    There are always problems linking one version of the CRT against a version of a compiler that it wasn’t written for.

    Create a win32 DLL project.

    C/C++ settings for VC2008

    阅读全文…

内核编程, 技术心得 , , , , ,

1,107 views

sfilter 流程浅析

2008年4月17日

基本思路其实不复杂,sfilter 先创建一个control device object,用于接受应用程序的控制,然后创建多个device object,绑定到文件系统驱动的device object上(譬如NTFS,FAT,CDFS,等等),这里要注意不要绑到文件系统识别器(file system recognizer)上,它是用来加载真正的文件系统驱动程序的。
  绑定完文件系统驱动的device object后,sfilter就可以收到发给各个文件系统驱动程序的irp了,这样你可以在windows要求文件系统装配各个卷的时候获得消息,然后你就可以得到文件系统为各个卷所创建的device object,然后再创建device object,绑定到这些volumn object上,下面的工作就是用你的FiDO过滤发往各个卷的irp,取得文件名称及其操作,进行判断,如果是对敏感文件的操作,fail掉该irp,这样就可以了。
  第一步:创建CDO,这是在DriverEntry里:

  NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
  {
   ……
   // Create the Control Device Object(CDO). This object represents this
   // driver. Note that it does not have a device extension.
   RtlInitUnicodeString(&wstrName, L"\FileSystem\Filters\SFilter");
   ntStatus = IoCreateDevice(pDriverObject,
   0, //has no device extension
   &wstrName,
   FILE_DEVICE_DISK_FILE_SYSTEM,
   FILE_DEVICE_SECURE_OPEN,
   FALSE,
   &gSFilterControlDeviceObject);
   ……
  }

阅读全文…

内核编程, 技术心得

647 views

Windows 文件过滤驱动经验总结

2008年4月17日

发自己心得的人无非是两种目的,一是引发一些讨论,好纠正自己错误的认识,以便从中获取更多的知识使自己进步的更快。二是做一份备忘,当自己遗忘的时候能够马上找到相关资料。我这里也总结了近几年做文件过滤驱动时所积累下来的一些小小经验,这分笔记也是看了 ChuKuangRen 的
教程后,临时想到的一小部分而已,是想到哪写到哪,不是很全,如果以后再回想起什么也会不断补充。因其工作原因,近段时间在 SOLARIS 驱动与 Linux 内核方面投入的精力比较多,Windows 下的文件过滤驱动一直也没有怎么去碰,所以最后还是那句老话 FIXME。

1、获得文件全路径以及判断时机

除在所有 IRP_MJ_XXX 之前自己从头创建 IRP 发送到下层设备查询全路径外,
不要尝试在 IRP_MJ_CREATE 以外的地方获得全路径,因为只有在 IRP_MJ_CREATE
中才会使用 ObCreateObject() 来建立一个有效的 FILE_OBJECT。而在 IRP_READ
IRP_WRITE 中它们是直接操作 FCB (File Control Block)的。

2、从头建立 IRP 发送关注点

无论你建立什么样的 IRP,是 IRP_MJ_CREATE 也好还是 IRP_MJ_DIRECTORY_CONTROL
也罢,最要提醒的就是一些标志。不同的标志会代来不同的结果,有些结果是直接
返回失败。这里指的标志不光是 IRP->Flags,还要考虑 IO_STACK_LOCATION->Flags
还有其它等等。尤其是你要达到一些特殊目的,这时候更需要注意,如 IRP_MN_QUERY_DIRECTORY,
不同的标志结果有很大的不同。

3、从头建立 IRP 获取全路径注意点

自己从头建立一个 IRP_MJ_QUERY_INFORMATION 的 IRP 获取全路径时需要注意,
不仅在 IRP_MJ_CREATE 要做区别处理,在 IRP_MJ_CLOSE 也要做同样的处理,
否则如果目标是 NTFS 文件系统的话可能产生 deadlock。如果是 NTFS 那么在
IRP_MJ_CLEANUP 的时候也需要对 FO_STREAM_FILE 类型的文件做同样处理。

阅读全文…

内核编程, 技术心得

574 views

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;
 }

}

 }
}

阅读全文…

内核编程, 技术心得 ,

532 views

FS & Recognizer & Filter

2008年4月17日

注一:

File system recognizer 文件系统识别器(下文简称为recognizer)
File system 文件系统 (下文简称为fs)
File system filter 文件系统过滤器(下文简称为filter)

文件系统识别器是一个标准的NT内核模式驱动程序;它只实现一项功能:检查物理介质设备,如果它能够识别存储介质的格式便加载相应的文件系统驱动程序,利用它主要是为节约系统内存,文件系统驱动程序没用到时为什么让他在内存中呢?

文件系统过滤驱动的一般处理流程(参照sfilter):

阅读全文…

内核编程, 技术心得

692 views

sfilter 动态加解密吐血总结

2008年4月16日

晕了好几天, 总算把 IFS 的动态加解密给闹明白了.

  为了后来者不再晕,总结如下:

  • 加密在 SfWrite(IRP_MJ_WRITE) 中, 而不是完成例程.
  • 解密在 SfRead(IRP_MJ_READ) 中, 而不是完成例程
  • 只要处理 IRP_NOCACHE|IRP_PAGING_IO|IRP_SYNCHRONOUS_PAGING_IO
  • 加密简单过程
    1. 得到Windows传下来的 Buffer Address
        if (Irp->MdlAddress)
        {
          SysDataBuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
        }
        else
        {
          SysDataBuf = Irp->UserBuffer;
        }
    2. 保存明文 SysDataBuf 在 SysDataBufFirst
    3. 用你强大的算法加密SysDataBuf –>> MyBuf
    4. 把 MyBuf 复制到 SysDataBuf
    5. IoCallDriver 把密文向下传, 写入 HardDisk
    6. 恢复内存的明文 RtlCopyMemory(SysDataBuf, SysDataBufFirst, ulWriteLen);
  • 解密的大致过程
    1. IoCallDriver 读到密文
    2. 解密
    3. IoCompleteRequest 搞定

我的开发环境: IFS2600, SFilter 的代码却是 for XP SP1 的.

另一派的意见:
解密在 ReadCompleteRoutine 里实现没有问题. 当然 CALL FILESYSTEM 再处理也是一种方法.
还有在处理加密不时要去碰原来的 BUFFER, 而是自己分配一个 BUFFER 复制过来, 然后生成 MDL, 保存原先的 MDL, 替换系统原先的 MDL,在 WriteCompleteRoutine 中还原 MDL. 内存中要保持原有 BUFFER 为明文, 否则会出问题.

内核编程, 技术心得