摘要
我们的作业是在Windows下编写一个文件过滤驱动程序,该文件过滤驱动可以保护某一文件或者目录,驱动可以根据权限文件的权限记录来控制用户对被保护文件的读、写、删除操作。我们的计划是先在网上收集相关的学习资料进行学习和参考,学习如何去配置环境,如何用模板来写出一个HelloWorld程序,然后再实现如何对文件的保护,一步一步地实现作业需求。花了一定时间后,我们发现了Windows的Visual Studio 2017下面的Driver:Minifilter框架(微过滤器框架),其特点是封装得比较好,适合初学者开发。我们的测试环境是VMware虚拟机+Windows7,在禁止强制签名的情况下可以安装没有数字签名的驱动。在Minifilter框架下,对不同的IRP进行相应的判断和操作可以实现对文件的保护,比如用户进入了被保护的文件,而且尝试进行写,那么就会产生IRP_MJ_WRITE信号,禁止其则可以阻止写操作。在编译工程的时候,一开始一直编译不成功(编译可以通过,但是无法运行,错误:1275),后来发现要把解决方案平台x86改成x64,然后还要改工程的两个属性,这个具体后面再讲。编译成功后,驱动可以正常运行,实现了对文件的读、写和删除的权限限制。接下来我们的工作是实现在内核中读取权限记录文件,然后在对读取的内容进行判断,如果是false则阻止,true则不阻止。但是我们发现在内核中的文件操作很容易造成蓝屏,研究了很长时间都没有解决这个问题。所以我们的开发的驱动只是完成了最基本的过滤操作,并没有完全实现功能需求。
功能需求
设计一个可以对指定文件的操作权限监管的驱动程序,且该驱动程序可以在Windows7 x64环境下运行。用户通过修改权限文件中的内容修改指定文件的操作权限,并按照用户的需求启用和卸载该驱动程序。驱动程序要求有对指定目标文件的读、写、删除权限的控制,要求能够从权限文件中读取权限。在安装该驱动程序的时候,要求用户填写用户名,密码,要保护的文件或者文件目录,然后再确定保护权限,即读、写和删除权限。安装成功后,如果有对保护文件或者文件目录的非法操作,驱动就会阻止。如果用户想更改权限或者删除该驱动程序,首先得输入用户名和密码,然后才可以更改权限记录文件的记录以及删除该驱动程序。
设计思路
本次实验要求对目标文件具有过滤功能。通过上网查找资料,我们找到了Windows Driver Kit 中自带的Minifilter(也称微过滤器)框架。Minifilter框架相比较其他的过滤器框架来说,所具有的优点是Minifilter框架的封装程度高,入门比较简单,无需输入复杂的代码。但是此框架由于出现时间较晚,而且对文件的操作与其他过滤器有些区别,而且minifilter的参考资料很少,Msdn中的介绍缺少实例。
1.因为Minifilter框架(微过滤器)的封装程度较高,所以在源代码里面直接调用相关函数,或者解注释即可实现相关的功能。在这次作业中,我们要实现的功能是和写、读和删除有关。那么,在该框架下的源代码中的 Callbacks[]函数将相关的IRP请求放出来(去掉注释)。写对应IRP_MJ_WRITE,读对应IRP_MJ_CREATE,删除对应IRP_MJ_SET_INFORMATION
当用户进行相关的操作后,系统就会发出相应的IRP请求,驱动就可以将其截获,然后就可以调用回调函数对其判断,如果判断出该IRP请求的文件路径或者文件名就是我们所要的保护的文件,则再根据权限记录来限制其操作。
2.读取权限文件,因为要获得权限记录,所以要在驱动程序中进行相关的文件操作,这个文件操作不同于上面的IRP操作。我们打算用FLTxxxxfile()系列函数来进行相关的文件操作。首先把文件中的所有内容读取到变量buffer里面,然后再判断buffer里面有没有xxxx_true或者xxxx_false 子串,经过条件判断后再确定阻止不阻止该操作。
3.登录界面和安装程序,在执行安装程序时,要求用户输入姓名和密码,以及要保护的文件或者文件目录,还有要求的三个权限。输入完成之后就安装驱动程序,然后用户在通过管理员模式下的命令行来启动该驱动。
开发环境配置
a.开发包。wdk10.
Wdk10下载地址(需保证vs有对应版本的sdk):
微软官方Windows Driver Kits下载地址: https://docs.microsoft.com/zh-cn/windows-hardware/drivers/download-the-wdk
要注意的是该WDK要求对应的VisualStudio是2017版本,下载完成之后就双击该安装程序,它可以自动的安装到Visual Studio.安装成功后就会有相应的开发框架选项
我们选择的开发框架是Filter Driver:Filesystem Mini-filter.
b.测试环境:windows7(x64).
首先要安装一个虚拟机VMware,然后选择新建虚拟机,经典安装,再选择Windows7的iso文件进行安装。装成功后,Windows高级选项界面,选择【禁用驱动程序签名强制】选项来进入Windows7.
c.编译及测试过程:用VisualStudio2017打开工程,生成解决方案后,工程Debug目录下会生成对应的.inf和.sys两个文件。将这两个文件复制到测试环境下,选择.inf文件右键安装即可。然后在相应的位置建立一个文本文件(被保护文件)工程保护的文件名为“xxxx.txt”。在管理员模式下打开cmd.exe命令管理器,输入相应的命令(下面会介绍到)来启动驱动程序,然后用户再对xxxx.txt进行相关操作。
程序的难点
1.对通过文件路径获取文件内容并将内容存入缓冲
这项技术主要是给读取权限记录文件服务的。在内核中文件操作有两个系列的函数:ZwxxxxFile()系列和FltxxxxFile()系列。我们将该功能的实现写成一个函数NTSTATUS ReadFileTest(PVOID buffer),参数为一个指向字符数组的指针变量。该函数的具体实现如下:首先进行初始化,获取权限文件目录:InitializeObjectAttributes(&ObjectAttributes,"??\C\user.bat",
OBJ_KERNEL_HANDLE| OBJ_CASE_INSENSITIVE,NULL,NULL);然后在调用FltCreateFileEx()以“读”的方式来将文件内容读取到buffer。但是在那么多次的测试中都是以电脑蓝屏死机而告终。
2.从缓冲区中对比指定字符串
该功能有两个作用:判断权限文件记录内容和判断用户的操作有没有和被保护的文件有关。
通过FltGetFileNameInformation()和FltParseFileNameInformation(nameInfo)两个函数可以获取用户当前操作的文件路径或者文件名,再通过RtlCopyMemory(pTemp, nameInfo->Name.Buffer, nameInfo->Name.MaximumLength)可以将文件名称内容复制到pTemp变量。在通过wcsstr(pTemp, L"XXXX.TXT") 可以判断pTemp储存的内容中是否含有子串"XXXX.TXT",如果返回值不为零,则说明有关系,接下来再结合通过同样的方式判断buffer中含有的true/false信息来决定是否阻止该IRP操作。
3.通过文件名管理文件的读、写、删除权限
首先,需要在callback[]函数将相关的IRP请求放出来(去掉注释)。写对应IRP_MJ_WRITE,读对应IRP_MJ_CREATE,删除对应IRP_MJ_SET_INFORMATION
然后再分别在在回调函数WritePreOperation()、ReadPreOperation()和DeletePreOperation()中编写相应的功能以管理文件的读、写、删除权限,这里以WritePreOperation()为例:
通过上面的功能,我们可以判断pTemp储存的内容中是否含有子串"XXXX.TXT",如果返回值不为零,在加上权限记录为write_false,则通过返回 FLT_PREOP_DISALLOW_FASTIO来阻止该“写”操作。其他函数的实现方式和这个的大同小异。
运行和测试过程
1.生成解决方案
2.获取.inf 和 .sys 两个文件
3.开始时进入高级选项,选择Windows(x64)下禁止驱动签名
4.复制.inf 和.sys 文件到测试环境下,安装及运行
用sc start 来启动驱动
运行效果
1.试图修改保护文件
2.试图删除保护文件
3.试图打开保护文件