首页
论坛
课程
招聘
[系统底层] [原创]win10 1909逆向(MiniFilter原理剖析2---FltRegisterFilter(注册))
2021-4-16 21:01 1799

[系统底层] [原创]win10 1909逆向(MiniFilter原理剖析2---FltRegisterFilter(注册))

2021-4-16 21:01
1799

0x0 前言

接上篇win10 1909逆向(MiniFilter原理剖析1---FltMgr的初始化)


0x1 原理剖析

status = FltRegisterFilter( DriverObject, &FilterRegistration,&gFilterHandle );

FLT_REGISTRATION-----------------------微过滤器注册结构(用户自已填写)

FLT_FILTER----------------------------------微过滤器对象结构(在注册阶段,由系统根据FLT_REGISTRATION结构填写)

// Filter管理器还没有初始化就调用注册函数。需要确保 filter管理器已经作为一个驱动启动了

 if ( !(GLOBALS->Gflags & 1) )                           // dt _FLTMGR!_GLOBALS 微过滤器的全局结构

   return STATUS_FLT_NOT_INITIALIZED;  

FltMgr管理器的全局结构,后续会多次用到。


// 判断版本号,次版本号可以忽略,但主版本号必须正确

if ((Registration->Version & 0xFF00) != FLT_MAJOR_VERSION)

{

return STATUS_INVALID_PARAMETER;

}

//判断命名回调组合

if ((!Registration->GenerateFileNameCallback && Registration->NormalizeNameComponentCallback) ||

(!Registration->NormalizeNameComponentCallback && Registration->NormalizeContextCleanupCallback))

{

return STATUS_INVALID_PARAMETER;

}

//得到回调函数集合地址

Callbacks = (PFLT_OPERATION_REGISTRATION)Registration->OperationRegistration;

//计算当前回调函数集合有几个回调

while (Callbacks)

{

Count++;

if (Callbacks->MajorFunction == IRP_MJ_OPERATION_END)

break;

Callbacks++;

}

//计算过滤器缓存结构大小

CallbackBufferSize = Count * sizeof(FLT_OPERATION_REGISTRATION);

FilterBufferSize = sizeof(FLT_FILTER) +

CallbackBufferSize +

DriverObject->DriverExtension->ServiceKeyName.Length;

//分配一个块空间来保存我们的过滤器缓存结构

Filter = ExAllocatePoolWithTag(NonPagedPoolNx,FilterBufferSize,FM_TAG_FILTER);

if (Filter == NULL) return STATUS_INSUFFICIENT_RESOURCES;

RtlZeroMemory(Filter, FilterBufferSize);

//设置回调地址,将注册结构的回调地址复制到Filter对象里

Filter->FilterUnload = Registration->FilterUnloadCallback;

Filter->InstanceSetup = Registration->InstanceSetupCallback;

Filter->InstanceQueryTeardown = Registration->InstanceQueryTeardownCallback;

Filter->InstanceTeardownStart = Registration->InstanceTeardownStartCallback;

Filter->InstanceTeardownComplete = Registration->InstanceTeardownCompleteCallback;

Filter->GenerateFileName = Registration->GenerateFileNameCallback;

Filter->NormalizeNameComponent = Registration->NormalizeNameComponentCallback;

Filter->NormalizeContextCleanup = Registration->NormalizeContextCleanupCallback;

UINT64 Version=Registration->Version;

if ( Version>= 0x201 )  //Vista Beta 2以上

   {

     Filter->KtmNotification= Registration->TransactionNotificationCallback;

     Version = Registration->Version;

   }

if ( Version>= 0x202 )  //Vista RTM以上

   {

    Filter->NormalizeNameComponentEx= Registration->NormalizeNameComponentExCallback;

     Version = Registration->Version;

   }

if ( Version>= 0x203 )  //Win 8以上

   {

    Filter->SectionNotification= Registration->SectionNotificationCallback;

    if(Registration->Flags & FLTFL_REGISTRATION_SUPPORT_NPFS_MSFS)   //如果已设置,则此筛选器可识别命名管道和邮件槽筛选

       {

                 Filter->Flags | = FLTFL_SUPPORTS_PIPES_MAILSLOTS;  

       }

   }

if(Registration->Flags & FLTFL_REGISTRATION_SUPPORT_DAX_VOLUME)  //如果已设置,则此筛选器将识别DAX卷,即支持直接在永久内存

  {                                                                                                                           //设备上映射文件的卷。对于这样的卷,缓存和内存映射到用户

         Filter->Flags | = FLTFL_SUPPORTS_DAX_VOLUME;                               //文件的IO不会生成分页IO。

  }

//Ptr是FilterBuffer结构的一部分,里面会存放Flt_Registration里的OperationRegistration的数据,然后将ptr的地址放进_FLT_FILTER->Operation

Ptr = (PCHAR)(Filter + 1);

Filter->Base.Flags = FLT_OBFL_TYPE_FILTER;   //设置类型

Filter->Base.PointerCount = 1;  //引向次数+1

ExInitializeRundownProtection(&Filter->Base.RundownRef); //初始化停止运行保护机制

//初始化

Filter->Base.PrimaryLink=0;

Filter->UniqueIdentifier.Data1=0;

Filter->UniqueIdentifier.Data2=0;

Filter->UniqueIdentifier.Data3=0;

Filter->UniqueIdentifier.Data4=0;

FltObjectReference(&Filter->Base);  //锁住保护Filter

Filter->DriverObject = DriverObject;

//初始化各个链表

ExInitializeResourceLite(&Filter->InstanceList.rLock);

InitializeListHead(&Filter->InstanceList.rList);

Filter->InstanceList.rCount = 0;

ExInitializeFastMutex(&Filter->ActiveOpens.mLock);

InitializeListHead(&Filter->ActiveOpens.mList);

Filter->ActiveOpens.mCount = 0;

ExInitializeFastMutex(&Filter->ConnectionList.mLock);

InitializeListHead(&Filter->ConnectionList.mList);

Filter->ConnectionList.mCount = 0;

ExInitializeFastMutex(&Filter->PortList.mLock);

InitializeListHead(&Filter->PortList.mList);

Filter->PortList.mCount = 0;

//如果有上下文注册

if (Registration->ContextRegistration)

{

Status = FltpProcessContextRegistration(Filter, Registration->ContextRegistration);

if(!NTSTATUS(Status))

{

****省略*****

}

}

//

if (Registration->OperationRegistration)

{

//当前Ptr是FilterBuffer结构的一部分,里面会存放Flt_Registration里的OperationRegistration的数据,然后将ptr的地址放进_FLT_FILTER->Operation

Filter->Operations = (PFLT_OPERATION_REGISTRATION)Ptr;

//当前Ptr是FilterBuffer结构的一部分,后面会存放DriverObject->DriverExtension->ServiceKeyName的数据

Ptr += (Count * sizeof(FLT_OPERATION_REGISTRATION));

//将Flt_Registration里的OperationRegistration的数据复制到 Filter->Operations指向的地址空间里

RtlCopyMemory(Filter->Operations, Registration->OperationRegistration, CallbackBufferSize);

//

for (Callbacks = Filter->Operations;

Callbacks->MajorFunction != IRP_MJ_OPERATION_END;

Callbacks++)

{

if (Callbacks->MajorFunction == IRP_MJ_VOLUME_MOUNT)

{

Filter->PreVolumeMount = Callbacks->PreOperation;

Filter->PostVolumeMount = Callbacks->PostOperation;

}

else if (Callbacks->MajorFunction != IRP_MJ_VOLUME_DISMOUNT)

{

if (Callbacks->MajorFunction == IRP_MJ_SHUTDOWN)

{

//如果是关机,只有预操作函数,没有后操作回调函数直接设为NULL

Callbacks->PostOperation = NULL;

}


//将注册表服务键值复制到Filter->Name里

Filter->Name.Length = 0;

Filter->Name.MaximumLength = DriverObject->DriverExtension->ServiceKeyName.Length;

Filter->Name.Buffer = (PWCH)Ptr;

RtlCopyUnicodeString(&Filter->Name, &DriverObject->DriverExtension->ServiceKeyName);

//初始化过滤验证,需要开启标志,未开启标记返回0

Status = FltpInitializeFilterVerifier(Filter);

if ( Status < 0 )  //退出清理

// 从注册表里和Filter->Name配合得到Altitude这个字符串放进Filter->DefaultAltitude里

Status = FltpGetInstanceAltitude(Filter,nouse, nouse, &Filter->DefaultAltitude);

if ( Status < 0 )  //退出清理

//从全局帧链表里找到符合条件的帧放进Filter->Frame

Status = FltpFindFrameForFilter(Filter, &Filter->DefaultAltitude);

if ( Status < 0 )  //退出清理

//内核事务管理器

if ( Filter->KtmNotification )           // KtmNotification

   {

     Status = FltpCreateKtmResourceManager(

                &varFilter->Frame->KtmResourceManagerHandle,

                &varFilter->Frame->KtmResourceManager,

                FltpKtmNotification);

     if ( Status < 0 )  //退出清理

   }

//将&Filter->Base.PrimaryLink地址放进Filter->Frame->RegisteredFilters->Fink

//

Status = FltpLinkFilterIntoFrame(Filter);  if ( Status < 0 )  //退出清理

//先保存驱动的卸载函数到Filter->OldDriverUnload

Filter->OldDriverUnload = (PFLT_FILTER_UNLOAD_CALLBACK)DriverObject->DriverUnload;

if (Registration->FilterUnloadCallback && !FlagOn(Filter->Flags, FLTFL_REGISTRATION_DO_NOT_SUPPORT_SERVICE_STOP))

{

//我们写了Filter卸载函数,并且未设置不同意卸载,则将当前驱动的卸载函数换成我们写的卸载函数

DriverObject->DriverUnload = (PDRIVER_UNLOAD)FltpMiniFilterDriverUnload;

}

else

{

//我们没有写Filter的卸载函数或者,我们将flags设为不同意卸载,那直接将当前驱动的卸载函数设为NULL

DriverObject->DriverUnload = (PDRIVER_UNLOAD)NULL;

}

//这里会有一些判断,我直接简化掉了

//设置Filter的标识符

FltpGetUniqueIdentifierForObject(Filter)


if (NT_SUCCESS(Status))

{

//返回值。

*RetFilter = Filter;

//得到注册表里的值格式化字符串

FltpTelemetrySerializeFilterRegistrationInfo(Filter, Registration, &UnicodeString)

...略...

}

else

{

...略...

}

以上就是注册的基本流程。



[看雪官方培训] Unicorn Trace还原Ollvm算法!《安卓高级研修班》2021年6月班火热招生!!

收藏
点赞3
打赏
分享
最新回复 (2)
雪    币: 1545
活跃值: 活跃值 (491)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dearfuture 活跃值 2021-4-19 09:50
2
0
豆总牛逼我也一直想逆逆这块,但没啥时间。希望豆总后面也讲讲Fltmgr.sys收到irp或者fastio请求后怎么封装成FLT_CALLBACK_DATA并分发给各个altitude的minifilter的?precallback和postcallback的调用时机和拦截原理(返回FLT_PREOP_SUCCESS_NO_CALLBACK/FLT_PREOP_COMPLETE的效果如何实现),卷绑定的实现原理之类的
雪    币: 3131
活跃值: 活跃值 (3366)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
学技术打豆豆 活跃值 1 2021-4-20 10:53
3
0
dearfuture 豆总牛逼[em_63]我也一直想逆逆这块,但没啥时间。希望豆总后面也讲讲Fltmgr.sys收到irp或者fastio请求后怎么封装成FLT_CALLBACK_DATA并分发给各个altitude的m ...
你可真想累死我
游客
登录 | 注册 方可回帖
返回