diff --git a/Anti-Rootkit/ARK.cpp b/Anti-Rootkit/ARK.cpp index 02346f3..392ca3b 100644 --- a/Anti-Rootkit/ARK.cpp +++ b/Anti-Rootkit/ARK.cpp @@ -1309,6 +1309,21 @@ NTSTATUS AntiRootkitDeviceControl(PDEVICE_OBJECT, PIRP Irp) { } break; } + + case IOCTL_ARK_REMOVE_MINIFILTER: + { + if (Irp->AssociatedIrp.SystemBuffer == nullptr) { + status = STATUS_INVALID_PARAMETER; + break; + } + if (dic.InputBufferLength < sizeof(MiniFilterData)) { + status = STATUS_INVALID_BUFFER_SIZE; + break; + } + MiniFilterData* pData = (MiniFilterData*)Irp->AssociatedIrp.SystemBuffer; + status = RemoveMiniFilter(pData); + break; + } } Irp->IoStatus.Status = status; diff --git a/Anti-Rootkit/AntiRootkit.h b/Anti-Rootkit/AntiRootkit.h index e5f348d..73f3f57 100644 --- a/Anti-Rootkit/AntiRootkit.h +++ b/Anti-Rootkit/AntiRootkit.h @@ -45,7 +45,7 @@ Typical drivers just use FILE_ANY_ACCESS and deal with the actual request in the // 回调驱动 链接器 命令行 + -----> /integritycheck #define ANTI_ROOTKIT_DEVICE 0x8000 -#define DRIVER_CURRENT_VERSION 0xAB +#define DRIVER_CURRENT_VERSION 0xAD // 用MDL锁定用户内存 @@ -92,6 +92,8 @@ Typical drivers just use FILE_ANY_ACCESS and deal with the actual request in the #define IOCTL_ARK_ENUM_MINIFILTER_OPERATIONS CTL_CODE(ANTI_ROOTKIT_DEVICE,0x82A,METHOD_BUFFERED,FILE_ANY_ACCESS) #define IOCTL_ARK_BYPASS_DETECT CTL_CODE(ANTI_ROOTKIT_DEVICE,0x82B,METHOD_BUFFERED,FILE_ANY_ACCESS) #define IOCTL_ARK_UNBYPASS_DETECT CTL_CODE(ANTI_ROOTKIT_DEVICE,0x82C,METHOD_BUFFERED,FILE_ANY_ACCESS) +#define IOCTL_ARK_REMOVE_MINIFILTER CTL_CODE(ANTI_ROOTKIT_DEVICE,0x82D,METHOD_BUFFERED,FILE_ANY_ACCESS) + diff --git a/KernelLibrary/Common.h b/KernelLibrary/Common.h index 787430d..27cef75 100644 --- a/KernelLibrary/Common.h +++ b/KernelLibrary/Common.h @@ -172,6 +172,7 @@ struct IoTimerInfo { struct MiniFilterData { ULONG Length; ULONG OperationsOffset; + ULONG RundownRefOffset; WCHAR Name[1]; }; diff --git a/KernelLibrary/SysMon.cpp b/KernelLibrary/SysMon.cpp index cd1c02f..065debc 100644 --- a/KernelLibrary/SysMon.cpp +++ b/KernelLibrary/SysMon.cpp @@ -883,5 +883,63 @@ NTSTATUS EnumMiniFilterOperations(MiniFilterData* pData, OperationInfo* pInfo) { ExFreePoolWithTag(ppFltList, 'tsil'); + return status; +} + +NTSTATUS RemoveMiniFilter(MiniFilterData* pData) { + NTSTATUS status = STATUS_SUCCESS; + + WCHAR name[128] = { 0 }; + WCHAR filterName[128] = { 0 }; + if (pData->Length < sizeof(filterName) / sizeof(WCHAR)) { + RtlCopyMemory(name, pData->Name, pData->Length * sizeof(WCHAR)); + name[pData->Length] = L'\0'; + } + + ULONG filtersCount = 0; + ULONG size = 0; + ULONG offset = pData->RundownRefOffset; + PFILTER_FULL_INFORMATION pFullInfo = nullptr; + PFLT_FILTER* ppFltList = nullptr; + status = FltEnumerateFilters(nullptr, 0, &filtersCount); + if ((status == STATUS_BUFFER_TOO_SMALL) && filtersCount) { + size = sizeof(PFLT_FILTER) * filtersCount; + ppFltList = (PFLT_FILTER*)ExAllocatePoolWithTag(NonPagedPool, size, 'tsil'); + if (ppFltList) { + status = FltEnumerateFilters(ppFltList, size, &filtersCount); + for (decltype(filtersCount) i = 0; NT_SUCCESS(status) && (i < filtersCount); i++) { + status = FltGetFilterInformation(ppFltList[i], FilterFullInformation, nullptr, 0, &size); + if ((status == STATUS_BUFFER_TOO_SMALL) && size) { + pFullInfo = (PFILTER_FULL_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, size, 'ofni'); + if (pFullInfo) { + status = FltGetFilterInformation(ppFltList[i], FilterFullInformation, pFullInfo, size, + &size); + if (NT_SUCCESS(status)) { + if (pFullInfo->FilterNameLength < sizeof(filterName) / sizeof(WCHAR)) { + RtlCopyMemory(filterName, pFullInfo->FilterNameBuffer, pFullInfo->FilterNameLength); + filterName[pFullInfo->FilterNameLength / sizeof(WCHAR)] = L'\0'; + } + if (!_wcsicmp(filterName, name)) { + PEX_RUNDOWN_REF RunRefs = (PEX_RUNDOWN_REF)((char*)ppFltList[i] + offset); + ExReleaseRundownProtection(RunRefs); + FltUnregisterFilter(ppFltList[i]); + break; + } + } + ExFreePool(pFullInfo); + pFullInfo = nullptr; + } + } + } + ExFreePoolWithTag(ppFltList, 'tsil'); + ppFltList = nullptr; + } + } + if (pFullInfo != nullptr) + ExFreePool(pFullInfo); + + if (ppFltList != nullptr) + ExFreePoolWithTag(ppFltList, 'tsil'); + return status; } \ No newline at end of file diff --git a/KernelLibrary/SysMon.h b/KernelLibrary/SysMon.h index 7679589..ade56ba 100644 --- a/KernelLibrary/SysMon.h +++ b/KernelLibrary/SysMon.h @@ -189,3 +189,5 @@ using PPsSetCreateProcessNotifyRoutineEx2 = NTSTATUS ); NTSTATUS EnumMiniFilterOperations(MiniFilterData* pData, OperationInfo* pInfo); + +NTSTATUS RemoveMiniFilter(MiniFilterData* pData); diff --git a/WinArk/MiniFilterOperationTable.cpp b/WinArk/MiniFilterOperationTable.cpp index 7145452..70ebe4d 100644 --- a/WinArk/MiniFilterOperationTable.cpp +++ b/WinArk/MiniFilterOperationTable.cpp @@ -275,6 +275,8 @@ void COperationTable::Refresh() { data->Length = len; ::wcscpy_s(data->Name, len + 1, m_Name.c_str()); + DWORD dataSize = size; + int maxCount = IRP_MJ_MAXIMUM_FUNCTION + FLT_INTERNAL_OPERATION_COUNT; size = maxCount * sizeof(OperationInfo); wil::unique_virtualalloc_ptr<> buffer(::VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE)); @@ -282,7 +284,7 @@ void COperationTable::Refresh() { if (p != nullptr) { memset(p, 0, size); - DriverHelper::EnumMiniFilterOperations(data, p, size); + DriverHelper::EnumMiniFilterOperations(data, dataSize,p, size); for (int i = 0; (p->MajorFunction != IRP_MJ_OPERATION_END&& iPostOperation); diff --git a/WinArk/MiniFilterOperationTable.h b/WinArk/MiniFilterOperationTable.h index d2cbc35..10fce0d 100644 --- a/WinArk/MiniFilterOperationTable.h +++ b/WinArk/MiniFilterOperationTable.h @@ -48,6 +48,7 @@ public: MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) MESSAGE_HANDLER(WM_SYSKEYDOWN, OnSysKeyDown) //COMMAND_ID_HANDLER(ID_MINIFILTER_REFRESH, OnRefresh) + //COMMAND_ID_HANDLER(ID_MINIFILTER_REMOVE,OnRemove) END_MSG_MAP() LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/); @@ -72,6 +73,8 @@ public: //LRESULT OnPiDDBCacheExport(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); LRESULT OnRefresh(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + + PCWSTR OperationTypeToString(UCHAR type); CString FlagToString(DWORD flag); private: diff --git a/WinArk/MiniFilterTable.cpp b/WinArk/MiniFilterTable.cpp index 83b588e..6d6004a 100644 --- a/WinArk/MiniFilterTable.cpp +++ b/WinArk/MiniFilterTable.cpp @@ -4,6 +4,8 @@ #include "ClipboardHelper.h" #include #include "MiniFilterDlg.h" +#include "DriverHelper.h" +#include "SymbolHelper.h" #pragma comment(lib,"FltLib") @@ -255,3 +257,33 @@ LRESULT CMiniFilterTable::OnCallback(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /* return TRUE; } + +LRESULT CMiniFilterTable::OnRemove(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { + int selected = m_Table.data.selected; + ATLASSERT(selected >= 0); + auto& info = m_Table.data.info[selected]; + + auto len = info.FilterName.length(); + DWORD size = len * sizeof(WCHAR) + sizeof(MiniFilterData); + + auto pData = std::make_unique(size); + if (!pData) + return FALSE; + + ULONG offset = SymbolHelper::GetFltmgrStructMemberOffset("_FLT_OBJECT", "RundownRef"); + + auto data = reinterpret_cast(pData.get()); + data->OperationsOffset = 0; + data->RundownRefOffset = offset; + data->Length = len; + ::wcscpy_s(data->Name, len + 1, info.FilterName.c_str()); + + bool ok = DriverHelper::RemoveMiniFilter(data, size); + if (!ok) { + AtlMessageBox(m_hWnd, L"移除失败!", L"Error", MB_ICONERROR); + } + if (ok) { + Refresh(); + } + return TRUE; +} diff --git a/WinArk/MiniFilterTable.h b/WinArk/MiniFilterTable.h index 96747aa..71ac9b5 100644 --- a/WinArk/MiniFilterTable.h +++ b/WinArk/MiniFilterTable.h @@ -40,6 +40,7 @@ public: MESSAGE_HANDLER(WM_SYSKEYDOWN, OnSysKeyDown) COMMAND_ID_HANDLER(ID_MINIFILTER_REFRESH, OnRefresh) COMMAND_ID_HANDLER(ID_MINIFILTER_CALLBACK,OnCallback) + COMMAND_ID_HANDLER(ID_MINIFILTER_REMOVE,OnRemove) END_MSG_MAP() LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/); @@ -64,6 +65,7 @@ public: //LRESULT OnPiDDBCacheExport(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); LRESULT OnRefresh(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); LRESULT OnCallback(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnRemove(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); void BuildFilterInfo(PVOID buffer, bool isNewStyle); diff --git a/WinArk/WinArk.rc b/WinArk/WinArk.rc index 99a3ee0..1c0e2c5 100644 --- a/WinArk/WinArk.rc +++ b/WinArk/WinArk.rc @@ -873,6 +873,7 @@ BEGIN BEGIN MENUITEM "Refresh", ID_MINIFILTER_REFRESH MENUITEM "Callback", ID_MINIFILTER_CALLBACK + MENUITEM "Remove", ID_MINIFILTER_REMOVE END END diff --git a/WinArk/resource.h b/WinArk/resource.h index 4052cb8..da24b92 100644 --- a/WinArk/resource.h +++ b/WinArk/resource.h @@ -358,13 +358,14 @@ #define ID_SERVICE_UNINSTALL 32952 #define ID_SERVICE_ 32953 #define ID_SERVICE_PROPERTIES 32954 +#define ID_MINIFILTER_REMOVE 32955 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 279 -#define _APS_NEXT_COMMAND_VALUE 32955 +#define _APS_NEXT_COMMAND_VALUE 32956 #define _APS_NEXT_CONTROL_VALUE 1096 #define _APS_NEXT_SYMED_VALUE 101 #endif diff --git a/WinSysCore/DriverHelper.cpp b/WinSysCore/DriverHelper.cpp index 2febbd4..359f684 100644 --- a/WinSysCore/DriverHelper.cpp +++ b/WinSysCore/DriverHelper.cpp @@ -555,15 +555,24 @@ bool DriverHelper::DisableDbgSys() { nullptr, 0, &bytes, nullptr); } -bool DriverHelper::EnumMiniFilterOperations(MiniFilterData* pData, OperationInfo* pInfo, SIZE_T size) { +bool DriverHelper::EnumMiniFilterOperations(MiniFilterData* pData,SIZE_T dataSize, OperationInfo* pInfo, SIZE_T size) { if (!OpenDevice()) return false; DWORD bytes; - return ::DeviceIoControl(_hDevice, IOCTL_ARK_ENUM_MINIFILTER_OPERATIONS, pData, sizeof(KernelTimerData), + return ::DeviceIoControl(_hDevice, IOCTL_ARK_ENUM_MINIFILTER_OPERATIONS, pData, dataSize, pInfo, size, &bytes, nullptr); } +bool DriverHelper::RemoveMiniFilter(MiniFilterData* pData, SIZE_T dataSize) { + if (!OpenDevice()) + return false; + + DWORD bytes; + return ::DeviceIoControl(_hDevice, IOCTL_ARK_REMOVE_MINIFILTER, pData, dataSize, + nullptr, 0, &bytes, nullptr); +} + bool DriverHelper::Bypass(DWORD flag) { if (!OpenDevice()) return false; diff --git a/WinSysCore/DriverHelper.h b/WinSysCore/DriverHelper.h index 103e666..85ac8b9 100644 --- a/WinSysCore/DriverHelper.h +++ b/WinSysCore/DriverHelper.h @@ -45,7 +45,8 @@ struct DriverHelper final { static bool DisableDbgSys(); static bool EnumKernelTimer(KernelTimerData* pData,DpcTimerInfo* pInfo,SIZE_T size); static bool EnumIoTimer(IoTimerData* pData, IoTimerInfo* pInfo, SIZE_T size); - static bool EnumMiniFilterOperations(MiniFilterData* pData, OperationInfo* pInfo, SIZE_T size); + static bool EnumMiniFilterOperations(MiniFilterData* pData, SIZE_T dataSize,OperationInfo* pInfo, SIZE_T size); + static bool RemoveMiniFilter(MiniFilterData* pData, SIZE_T dataSize); static ULONG GetKernelTimerCount(KernelTimerData* pData); diff --git a/WinSysCore/KernelModuleTracker.cpp b/WinSysCore/KernelModuleTracker.cpp index fd4dc58..2ce0b71 100644 --- a/WinSysCore/KernelModuleTracker.cpp +++ b/WinSysCore/KernelModuleTracker.cpp @@ -4,6 +4,7 @@ using namespace WinSys; uint32_t WinSys::KernelModuleTracker::EnumModules() { + _modules.clear(); DWORD size = 1 << 18; wil::unique_virtualalloc_ptr<> buffer(::VirtualAlloc(nullptr, size,MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));