精华内容
下载资源
问答
  • 文件系统过滤驱动实现文件隐藏

    热门讨论 2010-03-18 09:36:31
    C盘对应的设备对象是\Device\HarddiskVolume1文件系统过滤驱动,就是在文件系统驱动上生成自己的设备,然后去绑定这些设备,从而实现对发送给卷设备的IRP进行过滤,进而过滤各种文件操作。比如文件隐藏。
  • 文件过滤驱动

    千次阅读 2018-06-02 15:52:02
    文件过滤驱动一、文件透明加解密关键字:透明、文件过滤驱动、加密标识,缓存 文件过滤驱动最重要的两点是搞定加密标识和缓存管理1、透明概念:透明指的是用户在操作的时候,虽然后台在自动的进行加解密,但是用户...

    文件过滤驱动

    一、文件透明加解密

    关键字:透明、文件过滤驱动、加密标识,缓存

     

    文件过滤驱动最重要的两点是搞定加密标识和缓存管理

    1、透明概念:

    透明指的是用户在操作的时候,虽然后台在自动的进行加解密,但是用户根本就不知道加密的存在,就像中间隔了一层透明的玻璃一样。

         透明的好处在于不改变用户的操作,一切都和加密之前一样,甚至在有些企业安装加密后都无需通知所有的员工,就像加密并不存在一样,只是加密文件到了企业安全环境的外部才会发现文件无法打开。

    透明的程度也是加密软件一个很重要的方面,例如:正在编辑一个Word文件时,能否拷贝或者使用其他程序来读取这个文件,如果不能那么这里就不够透明,在一些PDM的文档管理软件中就是文件在一个应用程序打开状态时另一个应用程序进行检入。透明的程度越高,用户使用时就越是和未加密时一样,透明程序越低用户就会发现有越多的操作受到限制,和加密前有较大的差异。

    2、加密类型:

    加密类型

    加密原理

    举例

    静态加密

    把整个文件加密掉、或者把整个文件加密掉。

     

    动态加密

    文件整体是加密状态,需要解密时读取多少就解密多少,写入多少就加密多少,而不需要把整个文件都解密掉。

     

    主动加密

     

    由使用者自行要求文件变成加密状态称之为主动加密

    主动加密的方式很多,例如用WinRar把文件压缩并定义一个口令,或者给Word、Excel文件一个打开或者修改的口令,这样其他人使用时必须由正确的口令才能打开,这是使用者主动进行的加密,如果使用者不进行加密则文件不会在加密状态。只针对某些文件夹加密的方式也可以理解为主动加密方式。主动加密主要应用于个人的文件保护。

    被动加密

    使用者并不知道或者并不想文件变成加密状态,系统自动将文件加密,称之为被动加密。

    被动加密主要用于企业内部防止文件泄密,即使使用者不想文件被加密,系统还是会根据定义加密文件,这样文件被拷贝等各种方法脱离企业环境后,由于文件在加密状态而无法打开。被动加密具有另一个特性就是透明操作,即使用者并不需要进行加密和解密操作,一切都是后台自动完成,使用者可以不知道加密的存在。被动加密与作者的意愿无关,相关文件都会被加密,磁盘加密和文件透明加解密属于此类。

       

       

    3、文件过滤驱动怎样加密:

    文件过滤驱动是微软公开支持进行文件加密的技术手段,在驱动的层次定义中,微软定义了杀毒、压缩、加密等各种功能层次,加密的定义如下:
         Load Order Group:FSFilter Encryption ,Altitude Range:140000-149999

         由于文件过滤驱动处于驱动层面(不像API Hook处于应用层),可以控制系统的更多细节,和应用程序的关联度很小,可以兼容所有的应用程序,使用文件过滤驱动更利于进行动态加解密的处理。

         API Hook 主要是拦截打开和关闭的动作,在这2个动作里做文件的静态加解密处理;而文件过滤驱动主要拦截的读和写的动作,在这2个IRP请求中进行动态的加解密处理,处理的内容很精确(读多少解密多少、写多少加密多少),由于动态加解密实际上处理的大多数都是缓存,没有磁盘IO操作速度更快。当然文件过滤驱动中进行动态加解密的技术难度也要大得多。

     

         由于原有的Legacy Filter架构在很多杀毒等软件中使用,微软于近几年推出了MiniFilter架构,旨在减少各驱动间的冲突,提高工作效率,是微软大力推广的技术架构,可以在后续的各种新操作系统中使用而不用担心。MiniFilter具有兼容、高效、标准、稳定等各种优点。

    4、文件加密标记:

    加密标记是指如何判断一个文件是否加密的关键,也是在做动态透明加解密开发中最为重要的一环,加密标记的正确与否决定了文件是否会丢失、损坏,是必须要保证不能出任何问题的技术关键点。加密标记一般可存放在文件外部和文件内部,存放于文件内部时,又常分为存放在文件头上、文件尾上、压缩在文件内等三类技术方法,相关介绍如下:

    序号

    标记存储位置

    类型

    文件变长

    方法

    1

    数据库中

    文件外部

    文件的加密状态记录在数据库中,判断文件加密状态时读取数据库,缺点巨大,在驱动中是很难访问数据库的,且若数据库丢失则所有文件都可能无法打开了。

    2

    文件目录中

    文件外部

    文件的加密状态记录在其所在的目录中,文件所属目录变化时程序需要处理各种细节,且存在记录丢失整个目录文件无法打开的可能性。

    3

    文件名上

    文件内部

    将文件的名字加上一个后缀来识别是否加密过且使用技术手段对用户隐藏掉这个后缀,通用性不好且容易被人为不小心去掉加密标记。

    4

    文件属性里

    文件内部

    将文件的时间或者其他属性改变一下,例如将时间加上1000年且向用户隐藏掉这个变化,通用性太差且加密标记极易丢失。

    5

    压缩在文件里

    文件内部

    最好的思路可惜无法兼容所有的文件,一方面如果文件太小,可能很难进行压缩,对于一些压缩软件产生的压缩文件无法继续压缩等,通用性很差。

    6

    文件头上

    文件内部

    在文件头部附加一段内容来记录文件的加密标记,和文件尾的对比见图1

    7

    文件尾上

    文件内部

    在文件尾部附加一段内容来记录文件的加密标记,和文件头的对比见图1

        实际上,考虑到整体系统的稳定性和可管理性,文件的加密标记存放在文件内部,更能保证标记的可靠性、恒久性和通用性,而使用重定向原理时由于是静态加解密,加密标记存放位置对此类产品的影响不大。我们这里把使用动态加解密原理时的文件头和文件尾技术进行对比:

        假设一个文件的开头位置是P1,结束位置是P2,加密标记的长度是L,带文件头和带文件尾有不同的状态,然后需要发出一个写操作从Pw1位置写到Pw2位置,此事写操作会超过原有的结束位置P2,如图1

     

    图1 动态加解密时文件头和文件尾对比

     文件头标记的处理方法:仅改变写入位置参数将Pw1= Pw1+L然后加密Pw2-Pw1这段内容并传递下去。
        文件尾标记的处理方法也有两种:一种方法是将L段加密标记复制到内存中,然后加密Pw2-Pw1这段内容并原位置传递下去,再到Pw2的位置把L段加密标记接上去;另一种方法是先到Pw2的位置复制L段加密标记并接上去,然后加密Pw2-Pw1这段内容并原位置传递下去。

       从以上分析可以看出,在文件尾加标记会导致加长写文件时软件要多执行一个动作,就是移动尾部加密标记的动作,如果完成第一个动作后由于掉电或其他原因未能完成第二个动作,那么文件就会被损坏。不论是加长写文件还是缩短写文件都需要把加密标记不断移动,可能在一个文档的一个保存操作中这种动作会执行几十上百次。
        当然计算机掉电本来就有可能造成文件的损坏,但使用文件头标记不会造成多余的动作,也就意味着使用文件头存放加密标记在文件损坏的概率与文件未加密时是相等的,没有扩大文件损坏的概率。

     

    5、文件加密逻辑,文件后缀

     文件的加密逻辑有2种方法

         1、加密指定后缀: 

        通过指定后缀加密是指保密程序对生成的某一类文档进行加密,而对其他后缀仍然采用明文。其优点是只加密制定类型的文档,而不影响其它文件,在加密范围上相对较小,系统的稳定性容易提高;缺点是可能产生“另存为其他类型的文档”的泄密漏洞,因为此时存储的结果并不是被指定加密的文件类型。即使把程序可能产生的后缀格式都指定也没有用,因为有很多办法另存出来 ,例如在Word中可以点击另存为然后在文件名栏输入2个双引号("),然后在这2个双引号之间输入任意后缀(例如test.123),那么保存后的文件就是明文的,拷贝出来文件名改回doc后缀就可能导致文档泄密。
         而且有些程序的文件格式没有定式,甚至可以保存为任意后缀,例如记事本,这样加密指定的文件后缀就带来了安全漏洞。

         2、加密不区分后缀: 

        加密不区分后缀是指保密程序对生成的所有文件都进行加密。这种加密方式由于对指定进程产生的任何文件都加密从而堵住“另存为其他类型的文档”的漏洞,可保证不论用户如何将文件另存都不会出现明文文件。其工作原理为指定进程只要发生写操作就加密被写的文件,任何中间文件和临时文件都会被加密。不区分文件后缀有更高的安全性,技术难度也大得多。

        加密不区分后缀的透明加密产品开发的层面有两个:应用层和驱动层,应用层基本上采用重定向原理+加密指定后缀;驱动层可能为2×2的组合即4种模式,如下表所示:

     

    加密指定后缀

    加密不区分后缀

    重定向原理

    重定向原理+加密指定后缀(1)

    重定向原理+加密不区分后缀(2)

    动态加解密原理

    动态加解密原理+加密指定后缀(3)

    动态加解密原理+加密不区分后缀(4)

      上表中模式2技术实现上很困难,所以实际上驱动层加密一般采用模式(1)-模式(3)-模式(4)。
         还可能将加解密操作在应用层和驱动层中混合完成,在驱动层拦截文件打开然后传递给应用层加解密,这种方法和纯应用层开发是一样只能采用模式(1)。



    二、文档加密流程讲解

    1、基本知识讲解

    基本流程
    1、读流程


    2、写流程

    需要判断的的IRP标识介绍:

     

    1、IRP_MN_MDL

    IoStatus.Information field字段表明有写入MDL的字节数

    主要是调用者需要fsd够着写入文件的MDL,fsd来分配和构造MDL

    2、IRP_MN_MDL_COMPLETE

    表示调用者已经处理完fsd创建的mdl,由mdl来清除和释放mdl

    3、IRP_MN_DPC

    表示调用者的上下文环境是DPC,fsd必须返回STATUS_PENDING,并且在工作线程中完成此历程

     

     

     

     

    2、主要数据结构


    FileObject ,打开一个文件, io 管理器为其创建一个文件对象结构
    FCB ,一个文件可能被多个程序同时打开,这样会生成多个 FileObject ,但是只存在一个 FCB
    段对象指针

      

    FILE_CONTEXT

     

     

    2、加解密算法

    RC4流加密

    密钥为静态密钥

    3、读写流程

    读过滤条件

    A、过滤标志g_bStartFilter是否启动

    B、判断pFileObj->FsContext是否存在

    C、IrpSp->MinorFunction判断是否为 IRP_MN_COMPLETE_MDL

    D、是否为目录操作

     

    获取读文件的读取的长度,起始位置,读取内容:

     

    文件的长度

    Length= IrpSp->Parameters.Read.Length;

    文件的偏移量:

    Offser.QuadPart= IrpSp->Parameters.Read.ByteOffset.QuadPart

    文件内容:

    Irp-> MdlAddress不为空,则使用Irp-> MdlAddress,缓冲区位置为MmGetSystemAddressForMdlSafe(Irp-> MdlAddres),否则直接使用Irp-> UserBuffer

     

    #define CdMapUserBuffer(IC, UB) {                                              \

               *(UB) = (PVOID) ( ((IC)->MdlAddress == NULL) ?                 \

                        (IC)->UserBuffer :                                     \

                       (MmGetSystemAddressForMdlSafe( (IC)->MdlAddress,HighPagePriority)));   \

    }  

     

    写过滤条件

    E、过滤标志g_bStartFilter是否启动

    F、判断pFileObj->FsContext是否存在

    G、IrpSp->MinorFunction判断是否为IRP_MN_MDL

    H、是否为目录操作

      

    文件的长度

    Length= IrpSp->Parameters.Write.Length

    文件的偏移量:

    LARGE_INTEGERlnOffset=IrpSp->Parameters.Write.ByteOffset;

    文件内容:

    Irp-> MdlAddress不为空,则使用Irp-> MdlAddress,缓冲区位置为MmGetSystemAddressForMdlSafe(Irp-> MdlAddres),否则直接使用Irp-> UserBuffer

     

    #define CdMapUserBuffer(IC, UB) {                                              \

               *(UB) = (PVOID) ( ((IC)->MdlAddress == NULL) ?                 \

                        (IC)->UserBuffer :                                     \

                        (MmGetSystemAddressForMdlSafe((IC)->MdlAddress, HighPagePriority)));   


    缓存管理

    单缓存
    1、 合法进程打开存在文件,关闭文档,明文保存在缓存,此时缓存没有刷

      至硬盘,也没有清空内存中的资源。此时非法进程再打开文档,在

      IRP_MJ_CREATE例程会刷新缓存操作,所以非法进程打开为乱码

    2、 合法进程打开存在文件,明文保存在缓存,此时缓存没有刷至硬盘,也

      没有清空内存中的资源。此时非法进程再打开文档,如果是word这种占着句

      柄没有关闭的文档,判断为非法进程,禁止打开;如果是notedpad采用内存

      映射文件的方式的,句柄关闭,则非法进程打开正在被合法进程打开的文档,在IRP_MJ_CREATE例程会刷新缓存操作,所以非法进程打开为乱码

    3、 非法进程打开未打开过的加密文档,密文。合法进程再打开加密文档,会先刷新缓存。
    4、 合法进程打开加密文档,在关闭的时候在 IRP_MJ_CLEANUP 例程中对新  

      建的文件才刷新缓存

    获取缓存资源的顺序:
        文件系统资源最先获得
       缓存管理器资源次之获得
       VMM 资源最后获得



    附:
    参考资料
    ¢ 《File System Internals》
    ¢ 《Windows  文件系统过滤驱动开发教程 》---- 楚狂人
    ¢ 寒江独钓 -----windows 内核安全编程
    ¢ OSR DOC

    展开全文
  • 基于文件过滤驱动和事件触发的网页防篡改机制
  • 文件系统过滤驱动基础知识

    千次阅读 2018-06-02 17:30:31
    文件系统过滤驱动基础知识一、何谓文件系统过滤驱动? 文件系统过滤驱动是一种可选的,为文件系统提供具有附加值功能的驱动程序。文件系统过滤驱动是一种核心模式组件,它作为Windows NT执行体的一部分运行。 文件...

    文件系统过滤驱动基础知识
    一、何谓文件系统过滤驱动?
          文件系统过滤驱动是一种可选的,为文件系统提供具有附加值功能的驱动程序。文件系统过滤驱动是一种核心模式组件,它作为 Windows NT 执行体的一部分运行。
          文件系统过滤驱动可以过滤一个或多个文件系统或文件系统卷的 I/O 操作。按不同的种类划分,文件系统过滤驱动可以分成日志记录、系统监测、数据修改或事件预防几类。通常,以文件系统过滤驱动为核心的应用程序有防毒软件、加密程序、分级存储管理系统等。
    二、文件系统过滤驱动并不是设备驱动
          设备驱动是用来控制特定硬件 I/O 设备的软件组件。例如: DVD 存储设备驱动是一个 DVD 驱动。
         
    相反,文件系统过滤驱动与一个或多个文件系统协同工作来处理文件 I/O 操作。这些操作包括:创建、打开、关闭、枚举文件和目录;获取和设置文件、目录、卷 的相关信息;向文件中读取或写入数据。另外,文件系统过滤驱动必须支持文件系统特定的功能,例如缓存、锁定、稀疏文件、磁盘配额、压缩、安全、可恢复性、 还原点和卷装载等。
         
    下面两部分详细的阐述了文件系统过滤驱动和设备驱动之间的相似点与不同点。
    1 、文件系统过滤驱动同设备驱动的相似点:
    下列部分描述了 Windows 操作系统中文件系统过滤驱动和设备驱动之间的相似点:
    1 )、类似的结构
         
    类似于设备驱动,文件系统过滤驱动有着属于自己的 DriverEntry Dispatch I/O 组件例程。文件系统过滤驱动同设备驱动一样调用许多相同的系统核心例程,它们都会过滤发送给它们所关联的设备的 I/O 请求

    2 )、类似的功能:
         
    文件系统过滤驱动和设备驱动都是 I/O 子系统的组成部分,因此它们都接收和作用于 I/O 请求包( IRP )。
         
    类似于设备驱动,文件系统过滤驱动同样可以创建它们自己的 IRP 并将该 IRP 发送到低层驱动。
         
    这两种驱动均可以通过注册回调函数来接收多种系统事件的通知。

    3 )、其它类似点:
         
    同设备驱动类似,文件系统过滤驱动可以接收传入的 I/O 控制码( IOCTLs )。而且,文件系统过滤驱动还可以接收和定义文件系统控制码( FSCTLs
         
    同设备驱动类似,文件系统过滤驱动可以被配置为在系统引导过程中加载或者在系统启动过程完成后加载。
    2 、文件系统过滤驱动同设备驱动之间的不同点:
         
    下例部分描述了文件系统过滤驱动同设备驱动之间的不同点:
         
    1 )、无需电源管理
         
    由于文件系统过滤驱动并不是真正的设备驱动,而且它们不需要直接控制硬件设备,因此它们并不接收 IRP_MJ_POWER 请求。(电源管理 IRP 将直接发 送到存储设备堆栈中。但是,在非常罕见的情况下,文件系统过滤驱动有可能会影响到电源管理。)由此,文件系统过滤驱动并不注册 IRP_MJ_POWER 关例程,它们也不会调用 PoXxx 例程。
         
    2 )、非 WDM
         
    文件系统过滤驱动并不是 WDM 驱动程序, WDM 驱动模型仅适用于设备驱动。

         
    3 )、没有 AddDevice StartIo 例程
         
    由于文件系统过滤驱动并不是设备驱动,而且它们并不直接控制硬件设备,因此它们没有 AddDevice StartIo 例程。

         
    4 )、创建不同的设备对象
         
    虽然文件系统过滤驱动和设备驱动均需要创建设备对象,但是它们所创建的设备对象的种类和数量都是不同的。
         
    设备驱动创建物理和功能设备对象来描述设备。即插即用( PnP )管理器将构建一个设备树来存放所有由设备驱动所创建的设备对象。文件系统过滤驱动所创建的设备对象,并不包含在这个设备树中。
         
    文件系统过滤驱动并不创建物理或功能设备对象,它们创建控制设备对象和过滤设备对象。控制设备对象对系统和用户模式应用程序提供过滤驱动的描绘。过滤设备对象执行对指定文件系统或卷的实际过滤工作。文件系统过滤驱动通常创建一个控制设备对象和多个过滤设备对象。

         
    5 )、其它不同点:
         
    由于文件系统过滤驱动并不是设备驱动,因此他们将不会执行直接内存访问 DMA )。
         
    与设备过滤驱动不同,设备过滤驱动可以附加到目标设备功能驱动的上层和下层,文件系统过滤驱动仅能附加到目标文件系统驱动的上层。因此在设备驱动队列中,文件系统仅能进行上层过滤而无法进行下层过滤。
    三、安装文件系统过滤驱动
        对于Windows XP和后续操作系统来说,可以通过INI文件或安装应用程序来安装文件系统过滤驱动(对于Windows 2000和更早的操作系统,过滤驱动通常通过服务控制管理器Service Control Manager来进行安装)。
    四、初始化文件系统过滤驱动
    与设备驱动类似,文件系统过滤驱动也使用 DriverEntry 例程进行初始化工作。在驱动程序加载后,加载驱动相同的组件将通过调用驱动程序的  DriverEntry 例程来对驱动程序进行初始化工作。对于文件系统过滤驱动来说,加载和初始化过滤驱动的系统组件为 I/O 管理器。
        DriverEntry
    例程运行于系统线程上下文中,其 IRQL = PASSIVE_LEVEL 。本例程可分页,详细信息参见 MmLockPagableCodeSection
        DriverEntry
    例程定义如下:
    NTSTATUS
    DriverEntry (
        IN PDRIVER_OBJECT DriverObject,
        IN PUNICODE_STRING RegistryPath
    )
    本例程有两个输入参数。第一个参数, DriverObject 为系统在文件系统过滤驱动加载时所创建的驱动对象;第二个参数, RegistryPath 为包含驱动程序注册键路径的 Unicode 字符串。
        
    文件系统过滤驱动按如下顺序执行 DriverEntry 例程:

         01
    、创建控制设备对象:

        
    文件系统过滤驱动的 DriverEntry 例程通常以创建控制设备对象作为该例程的起始。创建控制设备对象的目的在于允许应用程序即使在过滤驱动加载到文件系统或卷设备对象之前也能够直接与过滤驱动进行通信。
      注意: 文件系统也会创建控制设备对象。当文件系统过滤驱动将其自身附加到文件系统之上时(而不是附加到某一特定文件系统卷),过滤驱动同样将其自身附加到文件系统的控制设备对象之上。

        
    FileSpy 驱动范例中,控制设备对象按如下方式创建:

    RtlInitUnicodeString(&nameString, FILESPY_FULLDEVICE_NAME);
    status = IoCreateDevice(
        DriverObject,                                                //DriverObject
        0,                                                           //DeviceExtensionSize
        &nameString,                                                 //DeviceName
        FILE_DEVICE_DISK_FILE_SYSTEM,                                //DeviceType
        FILE_DEVICE_SECURE_OPEN,                                     //DeviceCharacteristics
        FALSE,                                                       //Exclusive
        &gControlDeviceObject);                                      //DeviceObject
     
    RtlInitUnicodeString(&linkString, FILESPY_DOSDEVICE_NAME);
    status = IoCreateSymbolicLink(&linkString, &nameString);

        
    与文件系统不同,文件系统过滤驱动并不是一定要为其控制设备对象命名。如果传递给 DeviceName 参数一个非空 Non-NULL 值, 该值将作为控制设备对象的名称。接下来,在前面的代码范例中 DriverEntry 可以调用 IoCreateSymbolicLink 例程来将该对象的核 心模式名称与应用程序可见的用户模式名称关联到一起(同样可以通过调用 IoRegisterDeviceInterface 来使设备对象对应用程序可 见)。
        
    注意: 由于控制设备对象是唯一不会附加到设备堆栈中的设备对象,因此控制设备对象是唯一的可安全命名的设备对象。由此,是否为文件系统过滤驱动的控制设备对象是否命名是可选的。
        
    注意: 文件系统的控制设备对象必须命名。过滤设备对象从不命名。
        
    参数 DeviceType 代表某种设备类型,其可能的取值均以常量形式定义在 ntifs.h 中,例如:  FILE_DEVICE_DISK_FILE_SYSTEM
        
    如果向 DeviceName 传递了一个非空值( Non-NULL ), DeviceCharacteristics 标识必须包括  FILE_DEVICE_SECURE_OPEN 。该标识指示 I/O 管理器对所有发送到控制设备对象的 Open 请求进行安全检测。
        
    文件系统过滤驱动在分派例程中识别其自身控制设备对象的有效方式为将设备指针与前期存储的全局控制设备对象指针进行比较。因此 FileSpy 驱动范例将  IoCreateDevice 所返回的设备对象指针存储到了全局变量 gControlDeviceObject 中。

         02
    、注册 IRP 分派例程:

        
    过滤驱动 DriverEntry 例程中的 DriverObject 参数提供了一个指向过滤驱动的驱动对象的指针。为了注册 I/O 请求包( IRP )的分派例 程,必须为主功能码注册分派例程的入口点。例如: FileSpy 驱动范例按下列方式设置分派例程入口点:

    for  (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
    {
        DriverObject->MajorFunction[i] = SpyDispatch;
    }
    DriverObject->MajorFunction[IRP_MJ_CREATE] = SpyCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = SpyClose;
    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = SpyFsControl;

        
    注意:在上面的 For 循环为每个 IRP 主功能码分派例程都分派了默认的分派例程。这是一个比较好的做法,因为,默认情况下, I/O 管理器完成未知 IRP 返回 STATUS_INVALID_DEVICE_REQUEST 。文件系统过滤驱动在这种方式下不会拒绝未知的 IRP ,这些请求将发送给低层驱动。由于 这个原因,默认分派例程仅向下层传递 IRP

         03
    、注册 Fast I/O 分派例程:

        
    过滤驱动 DriverEntry 例程的 DriverObject 参数提供了指向过滤驱动驱动对象的指针。
        
    为了注册文件系统过滤驱动的 Fast I/O 分派例程,必须分配并初始化 Fast I/O 分派表,向该表中存储 Fast I/O 分派例程,然后将该分派表的地址存储到驱动对象的 FastIoDispatch 成员中。
        
    例如: FileSpy 驱动范例按下述方式为 Fast I/O 分派例程设置入口点:
     
    RtlZeroMemory(fastIoDispatch, sizeof(FAST_IO_DISPATCH));
    fastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
    fastIoDispatch->FastIoCheckIfPossible = SpyFastIoCheckIfPossible;
    fastIoDispatch->FastIoRead = SpyFastIoRead;
    fastIoDispatch->FastIoWrite = SpyFastIoWrite;
    fastIoDispatch->FastIoQueryBasicInfo = SpyFastIoQueryBasicInfo;
    fastIoDispatch->FastIoQueryStandardInfo = SpyFastIoQueryStandardInfo;
    fastIoDispatch->FastIoLock = SpyFastIoLock;
    fastIoDispatch->FastIoUnlockSingle = SpyFastIoUnlockSingle;
    fastIoDispatch->FastIoUnlockAll = SpyFastIoUnlockAll;
    fastIoDispatch->FastIoUnlockAllByKey = SpyFastIoUnlockAllByKey;
    fastIoDispatch->FastIoDeviceControl = SpyFastIoDeviceControl;
    fastIoDispatch->FastIoDetachDevice = SpyFastIoDetachDevice;
    fastIoDispatch->FastIoQueryNetworkOpenInfo = SpyFastIoQueryNetworkOpenInfo;
    fastIoDispatch->MdlRead = SpyFastIoMdlRead;
    fastIoDispatch->MdlReadComplete = SpyFastIoMdlReadComplete;
    fastIoDispatch->PrepareMdlWrite = SpyFastIoPrepareMdlWrite;
    fastIoDispatch->MdlWriteComplete = SpyFastIoMdlWriteComplete;
    fastIoDispatch->FastIoReadCompressed = SpyFastIoReadCompressed;
    fastIoDispatch->FastIoWriteCompressed = SpyFastIoWriteCompressed;
    fastIoDispatch->MdlReadCompleteCompressed = SpyFastIoMdlReadCompleteCompressed;
    fastIoDispatch->MdlWriteCompleteCompressed = SpyFastIoMdlWriteCompleteCompressed;
    fastIoDispatch->FastIoQueryOpen = SpyFastIoQueryOpen;
     
    DriverObject->FastIoDispatch = fastIoDispatch;

         04
    、注册 FsFilter 回调例程:

        FsFilter
    通知回调例程在下层文件系统执行某些操作之前或之后调用。如果需要获取更多有关于 FsFilter 回调例程相关信息,可参见 FsRtlRegisterFileSystemFilterCallbacks 例程  
        
    为了注册 FsFilter 的通知回调例程必须分配并初始化 FS_FILTER_CALLBACKS 结构体,然后向该结构体中促出 FsFilter 回调例 程,并将存储有 Callbacks parameter FsRtlRegisterFileSystemFilterCallbacks 中。
        
    例如: FileSpy 驱动范例按如下方式注册 FsFilter 回调。
     
    fsFilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS);
    fsFilterCallbacks.PreAcquireForSectionSynchronization = SpyPreFsFilterOperation;
    fsFilterCallbacks.PostAcquireForSectionSynchronization = SpyPostFsFilterOperation;
    fsFilterCallbacks.PreReleaseForSectionSynchronization = SpyPreFsFilterOperation;
    fsFilterCallbacks.PostReleaseForSectionSynchronization = SpyPostFsFilterOperation;
    fsFilterCallbacks.PreAcquireForCcFlush = SpyPreFsFilterOperation;
    fsFilterCallbacks.PostAcquireForCcFlush = SpyPostFsFilterOperation;
    fsFilterCallbacks.PreReleaseForCcFlush = SpyPreFsFilterOperation;
    fsFilterCallbacks.PostReleaseForCcFlush = SpyPostFsFilterOperation;
    fsFilterCallbacks.PreAcquireForModifiedPageWriter = SpyPreFsFilterOperation;
    fsFilterCallbacks.PostAcquireForModifiedPageWriter = SpyPostFsFilterOperation;
    fsFilterCallbacks.PreReleaseForModifiedPageWriter = SpyPreFsFilterOperation;
    fsFilterCallbacks.PostReleaseForModifiedPageWriter = SpyPostFsFilterOperation;
     
    status = FsRtlRegisterFileSystemFilterCallbacks(DriverObject, &fsFilterCallbacks);

        05
    、执行其它必要的初始化工作:

        
    在注册完 IRP Fast I/O 分派例程之后,文件系统过滤驱动的 DriverEntry 例程需要初始化其它该驱动所需的全局变量和数据结构。

        06
    、注册回调例程【可选】:

        
    过滤驱动可以通过调用 IoRegisterFsRegistrationChange 例程来注册用来侦听在文件系统调用  IoRegisterFileSystem IoUnregisterFileSystem 注册或卸载自身时所触发事件的回调例程。过滤驱动通过注册这个 回调函数来发觉新的文件系统加载事件,然后,过滤驱动将自身附加到这个新的文件系统之上。
        
    注意: 文件系统过滤驱动不可能调用 IoRegisterFileSystem IoUnregisterFileSystem 例程。这两个例程都是专为文件系统提供服务的。
        
    过滤驱动并不是在调用 IoRegisterFsRegistrationChange 时加载到卷之上,它必须在侦测到卷以后才能进行加载(例如,通过一个用户模式应用程序)。注意: 滤驱动使用该例程来获得在卷装在后立即附加到该卷之上的能力。使用该例程时,并不能保证过滤驱动将直接附加到卷设备对象之上。其余部分未翻译,如下:  But it does ensure that such a filter attaches before (and thus below) any filter that instead waits for a command from a user-mode application, because filters can attach only at the top of the current file system volume device stack.

        07
    、存储注册表路径字符串拷贝【可选】:

        
    注意: 本步骤是过滤驱动在执行 DriverEntry 例程之后,需要使用注册表路径时所必须的。
        
    其余部分未翻译,如下: Save a copy of the RegistryPath string that was passed as input to DriverEntry. This parameter points to a counted Unicode string that specifies a path to the driver's registry key,
    /Registry/Machine/System/CurrentControlSet/Services/DriverName, where
    DriverName is the name of the driver. If the RegistryPath string will be needed later, DriverEntry must save a copy of it, not just a pointer to it, because the pointer is no longer valid after the DriverEntry routine returns. 

        08
    、返回状态:

         文件系统过滤驱动的 DriverEntry 例程通常会返回 STATUS_SUCCESS 。然而,如果驱动初始化失败, DriverEntry 会向返回一个适当的状态值。
        
    如果 DriverEntry 例程返回了一个指示未成功的状态值,系统将卸载该驱动。因此, DriverEntry 例程必须在返回错误代码之前释放那些自己所分配的内存和所获取的诸如设备对象之类系统资源。
     
    五、附加过滤驱动到文件系统或卷之上
    文件系统过滤驱动将其自身附加到一个或多个已装载卷之上,并过滤发送给这些卷的 I/O 操作。下面将以 Windows Driver Kit  WDK )中的范例来说明通常会采用的两种方式:
    ·          文件系统过滤驱动可以附加到终 端用户指定需要过滤的卷,比如键入卷的驱动符。用户命令将传递给过滤驱动一个私有的 IRP_MJ_DEVICE_CONTROL 请求。 FileSpy 驱动 范例在全局变量 gFileSpyAttachMode 设置为 FILESPY_ATTACH_ON_DEMAND 时,采用这种方式(默认情况下,  gFileSpyAttachMode 将设置为 FILESPY_ATTACH_ALL_VOLUMES )。
    ·          文件系统过滤驱 动可以附加到一个或多个文件系统驱动之上,监听  IRP_MJ_FILE_SYSTEM_CONTROL IRP_MN_MOUNT_VOLUME 请求,并附加到文件系统所装载的卷之上。 SFilter  就驱动范例使用这种方式。 FileSpy 驱动范例在全局变量 gFileSpyAttachMode 被设置为  FILESPY_ATTACH_ALL_VOLUMES (默认值)采取这种方式。
          注意: 通常需要假定卷和文件系统驱动的关系为一对多,而不是一对一。这是由于某些高级存储功能,例如动态卷和卷装载点等所造成的。
        
    注意: 要将定文件系统会一直以同步方式处理 IRP_MN_MOUNT_VOLUME 请求。例如,辅助存储器可能异步的进行装载。因此,过滤驱动需要在 Mount Completion 例程中传递 PendingReturned 标识。如果需要获取更多信息,可查阅 DDK 在线文档的 “PendingReturned Flag” 部分。  
        
    文件系统过滤驱动可以附加并过滤文件系统卷。但是它们无法直接附加到诸如磁盘驱动或分区等存储设备之上,同样他们也无法附加到单独的目录或文件之上。
         
    如果需要获取更多信息,可参见下面章节:

        01
    、创建过滤设备对象

        
    调用 IoCreateDevice 例程来创建用来附加到卷或文件系统堆栈上的过滤设备对象,在 FileSpy 范例中,以下述方式进行该工作:

    status = IoCreateDevice(
        gFileSpyDriverObject,     //DriverObject
        sizeof(FILESPY_DEVICE_EXTENSION),     //DeviceExtensionSize
        NULL,           //DeviceName
        DeviceObject->DeviceType,     //DeviceType
        0,            //DeviceCharacteristics
        FALSE,          //Exclusive
        &newDeviceObject);        //DeviceObject


        
    在上面的代码片段中, DeviceObject 为指向过滤驱动所需要附加到的目标设备的设备对象,而 newDeviceObject 为指向过滤驱动自身的设备对象的指针。
        
    为了为过滤设备对象的设备扩展数据结构体分配存储空间,因此需要将 DeviceExtensionSize 参数设置为 sizeof (FILESPY_DEVICE_EXTENSION) 。新创建的过滤设备对象的设备扩展成员将设置为指向该数据结构的指针。文件系统过滤驱动通常为每个 过滤设备对象定义并分配设备扩展。设备扩展的数量和结构均由驱动指定。然而,在 MS Windows XP 以及后续操作系统之上,过滤驱动所定义的设备扩展结构 DEVICE_EXTENSION 至少需要包含下述成员: PDEVICE_OBJECT AttachedToDeviceObject
        
    在上面调用 IoCreateDevice 时,由于过滤设备对象并没有命名,因此将 DeviceName 参数设置为 NULL 。由于过滤设备对象需要附加到文件系统或卷设备堆栈之上,因此,为过滤设备对象分配一个名字将造成系统安全漏洞。
        DeviceType
    参数必须始终设置为过滤设备对象所附加到的目标(文件系统或过滤)设备对象。按照此方法传递设备类型是非常重要的,这是因为它将由 I/O Manager 使用,并传回给应用程序。
        
    注意: 文件系统和文件系统过滤驱动从来不会将 DeviceType 参数设置为 FILE_DEVICE_FILE_SYSTEM 。该值并不是一个有效参数值( FILE_DEVICE_FILE_SYSTEM 常量仅在定义 FSCTL 时使用)。
        DeviceType
    参数非常重要的其它原因是,许多过滤驱动仅仅附加到某些特定的文件系统之上。例如,一个特殊的过滤驱动将会附加到本地磁盘文件系统之 上,而并不附加到 CD-ROM 文件系统或远程文件系统之上。这些过滤驱动测试最文件系统或卷设备堆栈中最高层设备对象的 DeviceType 参数。在大多 数情况下,最高层设备对象为一个过滤设备对象。这就是为什么过滤驱动的 Device Type 参数需要同下层文件系统或卷设备对象的该参数一致的原因。


        02
    、将过滤设备对象附加到目标设备对象之上

        
    通过调用 IoAttachDeviceToDeviceStackSafe 来将过滤设备对象附加到目标文件系统或卷的过滤设备堆栈之中。

    devExt = filespyDeviceObject->DeviceExtension;
    status = IoAttachDeviceToDeviceStackSafe(
         filespyDeviceObject,       //SourceDevice
         DeviceObject,        //TargetDevice
         &devext->AttachedToDeviceObject);  //AttachedToDeviceObject


        
    注意: 在有其它过滤驱动已经附加到目标设备对象之上时, AttachedToDeviceObject 输出参数接收到的设备对象指针可以与 TargeDevice 不同。

         通过名称附加到文件系统之上
         每种文件系统需要创建一个或多个已命名控制设备对象。如果需要直接附加到文件系统之上,文件系统过滤驱动需要传递给  IoGetDeviceObjectPointer 传递该特定文件系统控制设备对象的名称来获取该设备对象的指针。下列代码范例显示了如何获取 RAW 文件 系统的两个控制设备对象中的一个的方法:

    RtlInitUnicodeString(&nameString, L"//Device//RawDisk");
    status = IoGetDeviceObjectPointer(
          &nameString,        //ObjectName
          FILE_READ_ATTRIBUTES,     //DesiredAccess
          &fileObject,        //FileObject
          &rawDeviceObject);      //DeviceObject
    if (NT_SUCCESS(status)) {
          ObDereferenceObject(fileObject);
    }

        
    如果调用 IoGetDeviceObjectPointer 成功,文件系统过滤驱动调用 IoAttachDeviceToDeviceStackSafe 方法来附加到前述方法返回的控制设备对象之上。

        
    注意:除了控制设备对象指针( rawDeviceObject )以外, IoGetDeviceObjectPointer 还会返回一个指向向用户模式应用表现该控制设备对象的文件对象的指针( fileObject )。在上述代码范例中,并不需要文件对象,因此通过调用 ObDereferenceObject 关闭了该文件对象。下面没有翻译: It is important to note that decrementing the reference count on the file object returned by IoGetDeviceObjectPointer causes the reference count on the device object to be decremented as well. Thus the fileObject and rawDeviceObject pointers should both be considered invalid after the above call to ObDereferenceObject, unless the reference count on the device object is incremented by an additional call to ObReferenceObject before ObDereferenceObject is called for the file object. 


        03
    、传递 DO_BUFFERED_IO DO_DIRECT_IO 标识

        
    在过滤设备对象成功的附加到文件系统或卷之上以后,下面没有翻译: always be sure to set or clear the DO_BUFFERED_IO and DO_DIRECT_IO flags as needed so that they match the values of the next-lower device object on the driver stack. (For more information about these flags, see Methods for Accessing Data Buffers.) In the FileSpy sample, this is done as follows: 

    if (FlagOn( DeviceObject->Flags, DO_BUFFERED_IO )) 
    {
        SetFlag( filespyDeviceObject->Flags, DO_BUFFERED_IO );
    }
    if (FlagOn( DeviceObject->Flags, DO_DIRECT_IO )) 
    {
        SetFlag( filespyDeviceObject->Flags, DO_DIRECT_IO );
    }


        
    在上述代码片段中, DeviceObject 为一个过滤设备对象附加到的设备对象的指针,  filespyDeviceObject 为指向过滤设备对象自身的指针。


        04
    、传递 FILE_DEVICE_SECURE_OPEN 标识

        
    在过滤设备对象成功附加到文件系统(并非卷)设备对象之上以后,下面没有翻译: always be sure to set the FILE_DEVICE_SECURE_OPEN flag on the filter device object as needed to so that it matches the value of the next-lower device object on the driver stack. (For more information about this flag, see Specifying Device Characteristics in the Kernel Architecture Design Guide and DEVICE_OBJECT in the Kernel Reference.) FileSpy 驱动范例中,实现方式如下:

    if (FlagOn( DeviceObject->Characteristics, FILE_DEVICE_SECURE_OPEN )) 
    {
        SetFlag( filespyDeviceObject->Characteristics, FILE_DEVICE_SECURE_OPEN );
    }


        
    在上述代码片段中, DeviceObject 为一个过滤设备对象附加到的设备对象的指针,  filespyDeviceObject 为指向过滤设备对象自身的指针。


        05
    、清除 DO_DEVICE_INITIALIZING 标记:

        
    在过滤设备对象附加到文件系统或卷之上以后,,需要确保清除过滤设备对象的 DO_DEVICE_INITIALIZING 标识。在 FileSpy 驱动范例中,以如下方式实现:

    ClearFlag(NewDeviceObject->Flags, DO_DEVICE_INITIALIZING);


        
    在过滤设备对象创建以后, IoCreateDevice 为设备对象设置 DO_DEVICE_INITIALIZING 标识。在过滤驱动成功进行附加以后,这个标识必须被清除掉。注意:如果本标识没有被清除,其它过滤驱动将无法再次附加到该过滤链中,因为,此时调用 IoAttachDeviceToDeviceStackSafe 将失败。

        
    注意: DriverEntry 例程中创建的设备对象,并不需要必须清除 DO_DEVICE_INITIALIZING 标识,这是因为这个工作将会由 I/O 管理器自动完成。然而,如果创建了其它设备对象,则需要进行该清除工作。
     
    展开全文
  • 一个很好的文件过滤驱动的实现,实现了aes透明加解密算法。
  • 基于文件过滤驱动的加密系统设计与实现 涉及过滤驱动技术的透明加密系统设计 毕业论文
  • 文件透明加解密方案,有需要的同学可以参考下
  •  1.1文件系统工作原理?  在NT内核的Windows系统中,它的I/O子系统是由I/O管理器、可扩展的一组驱动程序和其它一些执行体服务组成。I/O管理器定义了一套驱动程序的框架或者说模型,定义了如何进行处理各种I/O操作...
    基本结构和工作原理
    
        1.1文件系统工作原理?

        在NT内核的Windows系统中,它的I/O子系统是由I/O管理器、可扩展的一组驱动程序和其它一些执行体服务组成。I/O管理器定义了一套驱动程序的框架或者说模型,定义了如何进行处理各种I/O操作。整个I/O子系统是包驱动的,绝大多数的输入输出请求都是使用I/O请求包(I/O Request Packet, IRP)来传递的。IRP在I/O子系统的各个部件中间运动,把请求传递到合适的地方。

        在文件系统架构中,最底层的是文件系统驱动程序(FSD),在它上面有一系列的文件系统过滤驱动程序(File System Filter Driver),每当应用程序发起一个对于文件的操作时,通过一个陷阱指令(INT 2EH)将处理器模式提升到ring0,从而完成从用户态进入内核态。I/0管理器检查数据存取合法性之后,构造一个IRP_MJ_READ的I/0请求包(IRP),并送到文件系统驱动程序的入口点,文件系统等各层驱动程序传递并处理IRP,最后将结果通过I/0管理器返回用户进程。?
        值得注意的是,为了追求更好的性能,文件系统增加了FAST I/O例程,实现高速访问缓存数据的功能,也就是我们常说的Cache机制。不过只有在所需文件数据被缓存的情况下FAST I/O才会有效。当用户想访问某个文件时,I/O管理器首先调用FAST I/O例程。FAST I/O例程会返回一个布尔变量,告知是否能够进行FAST I/O处理。如果返回False,I/O管理器就不得不重新借助标准IRP的方式完成任务。如图1控制流程所示。

    1.2文件系统过滤驱动工作原理
    ?
        I/O管理器采用的是分层驱动程序模型,如图2所示。设备对象(FDO,FiDO)、驱动程序对象都是系统为便于分层管理而创建的数据结构。一个驱动程序可以根据需要创建多个设备对象。

        每个I/O请求,由I/O管理器出发,依次从相应的设备栈的顶部向下传递。每传递一层,系统就调用与当前设备对象关联的驱动程序例程来对请求进行处理。这分层的驱动程序模型,允许一个驱动程序构造一个匿名的设备对象,并把它附着在另一个设备对象上。I/O管理器在传递IRP到目标设备对象之前,如果有附着的匿名设备对象,它就把IRP首先传递给此匿名设备对象,经过对象的过滤设备驱动程序处理之后才发给真正的目标设备对象。而这个附着的匿名设备对象就是我们说的FiDO(过滤设备对象),与它关联的驱动程序就称为过滤驱动程序。因此,我们可以在文件系统设备对象的上面设置一个过滤驱动程序,这个过滤驱动程序可以首先获得I/O的IRP请求,从而对原始的请求进行预处理、修改和监控,最终达到我们想要的目的。

    2 USB移动存储设备安全访问技术
    ?
        当前对USB设备控制权限基本上是完全禁止或者完全禁用,防护粒度比较粗,缺少细化控制容易造成主机敏感信息的外流。而基于自定制的文件系统过滤驱动程序,自动挂接操作系统中的全部文件系统驱动程序,可以截获到所有的对文件的操作。在过滤驱动程序中,决定是否允许对USB文件的操作,判断依据就是IRP,其中包含了对所有的I/O请求的描述,从中判断是目标设备类型是否为FILE_REMOVABLE_MEDIA,如果不是则直接放行IRP到下层驱动进行处理;否则向应用程序发送请求,根据设定好的规则来决定是允许放行、禁止操作或者提示用户处理。这样可以实现对U盘的禁用、只读、允许等权限;结合对键盘鼠标以及执行程序的行为特征判断,还可以实现防轮渡木马窃取主机文件。其主要分派例程为:?
        SfCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp),在此函数中定义CheckRuleForFile来判断用户的操作是否符合设置的控制权限。具体流程如图3。

    3电子文档加解密技术?
        现有的电子文档保护方法主要有:一是文件加锁、解锁型;二是格式转换型。其主要缺点是需要手工进行转换,并且在文档创建、首次使用、打开后、外发或传输时不能做到全程保护,只要一个环节出了问题,就会有泄密的隐患。因此利用文件过滤驱动技术,全程加密保护敏感电子文档,包括查看、创建、打开以及修改等操作,可有效做到内核加解密、透明加解密和外发文档控制等功能,它既具有访问控制的方便性,又具有文件加密的安全性。它不但支持硬盘文件加密,也支持光盘、软盘、移动存储器的文件加密,与介质无关。?
        其技术实现也是在文件系统驱动中插入过滤驱动,通过截获文件系统对受保护文件的读写数据请求,对写入的数据进行加密存储,对用户合法读出的数据进行解密。加解密整个过程对用户是透明的,不影响用户正常操作习惯。其实现流程如下:

        加密算法可以采用AES、RC4、RC6等,并且密钥长度可选择。?
        以上的加密和解密操作只是完成电子文档保护的基本核心功能,做到受控文档在存储介质上都是密文存储;除此之外还要考虑使用特殊标识或水印对受控文档的识别,采用内核态HOOK技术对截屏、拷贝、拖曳、另存为、打印、内存转储等动作行为的监控;根据实际需要还可以实现离线解密、外带管理等辅助功能。
    ?
    4内核病毒防火墙技术?

        传统的静态文件扫描和杀毒通过用户层的请求加载数据,经过层层调用和用户态与核心态的切换,最终完成查杀,这样执行效率相对较低;而利用文件系统过滤驱动,由于其工作在内核态,可以直接对文件进行操作,降低了系统调用的层数,避免了状态的切换,因而有极高的效率,可以进行实时动态扫描。由于其能够发现并阻止其病毒爆发或扩散,因而称其为病毒防火墙。?
        下面介绍基于文件过滤驱动的病毒防火墙的工作机制,如图6。?
     
        应用程序利用CreateFile函数创建一个新文件或者打开一个已经存在的文件时,I/O管理器生成IRP并向下传递,我们的文件系统过滤驱动(病毒防火墙)截获该IRP请求,若是关心的文件类型,则经过进一步处理后能够保证使用的文件不存在病毒,存在病毒的文件不能被打开或使用。如果IRP的返回值表明打开文件时产生了错误,文件系统过滤驱动只是把结果返回给I/O管理器;否则病毒防火墙要接手并扫描整个文件,完成后才能继续以后的工作。?
    图6内核病毒防火墙工作机理
        为了提高效率,文件过滤驱动程序需要在系统内核中维护病毒特征代码库,其匹配算法可采用现有成熟的高效算法。采用文件过滤驱动程序实现了动态扫描病毒,能保证文件系统的安全运行。分析实时病毒防火墙实现原理有利于改进反病毒软件的执行效率与准确性。


    展开全文
  • 文件透明加密这点事儿,从2001年开始出现基于API HOOK的方式开始到现在,已经十几年了,有细心人按技术实现的方式将其细分为4代,分别是基于API HOOK的第一代技术、基于文件过滤驱动(加清缓存)的第二代技术、使用...
       
         文件透明加密这点事儿,从2001年开始出现基于API HOOK的方式开始到现在,已经十几年了,有细心人按技术实现的方式将其细分为4代,分别是基于API HOOK的第一代技术、基于文件过滤驱动(加清缓存)的第二代技术、使用Layerfsd的双缓冲第三代技术和基于微软新一代minifilter框架的Layerfsd双缓冲第四代技术。第一代和第二代的技术划分基本上没有异议,所谓的第四代很多人并不认同,认为使用minifilter框架算不上是技术突破,其技术实现仍然是基于Layerfsd的双缓冲技术,没有新意。
            我们从2009年开始研究并实现了基于Layerfsd的双缓冲技术,并应用于自己的产品中,这些本来都是老生长谈,只是最近几天根据用户反馈修改了几个BUG,忽然觉得还可以说道说道。Layerfsd的双缓冲技术最早出现在驱网论坛上的时候,讨论可谓是热烈,随着一些开发者逐步从理论到实践,完成了具体的实现之后,就开始了有意无意的技术封锁,一些技术理论和部分公开的源代码都无影无踪,不过从侧面也可以看出来,这个技术其实还是有一定的门槛的。其门槛并不在于技术有多难,关键在于细节和稳定性,根据理论做出一个实现不难,网上很多号称出售Layerfsd的双缓冲技术实现源代码的,叫价8-40万的都有,不过都只能算是一个理论研究系统,稳定性都很难保证,更不用说实用性了。
            为了了解同行的技术成熟度,我们经常找来同行的产品进行测试,今年上半年测试了两个驱动,一个驱动是对Visual Studio不兼容,每次保存文件后都会提示文件被外部修改,需要再确认一次,都是做这个的,我们当然清楚这个是layerfsd层的文件时间没有处理好,不过用VC编译一个加密的工程源代码时,总是蓝屏,这个应该就是实现者的技术实力问题了,还有对NTFS分区还马马虎虎,但是只要操作FAT分区的文件系统就没有反应,根据我们的经验应该是内部有死锁产生。还有一个驱动是不支持动态磁盘系统和可卸载的媒体(比如U盘),用WORD打开的文档,在编辑状态时居然可以从资源管理器中删除,这个是致命的layerfsd层文件权限管理失败,和作者沟通这个问题,作者认为这是双缓冲驱动实现的特征,只要是使用双缓冲技术实现的驱动都有这个问题,对此我们不敢苟同。
            这样的实现买回去也没办法用,想做出实用的商业软件至少还要2-3年的时间开发功能并做好稳定性。如果有钱,可以直接购买OSR的DMK,稳定性有一定的保证,但是要在上面做二次开发实现自己的功能。pfp也公开过一份源代码,是个半成品系统(现在驱网所有的下载链接都失效了),但是距离实现还有很远的距离,当然还是有很多人的实现都是基于这个源代码做的,这个一测试就能感觉出来。
            使用第二代技术实现的商业应用很多,只要能做稳定,基本都有市场,但是这个技术有几个致命的问题,就是文件操作效率低下,容易损坏文件,并且和反病毒软件不兼容。文件操作效率低下的原因在于为了防止非授信进程访问文件系统缓存的文件明文,每次打开和关闭文件时都要清理文件缓存。这对相当于屏蔽了系统文件缓存带来的性能优化,对大文件的操作影响尤其明显。我们测试过一个使用这种技术实现的商业软件,用word打开一个100多M的大文件后,用另一个非授信进程每隔15-30秒钟只读访问一次这个文件(这会促使驱动实现每隔15-30秒钟就清一次缓存),结果卡的基本上没办法操作这个word文档,如果是双缓冲,就没有这个问题。损坏文件的原因主要是对于延迟写入的缓冲文件,用户的写入操作是写入了缓存,但是负责延迟写入的system进程还没有将其写入文件,此时如果有非授信进程打开文件,会导致缓存被清除,这导致用户的修改没有写入,很多情况下都会造成文件数据丢失或文件格式损坏,与杀毒软件不兼容也基本上是这个原因。
            第二代技术的实现,在处理加密文件标识的问题上也很棘手,我们测试过的很多实现都是使用影子文件的方式,所谓影子文件,就是构造一个文件名与加密文件有一定的关联的影子文件,比如在原始文件名前增加一个固定标识的前缀,或后缀,或使用一个特殊的文件扩展名。当打开一个文件时,加密驱动首先看看是否存在影子文件,如果是就说明是一个加密文件,需要做解密处理。影子文件的管理也是一个很麻烦的地方,需要在驱动中对IRP_MJ_DIRECTORY_CONTROL进行过滤处理,对上层应用过滤掉这些文件名,使得用户在资源管理器中看不到这些影子文件,感觉不到他们的存在。但是只要用户停止驱动,这些文件就原型毕露,一些安全软件,比如冰刃,可以绕过驱动直接删除影子文件,会带来一些不稳定因素。此外,文件的复制和删除都要考虑影子文件,维护上也挺麻烦的。也有一些商业实现将影子文件集中在某个系统目录中进行管理,但是也要解决同名的问题,也不是完美的方案。
            从理论上所,使用双缓冲技术可以回避上面提到的清缓存问题,同时,双缓冲也可以解决文件加密标识的存放问题。双缓冲技术可以将加密信息构造成一个特殊的数据块直接存放在文件中,至于是放在文件头部还是文件尾部(从理论上说,也可以放在文件中间某个位置,不过是自找麻烦),不同意见还是很多的,各有各的理论依据,有人认为放在文件头部容易破坏文件,不过这是没有根据的,如果驱动实现不成熟,这块信息放在什么地方都可能破坏文件。倾向于将这块信息放在文件尾部的人觉得文件完成最后的写入,关闭之前补上一块加密信息是顺理成章的事情,倾向于将这块信息放在文件头部的人则是秉承传统的思想,毕竟很多文件格式都是将文件的特殊信息构造成一个特殊的文件头存放的,不过就实现而言,这二者没有优劣之分。
            双缓冲技术需要在一个layerfsd层访问真实文件,这就带来一个驱动的(IRP_MJ_CREATE)重入问题,这个解决不好就直接递归到栈溢出了。防止重入有多重方法,使用minifilter框架的有个优势,就是可以直接使用FltCreateFile系列函数绕开驱动直接打开和读写文件,这个后面再说。如果不使用minifilter框架,常用的两种方法就是构造影子卷进行文件访问,或直接构造IRP进行文件操作。构造影子卷的原理就是通过影子卷重定向文件的访问,因为过滤驱动不会attach影子卷,因此就规避了重入问题。使用影子卷的好处是可以使用ZwCreateFile等内核API直接操作文件,方便、安全。但是attach物理卷的时候要避开影子卷,一旦不小心attach了影子卷就会死的很惨。直接构造IRP进行文件操作应该是一个很优雅的方案,但是实现起来需要考虑比较多的细节,网上也有一些现成的源代码实现,不过或多或少都有一些问题,需要修改一下才能用。关于这方面的资料首先是OSR的“Rolling Your Own - Building IRPs to Perform I/O”一文,此外,还有baiyuanfan的“Windows平台内核级文件访问”一文也有很不错的介绍。
            minifilter是微软引入的一个轻量级微过滤驱动模型,简化了文件过滤驱动的实现细节,使得微过滤驱动可以忽略一些细枝末节的东西,将注意力集中在业务实现上。这比采用遗留驱动模型的sfilter框架有一定的优势,但是就透明加密驱动而言,并没有进步到说使用minifilter框架就比sfilter技术先进的程度,要知道,第二代透明加密技术的驱动也可以用minifilter框架实现,所以鼓吹minifilter+layerfsd更先进是没有依据的,重要的还是谁的驱动更稳定,毕竟动不动就蓝屏,或者损坏文件是用户最不能接受的。
            最后要说一些细节问题,比如双缓冲,所谓的双缓冲就是对同一个文件的访问形成两个cache缓存,对于授信进程,可以使用解密数据的明文cache,对于非授信进程,则使用密文的cache,二者共存且互相不干扰。使用双缓冲对系统内存的使用肯定是会增加的,但是带来的安全性和文件访问效率的提升是不言而喻的。至于cache的实现方式,可以使用windows的文件缓存系统,也可以自己实现文件缓存系统,据我所知,很多数据库软件就没有使用windows的文件缓存系统,而是根据需求自己实现的缓存系统。极端的说,你甚至可以不实现缓存,所有加密文件的读写都是实时操作实际文件,不支持一切缓存读写和fastio,我们在测试时遇到过这样的实现,也号称是支持layerfsd的双缓冲技术,虽然没有双缓冲的文件访问效率,但是也算是回避了第二代驱动技术的几个难题。还有比如授信进程的识别问题,简单地根据程序文件名称进行识别是非常幼稚的做法,对程序改个名字就可以欺骗加密驱动得到解密后的明文。还有授信进程的识别问题,对于有的应用程序,通常是一个图形的前端加上几个没有界面的后台程序配合工作,如果授信进程只有前端的UI进程,还是无法访问加密文件,对这种情况也要做进程父子关系的识别和处理。当然还有经典的线程注入问题,通过远程线程注入,可以在授信进程中启动一个线程访问加密文件,并将解密的明文通过共享内存或socket接口传递给另一个非授信进程。解决之道就是阻止线程注入,内核和应用层都可以做,当然也会对正常需要线程注入的程序产生影响,比如本人的TabSiPlus外挂插件,需要注入到Source Insight进程内部启动一个tab标签栏,就因为这个原因与加密软件产生冲突。对于一些支持插件的软件,比如office,还需要对插件进行识别和屏蔽,方法也很多,方式也很流氓,经常弄得用户莫名其妙。我的建议是对这种支持插件的软件不要做特殊处理,安全性由用户自己管理,用户有时候并不是那么傻,不要什么事情都替用户做了。
    展开全文
  • 针对当前信息安全的严峻形势,提出了基于Windows文件系统微过滤驱动文件透明加解密技术的解决方案。介绍了研究“基于Windows文件系统微过滤驱动文件透明加/解密技术”过程中必须掌握的一些理论基础,包括...
  • 基于过滤驱动技术的网络文件系统研究与实现,苏格林,路美娟,本文介绍了一种基于过滤驱动技术的网络文件系统的设计思路及原理。该系统利用文件系统过滤驱动技术,在文件系统驱动层之上插入过
  • 论述了过滤驱动技术出现的历史和最新出现的过滤驱动开发技术一 一过滤驱动管理器,指出今后开发过滤驱动程序的方向;对如何开发一个过滤 驱动程序进行了详细的分析,对开发过滤驱动的基本步骤做了仔细介绍,并结 合...
  • 透明底层文件过滤驱动加密技术.rar

    热门讨论 2010-03-18 09:56:22
    明加密技术是近年来针对企业文件保密需求应运而生的一种文件加密技术。应用透明加密技术,用户打开或编辑未加密的指定后缀文件时会自动加密;打开加密了的指定后缀文件时不需要输入密码会自动解密。
  • 我们的作业是在Windows下编写一个文件过滤驱动程序(作业1),该文件过滤驱动可以保护某一文件或者目录,驱动可以根据权限文件的权限记录来控制用户对被保护文件的读、写、删除操作。我们的计划是先在网上收集相关的...
  • 文件系统过滤驱动总结

    千次阅读 2016-04-13 18:35:30
    文件系统过滤驱动 . 1 文件系统过滤驱动工作原理 Windows NT内核操作系统的驱动模型采用分层结构,如图1所示。图中左边是一个设备对象栈,设备对象 是操作系统为帮助软件管理硬件而创建的数据结构。每个硬件...
  • 基于文件系统过滤驱动文件访问控制技术研究 基于IPA和过滤驱动文件控制系统的研究与实现 基于Windows微过滤器模型的_省略_明加密文件系统_UTEFS_研制 基于微过滤驱动模型的文档安全系统研究与实现 基于新一代...
  • 基于文件系统过滤驱动的内核Rootkit隐藏技术
  • 用于写论文时参考,主要是文件过滤驱动的研究,加密文件系统的研究
  • 应用 Linux 内核中的系统调用劫持技术和模块动态装载机制,研究与开发 Linux 下的文件过滤驱动。通过对文件标识的注入与识 别,采用blowfish 加密算法,设计和实现内核级的文件加/解密服务,并对软件的性能进行分析...
  • 基于文件过滤驱动的透明加解密

    千次阅读 2015-10-20 14:01:22
    文件过滤驱动 一、文件透明加解密 关键字:透明、文件过滤驱动、加密标识,缓存   文件过滤驱动最重要的两点是搞定加密标识和缓存管理 1、透明概念: 透明指的是用户在操作的时候,虽然后台在...
  • 文件系统Minifilter驱动(由WDK翻译而来)的技术详解文章,结构性强,通读下来,minifilter各要点内容了然于心了,必须看看
  • 过滤驱动 linux

    2012-07-15 23:21:37
    linux 过滤驱动 传入 设计与实现
  • 接上文。 如何实现 sfPassThrough 派遣函数,才能达到目录重定向呢。 我们首先要解决重定向的目的地,这里采用的是把... 这样我们的驱动中至少有两类设备,一类是文件过滤驱动设备,一类是控制设备, 如果驱动中还
  • 过滤驱动程序总结

    千次阅读 2016-04-13 18:52:16
    过滤驱动程序  过滤驱动程序可以修改已有驱动的功能,也可以对数据进行过滤加密。WDM驱动需要通过注册表记录 指定加裁的过滤驱动,OS会读取这些值完成加载,其可以是高层过滤,也可以是低层过滤。而NT...
  • 包含以下基本 More Effective+C++.pdf Effective+C++.pdf c++ primer plus 4th edition.chm ...多线程编程指南.pdf multiple thread.pdf Win32多线程编程.pdf ...Windows文件系统过滤驱动开发教程(第二版).pdf 免费送大家
  • 过滤驱动隐藏文件自己收藏的源码,特意贡献给大家
  • 基于文件系统过滤与进程空间的文件访问控制方法,苏格林,张悠慧,本文提出了一种基于文件系统过滤驱动技术文件访问控制方法,其可以实时监视/记录Windows系统下进程的派生关系,构成树形的进程空�
  • 摘要:在研究Windows NT 内核操作系统的驱动框架的基础上,基于Minifilter 过滤驱动技术以及文档标识技术,设计并实现了一个具有文件安全保护能力的终端文档安全保护系统。该系统既实现了对终端文档的透明标识及透明...
  • Windows 文件过滤驱动经验总结(转)

    千次阅读 2014-06-12 09:20:21
    1、获得文件全路径以及判断时机 除在所有 IRP_MJ_XXX 之前自己从头创建 IRP 发送到下层设备查询全路径外, 不要尝试在 IRP_MJ_CREATE 以外的地方获得全路径,因为只有在 IRP_MJ_CREATE 中才会使用 ...
  • 基于文件系统过滤驱动的安全增强型加密系统技术研究 ---论文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 54,862
精华内容 21,944
关键字:

文件过滤驱动技术