Win64 驱动内核编程-34.对抗与枚举MiniFilter
對抗與枚舉MiniFilter
????MiniFilter?是目前殺毒軟件用來實現“文件系統自我保護”和“文件實時監控”的方法。
由于?MiniFilter?模型簡單,開發快捷,通用性好,以前用?FSD?HOOK?或者標準過濾驅動來實現相關功能的殺軟紛紛改用?MiniFilter,比如卡巴斯基。不過,枚舉?MiniFilter?就跟之前枚舉回調的方法不太相同了,因為?MiniFilter?的框架不在?NTOSKRNL?里,自成一套系統,有專用的?API。不過“自成一套系統,有專用?API”的好處就是,無需我們自己通過特征碼來定位數組或者鏈表,直接使用?MiniFilter?提供的?API?就行。
? ? 枚舉MiniFilter主要使用FltEnumerateFilters這個API,它會返回過濾器對象(FLT_FILTER)的地址,然后根據過濾器對象的地址,加上一個偏移,獲得記錄過濾器?PreCall、PostCall、IRP?等信息的結構體指針(PFLT_OPERATION_REGISTRATION)。上文之所以說要加上偏移,是因為?FLT_FILTER?的定義在每個系統都不同,比如?WIN7X64?中的定義為:
nt!DbgBreakPointWithStatus:
fffff800`03e74f60?cc??????????????int?????3
kd>?dt?fltmgr!_FLT_FILTER
???+0x000?Base?????????????:?_FLT_OBJECT
???+0x020?Frame????????????:?Ptr64?_FLTP_FRAME
???+0x028?Name?????????????:?_UNICODE_STRING
???+0x038?DefaultAltitude??:?_UNICODE_STRING
???+0x048?Flags????????????:?_FLT_FILTER_FLAGS
???+0x050?DriverObject?????:?Ptr64?_DRIVER_OBJECT
???+0x058?InstanceList?????:?_FLT_RESOURCE_LIST_HEAD
???+0x0d8?VerifierExtension?:?Ptr64?_FLT_VERIFIER_EXTENSION
???+0x0e0?VerifiedFiltersLink?:?_LIST_ENTRY
???+0x0f0?FilterUnload?????:?Ptr64?????long?
???+0x0f8?InstanceSetup????:?Ptr64?????long?
???+0x100?InstanceQueryTeardown?:?Ptr64?????long?
???+0x108?InstanceTeardownStart?:?Ptr64?????void?
???+0x110?InstanceTeardownComplete?:?Ptr64?????void?
???+0x118?SupportedContextsListHead?:?Ptr64?_ALLOCATE_CONTEXT_HEADER
???+0x120?SupportedContexts?:?[6]?Ptr64?_ALLOCATE_CONTEXT_HEADER
???+0x150?PreVolumeMount???:?Ptr64?????_FLT_PREOP_CALLBACK_STATUS?
???+0x158?PostVolumeMount??:?Ptr64?????_FLT_POSTOP_CALLBACK_STATUS?
???+0x160?GenerateFileName?:?Ptr64?????long?
???+0x168?NormalizeNameComponent?:?Ptr64?????long?
???+0x170?NormalizeNameComponentEx?:?Ptr64?????long?
???+0x178?NormalizeContextCleanup?:?Ptr64?????void?
???+0x180?KtmNotification??:?Ptr64?????long?
???+0x188?Operations???????:?Ptr64?_FLT_OPERATION_REGISTRATION
???+0x190?OldDriverUnload??:?Ptr64?????void?
???+0x198?ActiveOpens??????:?_FLT_MUTEX_LIST_HEAD
???+0x1e8?ConnectionList???:?_FLT_MUTEX_LIST_HEAD
???+0x238?PortList?????????:?_FLT_MUTEX_LIST_HEAD
???+0x288?PortLock?????????:?_EX_PUSH_LOCK
?
?FLT_OPERATION_REGISTRATION?的結構體定義是不變的:
?枚舉代碼如下:
?
#include <Fltkernel.h> ULONG FltFilterOperationsOffset=0x188; //WIN7 OFFSET of fltmgr!_FLT_FILTER->PFLT_OPERATION_REGISTRATION//typedef struct _FLT_OPERATION_REGISTRATION //{ //UCHARMajorFunction; //ULONGFlags; //PVOIDPreOperation; //PVOIDPostOperation; //PVOIDReserved1; //} FLT_OPERATION_REGISTRATION, *PFLT_OPERATION_REGISTRATION;typedef struct _FLT_FILTER { UCHAR buffer[1024]; } FLT_FILTER, *PFLT_FILTER;//NTSTATUS //__fastcall //FltEnumerateFilters //( // PFLT_FILTER *FilterList, // ULONG FilterListSize, // PULONG NumberFiltersReturned //); // //NTSTATUS //__fastcall //FltObjectDereference //( // PVOID FltObject //);ULONG EnumMiniFilter() { long ntStatus; ULONG uNumber; PVOID pBuffer = NULL; ULONG uIndex = 0, DrvCount = 0; PVOID pCallBacks = NULL, pFilter = NULL; PFLT_OPERATION_REGISTRATION pNode; do { if(pBuffer != NULL) { ExFreePool(pBuffer); pBuffer = NULL; } ntStatus = FltEnumerateFilters(NULL, 0, &uNumber); if(ntStatus != STATUS_BUFFER_TOO_SMALL) break; pBuffer = ExAllocatePoolWithTag(NonPagedPool, sizeof(PFLT_FILTER) * uNumber, 'mnft'); if(pBuffer == NULL) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; break; } ntStatus = FltEnumerateFilters(pBuffer, uNumber, &uNumber); } while (ntStatus == STATUS_BUFFER_TOO_SMALL); if(! NT_SUCCESS(ntStatus)) { if(pBuffer != NULL) ExFreePool(pBuffer); return 0; } DbgPrint("MiniFilter Count: %ld\n",uNumber); DbgPrint("------\n"); __try { while(DrvCount<uNumber) { pFilter = (PVOID)(*(PULONG64)((PUCHAR)pBuffer + DrvCount * 8)); pCallBacks = (PVOID)((PUCHAR)pFilter + FltFilterOperationsOffset); pNode = (PFLT_OPERATION_REGISTRATION)(*(PULONG64)pCallBacks); __try { while(pNode->MajorFunction != 0x80) //IRP_MJ_OPERATION_END { if(pNode->MajorFunction<28) //MajorFunction id is 0~27 { DbgPrint("Object=%p\tPreFunc=%p\tPostFunc=%p\tIRP=%d\n", pFilter, pNode->PreOperation, pNode->PostOperation, pNode->MajorFunction); } pNode++; } } __except(EXCEPTION_EXECUTE_HANDLER) { FltObjectDereference(pFilter); DbgPrint("[EnumMiniFilter]EXCEPTION_EXECUTE_HANDLER: pNode->MajorFunction\n"); ntStatus = GetExceptionCode(); ExFreePool(pBuffer); return uIndex; } DrvCount++; FltObjectDereference(pFilter); DbgPrint("------\n"); } } __except(EXCEPTION_EXECUTE_HANDLER) { FltObjectDereference(pFilter); DbgPrint("[EnumMiniFilter]EXCEPTION_EXECUTE_HANDLER\n"); ntStatus = GetExceptionCode(); ExFreePool(pBuffer); return uIndex; } if(pBuffer != NULL) { ExFreePool(pBuffer); ntStatus=STATUS_SUCCESS; } return uIndex;}?
?
?
執行結果:
不過對抗?MiniFilter?似乎就只有兩種方法了:
1.把記錄的函數地址改為自己設置的空函數;
2.把處理函數頭改為?RET?直接返回。?為什么不能把?直接把?MiniFilter??對象?反注冊呢?因為MSDN?對?對?FltUnregisterFilter??的?用途?給出了?這樣的解釋?:A?minifilter?driver?can?only?callFltUnregisterFilter?to?unregister?itself,?not?another?minifilter?driver。據我測試,如果第三方驅動強制使用此函數注銷一個?MiniFilter,輕則無效,重則藍屏。
把?MINIFILTER?的處理函數禁用掉之后,卡巴斯基?2013?在?WIN64?系統上的文件保護就徹底失效了,可以直接使用最簡單的方法來刪除卡巴斯基文件夾內的文件,國內那些采用同樣方法實現文件自我保護的殺毒軟件(****)同理。
宋孖健,13
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的Win64 驱动内核编程-34.对抗与枚举MiniFilter的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win64 驱动内核编程-33.枚举与删
- 下一篇: 13.PHP_ThinkPHP