文件过滤驱动及应用
① 文件过滤驱动和磁盘过滤驱动有什么区别
神马狗屁老师教的啊
② 如何设计单机版的文件过滤驱动
透明指的是用户在操作的时候,虽然后台在自动的进行加解密,但是用户根本就不知道加密内的存在,就像中间容隔了一层透明的玻璃一样。透明的好处在于不改变用户的操作,一切都和加密之前一样,甚至在有些企业安装加密后都无需通知所有的员工,就像加密并不存在一样,只是加密文件到了企业安全环境的外部才会发现文件无法打开。透明的程度也是加密软件一个很重要的方面,例如:正在编辑一个Word文件时,能否拷贝或者使用其他程序来读取这个文件,如果不能那么这里就不够透明,在一些PDM的文档管理软件中就是文件在一个应用程序打开状态时另一个应用程序进行检入。透明的程度越高,用户使用时就越是和未加密时一样,透明程序越低用户就会发现有越多的操作受到限制,和加密前有较大的差异。
③ 怎么用代码实现WDM文件过滤驱动安装
为了让这个驱动被系统加载,必须创建一个inf文件。由于是使用现成的例子,因此这一步也可以省下来。直接右键点击例子中的inf文件,在弹出的菜单中选择“安装”即可。
这里要注意的是,inf中的StartType参数,它可以控制驱动被加载的方式:
SERVICE_AUTO_START (2) 安全模式下不会自动加载 SERVICE_BOOT_START (0) 在系统安全模式下启动时 驱动也会自动加载
SERVICE_DEMAND_START(3) 则驱动不会自动加载
因为是测试,我使用SERVICE_DEMAND_START,即由手动加载驱动。例子是miniFilter驱动,因此可以在命令提示行中用“fltmc load 驱动名称”来加载,相应的卸载是“fltmc unload”。如果是其它驱动,则用"net start 驱动名称"来加载,相应的卸载是"net stop 驱动名称"。注意驱动名称不是文件名,而是inf中[Settings]的ServiceName值。驱动要发布时,也可以通过CreateService & StartService API来动态安装。
Inf文件的写法,可以参考例子,或者拿现成的改一改。下面的是摘自驱动开发网的
XiangXiangRen整理的Inf文件,改起来比较方便,谢谢XiangXiangRen
④ windows10文件驱动过滤
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 类型的文件做同样处理。
4、获得本地/远程访问用户名(域名/SID)
方法只有在 IRP_MJ_CREATE 中才可用,那是因为 IO_SECURITY_CONTEXT 只有在 IO_STACK_LOCATION->Parameters.Create.SecurityContext 才会有效。这样你才有可能从 IO_SECURITY_CONTEXT->SecurityContext->AccessState->SubjectSecurityContext.XXXToken 中获得访问 TOKEN,从而进一步得到用户名或 SID。记得 IFS 中有一个库,它的 LIB 导出一个函数可以让你在获得以上信息后得到用户名与域名。但如果你想兼容 NT4 的话,只能自己分析来得出本地和远程的 SID。
5、文件与目录的判断
正确的方法在楚狂人的文档里已经说过了,再补充一句。如果你的文件过滤驱动要兼容所有文件系统,那么不要十分相信从 FileObject->FsContext 里取得的数据。正确的方法还是在你传递下去 IRP_MJ_CREATE 后从最下层文件系统延设备栈返回到你这里后再获得。
6、加/解密中判断点
只判断 IRP_PAGING_IO,IRP_SYNCHRONOUS_PAGING_IO,IRP_NOCACHE 是没错的。如果有问题,相信是自己的问题。关于有人提到在 FILE_OBJECT->Flags中的 FO_NO_INTERMEDIATE_BUFFERING 是否需要判断,对此问题的回答是只要你判断了 IRP_NOCACHE 就不用再判断 FILE_OBJECT 中的,因为它最终会设置 IRP->Flags 为 IRP_NOCACHE。关于你看到的诸如 IRP_DEFER_IO_COMPLETION 等 IRP 不要去管它,因为它只是一个过程。最终读写还是如上所介绍。至于以上这些 IRP 哪个是由 CC MGR 发送的,哪些是由 I/O MGR 发送和在什么时候发送的,这个已经有很多讨论了,相信可以找到。
7、举例说明关于 IRP 传递与完成注意事项
只看 Walter Oney 的那本 《Programming the Microsoft Windows driver model》里介绍的流程,自己没有实际的体会还是不够的,那里只介绍了基础概念,让自己有了知识。知道如何用,在什么情况下用,用哪种方法,能够用的稳定这叫有了技术。我们从另一个角度出发,把问题分为两段来看,这样利于总结。一个 IRP 在过滤驱动中,把它分为需要安装 CompleteRoutine 的与无需安装 CompleteRoutine 的。那么在不需要安装 CompleteRoutine 的有以下几类情况。
(1) 拿到这个 IRP 后什么都不做,直接调用 IoCompleteRequest() 来返回。
(2) 拿到这个 IRP 后什么都不做,直接传递到底层设备,使用IoSkipCurrentIrpStackLocation() 后调用 IoCallDriver() 传递。
(3) 使用 IoBuildSynchronousFsdRequest() 或 IoBuildDeviceIoControlRequest()来建立 IRP 的。
以上几种根据需要直接使用即可,除了一些参数与标志需要注意外,没有什么系统机制相关的东西需要注意了。那么再来看需要安装 CompleteRoutine 的情况。我们把这种情况再细分为两种,一是在 CompleteRoutine 中返回标志为STATUS_MORE_PROCESSING_REQUIRED 的情况。二是返回处这个外的标志,需要使用函数IoMarkIrpPending() 的情况。在 CompleteRoutine 中绝大多数就这么两种情况,你需要使用其中的一种情况。那么为什么需要安装 CompleteRoutine 呢?那是因为我们对其 IRP 从上层驱动,经过我们驱动,在经过底层设备栈返回到我们这一层驱动时需要得到其中内容作为参考依据的,还有对其中内容需要进行修改的。再有一种情况是没有经过上层驱动,而 IRP 的产生是在我们驱动直接下发到底层驱动,而经过设备栈后返回到我们这一层,且我们不在希望它继续向上返回的,因为这个 IRP 本身就不是从上层来的。综上所述,先来看下 IoMarkIrpPending() 的情况。
(1) 在 CompleteRoutine 中判断 Irp->PendingReturned 并使用 IoMarkIrpPending()然后返回。这种方法在没有使用 KeSetEvent() 的情况下,且不是自建 IRP 发送到底层驱动返回时使用。也就是说有可能我所做的工作都是在 CompleteRoutine 中进行的。比如加/解密时,我在这里对下层驱动返回数据的判断并修改。修改后因为没有使用 STATUS_MORE_PROCESSING_REQUIRED 标志,它会延设备堆一直向上返回并到用户得到数据为止。这里一定要注意,在这种情况下 CompleteRoutine返回后,不要在碰这个 IRP。也就是说如果这个时候你使用了 IoCompleteRequest()的话会出现一个 MULTIPLE_IRP_COMPLIETE_REQUEST 的 BSOD 错误。
(2) 在 CompleteRoutine 中直接返回 STATUS_MORE_PROCESSING_REQUIRED 标志。这种情况在使用了 KeSetEvent() 的函数下出现。这里又有两个小小的分之。
1) 出现于上层发送到我这里,当我这里使用 IoCallDriver() 后,底层返回数据经过我这一层时,我想让它暂时停止继续向上传递,让这个 IRP 稍微歇息一会,等我对这个 IRP 返回的数据操作完成后(一般是没有在 CompleteRoutine中对返回数据进行操作情况下,也就是说等到完成例程返回后再进行操作),由我来调用 IoCompleteRequest() 让它延着设备栈继续返回。这里要注意,我们是想让它返回的,所以调用了 IoCompleteRequest()。这个可不同于下面所讲的自己从头分配 IRP 时在 CompleteRoutine 中已经调用 IoFreeIrp() 释放了当前IRP 的情况。比如我在做一个改变文件大小,向文件头写入加密标志的驱动时,在上层发来了 IRP_MJ_QUERY_INFORMATION 查询文件,我想在这个时候获得文件信息进行判断,然后根据我的判断结果再移动文件指针。注意:上面是两步,第一步是先获得文件大小,那么在这个时候我就需要用到上述办法,先让这个 IRP传递下去,得到我想要的东西后在进行对比。等待适当时机完成这个 IRP,让数据继续传递,直到用户收到为止。第二步我会结合下面小节来讲。
2) 出现于自己从头建立 IRP,当使用 IoAllocate() 或 IoBuildAsynchronousFsdRequest()创建 IRP 调用 IoCallDriver() 后,底层返回数据到我这一层时,我不想让这个 IRP 继续向上延设备栈传递。因为这个 IRP 就是在我这层次建立的,上层本就不知道有这么一个 IRP。那么到这里我就要在 CompleteRoutine 中使用 IoFreeIrp()来释放掉这个 IRP,并不让它继续传递。这里一定要注意,在 CompleteRoutine函数返回后,这个 IRP 已经释放了,如果这个时候在有任何关于这个 IRP 的操作那么后果是灾难性的,必定导致 BSOD 错误。前面 1) 小节给出的例子只完成了第一步这里继续讲第二步,第一步我重用这个 IRP 得到了文件大小,那么这个时候虽然知道大小,但我还是无法知道这个文件是否被我加过密。这时,我就需要在这里自己从头建立一个 IRP_MJ_READ 的 IRP 来读取文件来判断是否我加密过了的文件,如果是,则要减少相应的大小,然后继续返回。注意:这里的返回是指让第一步的IRP 返回。而不是我们自己创建的。我们创建的都已经在CompleteRoutine 中销毁了。
8、关于完成 IRP 的动作简介
当一个底层驱动调用了 IoCompleteRequest() 函数时,基本上所有设备栈相关 IRP 处理工作都是在它那里完成的。包括 IRP->Flags 的一些标志的判断,对 APC 的处理,抛出MULTIPLE_IRP_COMPLETE_REQUESTS 错误等。当它延设备栈一直调用驱动所安装的 CompleteRoutine时,如果发现 STATUS_MORE_PROCESSING_REQUIRED 这个标志,则会停止向上继续回滚。这也是为什么在 CompleteRoutine 中使用这个标志即可暂停 IRP 的原因。
9、关于 ObQueryNameString 的使用
这个函数的使用,在有些环境下会有问题。它的上层函数是 ZwQueryObject()。在某些情况下会导致系统挂起,或者直接 BSOD。它是从 对象管理器中的 ObpRootDirectoryObject开始遍历,通过 OBJECT_HEADER_TO_NAME_INFO 获得对象名称。今天问了下 PolyMeta好象是在处理 PIPE 时会挂启,这个问题出现在 2000 系统。在 XP 上好象补丁了。
10、关于重入问题
其实这个问题在很久前的 IFS FAQ 里已经介绍的很清楚,包括处理方法以及每种方法可能带来的问题。IFS FAQ 里的 Q34 一共介绍了四种方法,包括自己从头建立 IRP发送,使用 ShadowDevice,使用特征字符串,根据线程 ID,在 XP 下使用() 函数。并且把以上几种在不同环境下使用要处理的问题也做了简单的介绍。且在 Q33 里介绍了在 CIFS 碰到的 FILE_COMPLETE_IF_OPLOCKED 问题的解决方法。
⑤ 《Windows文件系统过滤驱动开发教程(第二版)》最新txt全集下载
Windows文件系统过滤驱动开发教程(第二版) txt全集小说附件已上传到网络网盘,点击免费下载:
需要别的再问
⑥ 请教用文件过滤驱动的方式透明加密linux中的文件
文件系统过滤驱动是一种可选的,为文件系统提供具有附加值功能的驱动程序。文件系统回过滤驱动答是一种核心模式组件,它作为Windows NT执行体的一部分运行。 文件系统过滤驱动可以过滤一个或多个文件系统或文件系统卷的I/O操作。按不同的种类划分,...
⑦ 过滤驱动中打开文件时如何避免重入
在处理IRP_MJ_CREATE请求时,过滤驱动可能会使用不同的属性/权限等打开这个文件。这种情况经常发生在第二次调用ZwCreatefile时。这会导致生成一个对FSD 过滤驱动的回调(就是重入了).因而,正常的过滤驱动就要有能力检测这种重入的问题。
There are several ways of dealing with reentrancy ring an IRP_MJ_CREATE operation, and the appropriate solution for your particular driver will depend upon the circumstances. In addition, there are a number of techniques that might work for a single file system filter driver, but that fail when used in a multi-filter environment.
在处理IRP_MJ_CREATE操作过程中,有几种方法可以处理重入,处理你的驱动(中的重入)的适当方法取决于你的环境。另外,有许多种技术可以在单个文件系统过滤驱动上工作,但在多层过滤的环境下可能会失效。
For Windows XP and newer versions of Windows, the best mechanism for opening a file within the filter is to use . A filter driver can call this function and specify a given device object. The IRP_MJ_CREATE that is built will be passed to the specified device object. This technique avo
ids reentrancy issues and is the best mechanism available for a filter to open a file.
对Windows xp或者更新版的Windows来说,在过滤驱动中打开一个文件的最好方法是使用.文件过滤驱动可以调用这个函数并且指定一个给定的设备对象。
For versions of Windows prior to Windows XP, this mechanism is not available. The best mechanism in this environment is to implement your own functional equivalent of . This can be done by creating a second device object for each device you are filtering.
对Windows xp以前的Windows操作系统,这种方法无效。在这种环境下最好的方法是实现你自己的与等价的功能。这可以通过给你要过滤的设备创建第二个设备对象来实现。
For example, suppose you decide to filter some given file system device object, FSDVolumeDeviceObject. You then create a device object MyFilterDeviceObject and attach it using IoAttachDeviceToDeviceStack (of course, in Windows XP you would use instead). In addition, you create a second device object MyFilterShadowDeviceObject. This device object must be assigned a name ("DeviceMyFilterDevice27", for example). The name can be anything, but it must obviously be unique. In your device extension for your two device objects, you need to track this name, and you need to maintain pointers to the respective device objects (that is, the device extension for MyFilterShadowDeviceObject should point to MyFilterDeviceObject and the device object extension for MyFilterDeviceObject should point to yFilterShadowDeviceObject). Don't forget to set the StackSize field of the device object correctly!)
例如,假设你要过滤某个特定的文件系统设备对象,FSDVolumeDeviceObject(文件系统卷设备对象).这时你要创建一个设备对象MyFilterDeviceObject 并且使用IoAttachDeviceToDeviceStack 函数(在windows xp下使用 )来挂接它。另外,你还要创建第二个设备对象yFilterShadowDeviceObject.这个设备对象必须被指定一个名字(例如"DeviceMyFilterDevice27",注: 这里指的第二个设备对象,即Shadow device object )。名字可以是任意的,但必须唯一的。在这两个设备的设备扩展结构中,你需要跟踪这个名字
(注,其实就是做标志,你要知道你当前是处在哪个设备中,是第一个设备对象还是Shadow object )你需要维护一些指向相应的设备对象的指针(也就是说,MyFilterShadowDeviceObject的设备扩展要指向MyFilterDeviceObject,MyFilterDeviceObject的设备扩展对象要指向MyFilterShadowDeviceObject.不要忘了正确设置设备对象的StackSize成员变量。
Now, an IRP_MJ_CREATE request arrives in your filter, specifying MyFilterDeviceObject. To open the file without experiencing reentrancy problems, you call IoCreateFile (or ZwCreateFile). Since you must pass the name of the file being opened, you construct that by using both the name you gave MyFilterShadowDeviceObject and the name that is in the FileObject of the I/O stack Location (IoGetCurrentIr
pStackLocation(Irp)->FileObject).
现在,当IRP_MJ_CREATE 请求到达你的过滤驱动时,指定了 MyFilterDeviceObject.你调用IoCreateFile(或ZwCreateFile) 打开文件就没有重入的问题了.以后,你必须传递这个打开的文件的名字,这个名字是用你设置在MyFilterShadowDeviceObject中的名字和从I/O 堆栈区域中得到的文件对象中的名字一起构造的。
Since you are passing a name in that points to your second device object, the I/O Manager will build the IRP_MJ_CREATE and pass the resulting I/O request packet to your driver, but specifying MyFilterShadowDeviceObject.
当你传递一个指向你的第二个设备对象的名字,I/O管理器会构建IRP_MJ_CREATE 并且传递I/O请求的结果到你的驱动,但指定了MyFilterShadowDeviceObject.
In your IRP_MJ_CREATE dispatch handler you must detect that this is a "shadow" device object, rather than a typical filter device object. In this case, you should send the IRP_MJ_CREATE operation down to the device being filtered by MyFilterDeviceObject. Indeed, since you should not need to do any further processing, you can use IoSkipCurrentIrpStackLocation (rather than ).
在你的IRP_MJ_CREATE 分发例程处理函数中,你必须检测它是一个"Sahdow"设备对象而不是是一个典型的过滤设备对象。在这种情况下,你必须将IRP_MJ_CREATE操作下传到已经被 MyFilterDeviceObject过滤了的设备中。确实,此后你不需要作进一步的处理,你可以用IoSkipCurrentIrpStackLocation函数(不是).
⑧ linux怎样加载文件过滤驱动
文件系统过滤驱动是一种可选的,为文件系统提供具有附加值功能的驱动程序。文件系统过滤驱动是一种核心模式组件,它作为Windows NT执行体的一部分运行。
文件系统过滤驱动可以过滤一个或多个文件系统或文件系统卷的I/O操作。按不同的种类划分,文件系统过滤驱动可以分成日志记录、系统监测、数据修改或事件预防几类。通常,以文件系统过滤驱动为核心的应用程序有防毒软件、加密程序、分级存储管理系统等。
二、文件系统过滤驱动并不是设备驱动
设备驱动是用来控制特定硬件I/O设备的软件组件。例如:DVD存储设备驱动是一个DVD驱动。
相反,文件系统过滤驱动与一个或多个文件系统协同工作来处理文件I/O操作。这些操作包括:创建、打开、关闭、枚举文件和目录;获取和设置文件、目录、卷的相关信息;向文件中读取或写入数据。另外,文件系统过滤驱动必须支持文件系统特定的功能,例如缓存、锁定、稀疏文件、磁盘配额、压缩、安全、可恢复性、还原点和卷装载等。
下面两部分详细的阐述了文件系统过滤驱动和设备驱动之间的相似点与不同点。
三、安装文件系统过滤驱动
对于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来使设备对象对应用程序可见)。
注意:由于控制设备对象是唯一不会附加到设备堆栈中的设备对象,因此控制设备对象是唯一的可安全命名的设备对象。由此,是否为文件系统过滤驱动的控制设备对象是否命名是可选的。
注意:文件系统的控制设备对象必须命名。过滤设备对象从不命名。
⑨ 基于 IFS文件过滤驱动 编程
这个主要要看SDK,以及windows驱动编程
⑩ 如何在文件过滤驱动中启动一个应用层进程
一般来说,那些复在你电脑上安装的应用制程序在后台运行的进程是可以关闭的,而那些windows自动运行的服务程序/进程是万万不可关闭的(可以在进程中的描述一栏中找到)。但是,这并不意味着所有后台运行的应用程序/进程(你所安装的)都可以关闭,比如的数据传输通道,杀毒的后台防护程序等等,这些也不能关闭。还有一些进程,比如声卡等。其实,如果你是想关闭某个后台程序以用来释放内存的话,可以用杀毒自带的释放内存工具来实现,一般来说,还是不要直接通过任务管理器关闭后台进程,这样可能会让电脑崩溃,也可能会丢失那些被你关闭的应用程序的数据。