为了应付面试,学习MiniFilter,顺道将MiniFilter的内部实现基本逆了一道,逆了三个晚上感冒了,先放出一部分,后续会放出MiniFilter通信的内部实现,希望对于像我这种初学MiniFilter,又没有了解sfilter过的同学会有所帮助,大佬请略过。
本质:我们编写的minifilter过滤驱动则是通过向过滤管理器(Filter Manager)驱动进行注册自己需要过滤的一些操作,提供指定格式的回调函数让过滤管理器来进行调用即可。
FltMgr!GsDriverEntry:入口点
注:编译器默认开启/GS编译选项,用来保护内核栈的完整性。编译器会在程序开始的地方,保存一个cookie值到栈上;在程序退出时再检查这个cookie值是否被破坏,如果被破坏,说明栈溢出,表明系统遭到了破坏从而需要蓝屏保护。
GS是一种被普遍运用的保护机制。开启了GS选项后,编译器会链接一个GS相关的库文件来实现GS功能,当目标系统为Win7时库文件是BufferOverflowK.lib,当目标系统为Win8+时库文件是BufferOverflowFastFailK.lib。链接器是如何实现栈保护的呢?它先在驱动加载的时候,也就是GsDriverEntry函数内初始化cookie。然后在每个驱动函数的开始和结束的地方,添加cookie检查的代码。
链接器为了对cookie进行初始化,会为驱动程序重新生成一个名为GsDriverEntry的入口函数,初始化Cookie后再调用驱动程序自己的DriverEntry入口函数。
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pReg)(参数如下)
//注册MiniFsFilter的通知回调例程必须分配并初始化FS_FILTER_CALLBACKS结构体,后续会向该结构体中写入MiniFs回调例程,并将存储有Callbacks parameter到FsRtlRegisterFileSystemFilterCallbacks中。
FS_FILTER_CALLBACKS Callbacks;
RtlZeroMemory(&Callbacks,Sizeof(FS_FILTER_CALLBACKS));
//FTLMGR初始化全局变量结构,过滤管理器的关链数据结构都写在这个里面
GLOBALS FltGlobals;
RtlZeroMemory(&FltGlobals,Sizeof(GLOBALS))
//设置初始化标志, 1代表FltMgr驱动启动. Gflags第8位,是代表是否DisableFrameMonitoring
FltGlobals.Gflags=1;
//动态加载,将FsrtlFltMgrCallbacks的地址放进FltMgrCallbacks全局变量里
FsRtlRegisterFltMgrCalls(FsrtlFltMgrCallbacks);
//
FltGlobals.Gflags |= 0x102;
FltGlobals.FastManualAttachTimerPeriod=5;
FltGlobals.ManualAttachTimerPeriod=0xF;
//通过注册表里的参数给FltGlobals的结构赋值
FltpReadDriverParameters(RegPath); RegPath=\Registry\Machine\System\CurrentControlSet\Services\FltMgr
//初始化驱动程序分配的资源结构
ExInitializeResourceLite(&FltDynamicRegistrySettingsResource);
//注册表监控,监控Registry\\Machine\\System\\CurrentControlSet\\Control\\FileSystem\下所有子键
REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET的改变,例程立即返回
实际上就是调用ZwNotifyChangeKey
//判断是否对OCX磁盘阵列的支持,写进FltGlobals.FilterSupportedFeaturesMode 0为允许,1为禁止
//并且更新FltGlobals.FilterSupportedFeaturesMode
FltpUpdateDynamicRegistrySettings();
//给FltMgr全局变量赋值
FltGlobals.DriverObject = DriverObject;
FltGlobals.ActiveProcessorCount = KeQueryActiveProcessorCountEx(0xFFFFi64); //得到当前活动CPU数量
FltGlobals.CacheLineSize = KeGetRecommendedSharedDataAlignment();//Cache缓存的基本单位
FltGlobals.AlignedInstanceTrackingListSize = ~(FltGlobals.CacheLineSize - 1) & (FltGlobals.CacheLineSize - 1 + 0x30);
FltGlobals.RegistryPath.MaximumLength=0x140
FltGlobals.RegistryPath.Buffer = &FltGlobals.RegistryPathBuffer;
RtlCopyUnicodeString(&FltGlobals.RegistryPath, RegPath); //注册表路径Registry\Machine\System\CurrentControlSet\Services\FltMgr复制进去
//创建CDO(控制设备对象)
Status = IoCreateDevice( DriverObject,
NULL,
&FltMgrDeviceName, //"\FileSystem\Filters\FltMgr"
FILE_DEVICE_DISK_FILE_SYSTEM, //磁盘文件系统
FILE_DEVICE_SECURE_OPEN, //标识指示I/O管理器对所有发送到控制设备对象的Open请求进行安全检测
FALSE,
&FltGlobals.ControlDeviceObject);
//创建符号链接
RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\FltMgr");
Status=IoCreateSymbolicLink(&SymbolicLinkName, &FltMgrDeviceName)
//CDO设备扩展结构指针
(FltGlobals.ControlDeviceObject)->DeviceExtension=0;
//初始化事件跟踪
FltpInitializeTelemetry();
//设置派遣函数
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++){
DriverObject->MajorFunction[i] = FltpDispatch;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = FltpCreate;
DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = FltpCreate;
DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = FltpCreate;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FltpFsControl; //卷设备绑定
//初始化文件快速IO
PFAST_IO_DISPATCH fastIoDispatch;
fastIoDispatch = ExAllocatePoolWithTag( NonPagedPoolNx,sizeof( FAST_IO_DISPATCH ),'ifMF' );
if ( fastIoDispatch )
{
/*
当请求直接传递到基本文件系统时,有6个FastIO例程绕过了文件系统过滤器。
这6个例程是AcquireFileForNtCreateSection、ReleaseFileForNtCreateSection、
AcquireForModWrite、ReleaseForModWrite、AcquireForCcFlush和ReleaseForCcFlush。
*/
RtlZeroMemory(fastIoDispatch,SizeOf(FAST_IO_DISPATCH));
FastIoDipatch->SizeOfFastIoDispatch = Sizeof(FAST_IO_DISPATCH);
FastIoDipatch->FastIoCheckIfPossible = FltpFastIoCheckIfPossible;
FastIoDipatch->FastIoRead = FltpFastIoRead;
FastIoDipatch->FastIoWrite = FltpFastIoWrite;
FastIoDipatch->FastIoQueryBasicInfo = FltpFastIoQueryBasicInfo;
FastIoDipatch->FastIoQueryStandardInfo = FltpFastIoQueryStandardInfo;
FastIoDipatch->FastIoLock = FltpFastIoLock;
FastIoDipatch->FastIoUnlockSingle = FltpFastIoUnlockSingle;
FastIoDipatch->FastIoUnlockAll = FltpFastIoUnlockAll;
FastIoDipatch->FastIoUnlockAllByKey = FltpFastIoUnlockAllByKey;
FastIoDipatch->FastIoDeviceControl = FltpFastIoDeviceControl;
FastIoDipatch->FastIoDetachDevice = FltpFastIoDetachDevice;
FastIoDipatch->FastIoQueryNetworkOpenInfo = FltpFastIoQueryNetworkOpenInfo;
FastIoDipatch->FastIoQueryOpen = FltpFastIoQueryOpen;
FastIoDipatch->MdlRead = FltpFastIoMdlRead;
FastIoDipatch->MdlReadComplete = FltpFastIoMdlReadComplete;
FastIoDipatch->PrepareMdlWrite = FltpFastIoPrepareMdlWrite;
FastIoDipatch->MdlWriteComplete = FltpFastIoMdlWriteComplete;
FastIoDipatch->FastIoReadCompressed = FltpFastIoReadCompressed;
FastIoDipatch->FastIoWriteCompressed = FltpFastIoWriteCompressed;
FastIoDipatch->MdlReadCompleteCompressed = FltpFastIoMdlReadCompleteCompressed;
FastIoDipatch->MdlWriteCompleteCompressed = FltpFastIoMdlWriteCompleteCompressed;
DriverObject->FastIoDispatch = FastIoDipatch;
//初始化FsFilter回调
FS_FILTER_CALLBACKS fsFilterCallbacks;
fsFilterCallbacks.SizeOfFsFilterCallbacks = sizeof( FS_FILTER_CALLBACKS );
fsFilterCallbacks.PreAcquireForSectionSynchronization = FltpPreFsFilterOperation;
fsFilterCallbacks.PostAcquireForSectionSynchronization = FltpPostFsFilterOperation;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!