FltCreateCommunicationPort 函数在内核中创建Minifilter的ServerPort;
我们要Hook的回调函数MessageNotify,就在ServerPort结构中
typedef struct _FLT_SERVER_PORT_OBJECT
{
LIST_ENTRY FilterLink;
PFLT_CONNECT_NOTIFY ConnectNotify;
PFLT_DISCONNECT_NOTIFY DisconnectNotify;
PFLT_MESSAGE_NOTIFY MessageNotify;
PFLT_FILTER Filter;
PVOID Cookie;
ULONG Flags;
LONG NumberOfConnections;
LONG MaxConnections;
} FLT_SERVER_PORT_OBJECT, *PFLT_SERVER_PORT_OBJECT;
获取这个结构有两种思路
一种是根据Server端口名和ObReferenceObjectByName函数直接获取,比较麻烦的是对象类型是未公开的,需要动态获取,对象类型名称是FilterConnectionPort;
// 尝试获取目标filter类型
FilterConnectionPort = GetObjectType(L"FilterConnectionPort");
if(FilterConnectionPort)
{
RtlInitUnicodeString(&usFilterName, L"\\KernelFilterPort");
NtStatus = ObReferenceObjectByName(&usFilterName,OBJ_CASE_INSENSITIVE,NULL,FILE_ALL_ACCESS,FilterConnectionPort,KernelMode,NULL,(PVOID*)&pServerPort);
if(NT_SUCCESS(NtStatus))
{
DbgPrint("FltServerPort=%p FltMessage=%p FltConnect=%p FltDisConnect=%p\n",
pServerPort,
pServerPort->MessageNotify,
pServerPort->ConnectNotify,
pServerPort->DisconnectNotify
);
ObDereferenceObject(pServerPort);
}
}
第二种是通过FltEnumerateFilters函数,枚举所有Minifilter,得到_FLT_FILTER数组,该结构九二一根据名字判断是不是目标filter驱动
fltmgr!_FLT_FILTER
+0x000 Base : _FLT_OBJECT
+0x020 Frame : 0xfffffa80`31441630 _FLTP_FRAME
+0x028 Name : _UNICODE_STRING "TestDrv"
+0x038 DefaultAltitude : _UNICODE_STRING "168108"
+0x048 Flags : 2 ( FLTFL_FILTERING_INITIATED )
+0x050 DriverObject : 0xfffffa80`326b7ca0 _DRIVER_OBJECT
+0x058 InstanceList : _FLT_RESOURCE_LIST_HEAD
+0x0d8 VerifierExtension : (null)
+0x0e0 VerifiedFiltersLink : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ]
+0x0f0 FilterUnload : 0xfffff880`038011d0 long TestDrv!PtUnload+0
+0x0f8 InstanceSetup : (null)
+0x100 InstanceQueryTeardown : (null)
+0x108 InstanceTeardownStart : (null)
+0x110 InstanceTeardownComplete : (null)
+0x118 SupportedContextsListHead : (null)
+0x120 SupportedContexts : [6] (null)
+0x150 PreVolumeMount : (null)
+0x158 PostVolumeMount : (null)
+0x160 GenerateFileName : (null)
+0x168 NormalizeNameComponent : (null)
+0x170 NormalizeNameComponentEx : (null)
+0x178 NormalizeContextCleanup : (null)
+0x180 KtmNotification : (null)
+0x188 Operations : 0xfffffa80`32f493a0 _FLT_OPERATION_REGISTRATION
+0x190 OldDriverUnload : (null)
+0x198 ActiveOpens : _FLT_MUTEX_LIST_HEAD
+0x1e8 ConnectionList : _FLT_MUTEX_LIST_HEAD
+0x238 PortList : _FLT_MUTEX_LIST_HEAD
+0x288 PortLock : _EX_PUSH_LOCK
在该结构的ConnectionList.m_list字段中保存的是一个双向链表,刚好是_FLT_SERVER_PORT_OBJECT结构的FilterLink
3: kd> dx -id 0,0,fffffa8030ef1040 -r1 (*((fltmgr!_FLT_MUTEX_LIST_HEAD *)0xfffffa8032f492f8))
(*((fltmgr!_FLT_MUTEX_LIST_HEAD *)0xfffffa8032f492f8)) [Type: _FLT_MUTEX_LIST_HEAD]
[+0x000] mLock [Type: _FAST_MUTEX]
[+0x038] mList [Type: _LIST_ENTRY] --------> 双向链表 _FLT_SERVER_PORT_OBJECT
[+0x048] mCount : 0x2 [Type: unsigned long]
[+0x048 ( 0: 0)] mInvalid : 0x0 [Type: unsigned char]
typedef struct _FLT_SERVER_PORT_OBJECT
{
LIST_ENTRY FilterLink;
PFLT_CONNECT_NOTIFY ConnectNotify;
PFLT_DISCONNECT_NOTIFY DisconnectNotify;
PFLT_MESSAGE_NOTIFY MessageNotify;
PFLT_FILTER Filter;
PVOID Cookie;
ULONG Flags;
LONG NumberOfConnections;
LONG MaxConnections;
} FLT_SERVER_PORT_OBJECT, *PFLT_SERVER_PORT_OBJECT;
参考FltCreateCommunicationPort函数实现代码片段
/* Insert the object */
Status = ObInsertObject(PortObject,
NULL,
STANDARD_RIGHTS_ALL | FILE_READ_DATA,
0,
NULL,
(PHANDLE)ServerPort);
if (NT_SUCCESS(Status))
{
/* Lock the connection list */
ExAcquireFastMutex(&Filter->ConnectionList.mLock);
/* Add the new port object to the connection list and increment the count */
InsertTailList(&Filter->ConnectionList.mList, &PortObject->FilterLink);
Filter->ConnectionList.mCount++;
/* Unlock the connection list*/
ExReleaseFastMutex(&Filter->ConnectionList.mLock);
}