Windows内核安全——第六章 磁盘过滤

       本章目标:完成一个磁盘卷设备的上层类过滤驱动,该过滤驱动的功能是实现对卷的还原,即开启该驱动的功能之后,对还原卷的写操作将只适用于当前,重启电脑后所写入的数据都将清零,类似于还原卡之类的功能。

1、磁盘卷设备

       OK,根据章节的主题。首先要知道什么是磁盘卷设备,根据《windows internals》一书中的讲解,Windows的存储结构自上而下分成以下各个部分,如图所示:

Windows内核安全——第六章 磁盘过滤_第1张图片

(擦,一个图片翻译了N久,尼玛~)

       根据图中可以看出各个部分的功能,从中我们可以看见卷设备所处在的层级。


2、上层类过滤驱动

    根据驱动的层级,类功能驱动的上下可以添加相应的过滤驱动,添加在上层的称为上层过滤驱动,添加在下层的称为下层过滤驱动(前面的笔记中也有类似的介绍)。

代码分析:

1、  DriverEntry

DriveEntry中有一个API:

VOID IoRegisterBootDriverReinitialization(

 _In_      PDRIVER_OBJECTDriverObject,

 _In_      PDRIVER_REINITIALIZEDriverReinitializationRoutine,

 _In_opt_  PVOID Context

);

该API用来注册一个函数,用于在boot驱动结束之后回调,该函数会在所有boot类型驱动都运行完毕之后执行。

可以看到回调函数中使用了其它盘作为“数据暂存处”,所以需要保证其他盘已经加载OK之后再调用,也就是为什么使用该API进行注册的原因。

 

2、  AddDevice

AddDevice例程中就是创建对应的过滤设备对象,该例程中有点不一样的是创建了一个内核线程。

NTSTATUS PsCreateSystemThread(

 _Out_      PHANDLE         ThreadHandle,

 _In_       ULONG            DesiredAccess,

 _In_opt_   POBJECT_ATTRIBUTESObjectAttributes,

 _In_opt_   HANDLE            ProcessHandle,

 _Out_opt_  PCLIENT_ID         ClientId,

 _In_       PKSTART_ROUTINE   StartRoutine,

 _In_opt_   PVOID             StartContext

);

该线程用于处理读写的操作。

 

3、  PNP处理

在该例程中主要是对IRP_MN_DEVICE_USAGE_NOTIFICATION进行处理,因为分页文件的存在,根据Parameters.UsageNotification.Type判断是否是特殊文件,若有页面文件的存在则要清除DO_POWER_PAGEABLE,反之加上。对于特殊文件的处理都需要将请求发送给下层驱动去处理,过滤驱动本身不做任何操作,根据下层操作的结果返回状态。

POWER和DeviceIoControl的请求没有基本和其它的类似。

 

Bitmap的作用和分析

Bitmap是一个位图,实际上是一些内存块,这些内存块的每一个位用来标识一个磁盘的最小访问单位,一般情况下是一个扇区,每一个位可以被置位或被清除,用来表示这个扇区所对应的两种情况(这个让人想起《数学之美》书中讲的布隆过滤器,将所有的数据排放在对应的位上,该位是1,则数据存在,如果是0,则不存在数据,好吧,这个跟很多面试题中,判断几十万个电话号码中是否存在某一电话号码是一个概念~)。

根据Bitmap的信息我们就可以判断内存中哪一片已经使用,而哪一片是空的了。

 

Boot驱动完成回调函数和稀疏文件

在前面有用到一个函数IoRegisterBootDriverReinitialization,这个函数注册了一个完成回调函数,在该驱动所有操作结束之后就开始执行该函数了。从书的代码中可以看见,这边主要是设置了一个D盘的稀疏文件。

ntStatus = ZwFsControlFile(

                   gProtectDevExt->TempFile,

                   NULL,

                   NULL,

                   NULL,

                   &ios,

                   FSCTL_SET_SPARSE,

                   NULL,

                   0,

                   NULL,

                   0);

FileEndInfo.EndOfFile.QuadPart= gProtectDevExt->TotalSizeInByte.QuadPart + 10*1024*1024;

ntStatus =ZwSetInformationFile(

                   gProtectDevExt->TempFile,

                   &ios,

                   &FileEndInfo,

                   sizeof(FILE_END_OF_FILE_INFORMATION),

                   FileEndOfFileInformation

                   );

这边使用了一个很有趣的文件类型——稀疏文件,百度了一下这个,发现居然是一个很实用的文件类型,在建立这种文件的时候容量可以设定很大,但是在实际使用的时候却会根据实际磁盘的容量有限制。因为稀疏文件是依赖文件系统的,所以建立该文件的过程就被放在了boot回调函数中进行。

感觉笔记写的很乱~

你可能感兴趣的:(Windows,驱动开发)