diff --git a/Hidden/ExcludeList.c b/Hidden/ExcludeList.c index 60568bf..bb7606e 100644 --- a/Hidden/ExcludeList.c +++ b/Hidden/ExcludeList.c @@ -12,6 +12,7 @@ typedef struct _EXCULE_FILE_PATH { typedef struct _EXCLUDE_FILE_LIST_ENTRY { LIST_ENTRY list; ULONGLONG guid; + ULONGLONG parentGuid; EXCULE_FILE_PATH path; } EXCLUDE_FILE_LIST_ENTRY, *PEXCLUDE_FILE_LIST_ENTRY; @@ -19,10 +20,11 @@ typedef struct _EXCLUDE_FILE_CONTEXT { LIST_ENTRY listHead; FAST_MUTEX listLock; ULONGLONG guidCounter; + UINT32 childCounter; UINT32 type; } EXCLUDE_FILE_CONTEXT, *PEXCLUDE_FILE_CONTEXT; -NTSTATUS AddExcludeListEntry(ExcludeContext Context, PUNICODE_STRING FilePath, UINT32 Type, PExcludeEntryId EntryId); +NTSTATUS AddExcludeListEntry(ExcludeContext Context, PUNICODE_STRING FilePath, UINT32 Type, PExcludeEntryId EntryId, ExcludeEntryId ParentId); BOOLEAN FillDirectoryFromPath(PEXCULE_FILE_PATH path, PUNICODE_STRING filePath); @@ -56,6 +58,7 @@ NTSTATUS InitializeExcludeListContext(PExcludeContext Context, UINT32 Type) InitializeListHead(&cntx->listHead); ExInitializeFastMutex(&cntx->listLock); cntx->guidCounter = 1; + cntx->childCounter = 0; cntx->type = Type; *Context = cntx; @@ -70,27 +73,27 @@ VOID DestroyExcludeListContext(ExcludeContext Context) ExFreePoolWithTag(cntx, EXCLUDE_ALLOC_TAG); } -NTSTATUS AddExcludeListFile(ExcludeContext Context, PUNICODE_STRING FilePath, PExcludeEntryId EntryId) +NTSTATUS AddExcludeListFile(ExcludeContext Context, PUNICODE_STRING FilePath, PExcludeEntryId EntryId, ExcludeEntryId ParentId) { - return AddExcludeListEntry(Context, FilePath, ExcludeFile, EntryId); + return AddExcludeListEntry(Context, FilePath, ExcludeFile, EntryId, ParentId); } -NTSTATUS AddExcludeListDirectory(ExcludeContext Context, PUNICODE_STRING DirPath, PExcludeEntryId EntryId) +NTSTATUS AddExcludeListDirectory(ExcludeContext Context, PUNICODE_STRING DirPath, PExcludeEntryId EntryId, ExcludeEntryId ParentId) { - return AddExcludeListEntry(Context, DirPath, ExcludeDirectory, EntryId); + return AddExcludeListEntry(Context, DirPath, ExcludeDirectory, EntryId, ParentId); } -NTSTATUS AddExcludeListRegistryKey(ExcludeContext Context, PUNICODE_STRING KeyPath, PExcludeEntryId EntryId) +NTSTATUS AddExcludeListRegistryKey(ExcludeContext Context, PUNICODE_STRING KeyPath, PExcludeEntryId EntryId, ExcludeEntryId ParentId) { - return AddExcludeListEntry(Context, KeyPath, ExcludeRegKey, EntryId); + return AddExcludeListEntry(Context, KeyPath, ExcludeRegKey, EntryId, ParentId); } -NTSTATUS AddExcludeListRegistryValue(ExcludeContext Context, PUNICODE_STRING ValuePath, PExcludeEntryId EntryId) +NTSTATUS AddExcludeListRegistryValue(ExcludeContext Context, PUNICODE_STRING ValuePath, PExcludeEntryId EntryId, ExcludeEntryId ParentId) { - return AddExcludeListEntry(Context, ValuePath, ExcludeRegValue, EntryId); + return AddExcludeListEntry(Context, ValuePath, ExcludeRegValue, EntryId, ParentId); } -NTSTATUS AddExcludeListEntry(ExcludeContext Context, PUNICODE_STRING FilePath, UINT32 Type, PExcludeEntryId EntryId) +NTSTATUS AddExcludeListEntry(ExcludeContext Context, PUNICODE_STRING FilePath, UINT32 Type, PExcludeEntryId EntryId, ExcludeEntryId ParentId) { enum { MAX_PATH_SIZE = 1024 }; PEXCLUDE_FILE_CONTEXT cntx = (PEXCLUDE_FILE_CONTEXT)Context; @@ -98,8 +101,6 @@ NTSTATUS AddExcludeListEntry(ExcludeContext Context, PUNICODE_STRING FilePath, U UNICODE_STRING temp; SIZE_T size; - UNREFERENCED_PARAMETER(Type); - if (cntx->type != Type) { DbgPrint("FsFilter1!" __FUNCTION__ ": warning, type isn't equal: %d != %d\n", cntx->type, Type); @@ -156,10 +157,20 @@ NTSTATUS AddExcludeListEntry(ExcludeContext Context, PUNICODE_STRING FilePath, U { head = (PEXCLUDE_FILE_LIST_ENTRY)&cntx->listHead; } + + // Parent GUID is used when we want to link few entries in a group with one master, + // in this case parent GUID should be any valid entry GUID. When we remove parent entry + // all it's children will be removed too + entry->parentGuid = ParentId; ExAcquireFastMutex(&cntx->listLock); + + if (entry->parentGuid) + cntx->childCounter++; + entry->guid = cntx->guidCounter++; InsertTailList((PLIST_ENTRY)head, (PLIST_ENTRY)entry); + ExReleaseFastMutex(&cntx->listLock); *EntryId = entry->guid; @@ -188,6 +199,25 @@ NTSTATUS RemoveExcludeListEntry(ExcludeContext Context, ExcludeEntryId EntryId) entry = (PEXCLUDE_FILE_LIST_ENTRY)entry->list.Flink; } + + if (cntx->childCounter) + { + entry = (PEXCLUDE_FILE_LIST_ENTRY)cntx->listHead.Flink; + while (entry != (PEXCLUDE_FILE_LIST_ENTRY)&cntx->listHead) + { + PEXCLUDE_FILE_LIST_ENTRY remove = entry; + entry = (PEXCLUDE_FILE_LIST_ENTRY)entry->list.Flink; + + if (EntryId == remove->parentGuid) + { + ASSERT(cntx->childCounter > 0); + cntx->childCounter--; + RemoveEntryList((PLIST_ENTRY)remove); + ExFreePoolWithTag(remove, EXCLUDE_ALLOC_TAG); + } + + } + } ExReleaseFastMutex(&cntx->listLock); @@ -206,10 +236,17 @@ NTSTATUS RemoveAllExcludeListEntries(ExcludeContext Context) { PEXCLUDE_FILE_LIST_ENTRY remove = entry; entry = (PEXCLUDE_FILE_LIST_ENTRY)entry->list.Flink; + if (remove->parentGuid) + { + ASSERT(cntx->childCounter > 0); + cntx->childCounter--; + } RemoveEntryList((PLIST_ENTRY)remove); ExFreePoolWithTag(remove, EXCLUDE_ALLOC_TAG); } + ASSERT(cntx->childCounter == 0); + ExReleaseFastMutex(&cntx->listLock); return STATUS_SUCCESS; diff --git a/Hidden/ExcludeList.h b/Hidden/ExcludeList.h index 374cfe6..ce07089 100644 --- a/Hidden/ExcludeList.h +++ b/Hidden/ExcludeList.h @@ -23,10 +23,10 @@ typedef ExcludeEnumId* PExcludeEnumId; NTSTATUS InitializeExcludeListContext(PExcludeContext Context, UINT32 Type); VOID DestroyExcludeListContext(ExcludeContext Context); -NTSTATUS AddExcludeListFile(ExcludeContext Context, PUNICODE_STRING FilePath, PExcludeEntryId EntryId); -NTSTATUS AddExcludeListDirectory(ExcludeContext Context, PUNICODE_STRING DirPath, PExcludeEntryId EntryId); -NTSTATUS AddExcludeListRegistryKey(ExcludeContext Context, PUNICODE_STRING KeyPath, PExcludeEntryId EntryId); -NTSTATUS AddExcludeListRegistryValue(ExcludeContext Context, PUNICODE_STRING ValuePath, PExcludeEntryId EntryId); +NTSTATUS AddExcludeListFile(ExcludeContext Context, PUNICODE_STRING FilePath, PExcludeEntryId EntryId, ExcludeEntryId ParentId); +NTSTATUS AddExcludeListDirectory(ExcludeContext Context, PUNICODE_STRING DirPath, PExcludeEntryId EntryId, ExcludeEntryId ParentId); +NTSTATUS AddExcludeListRegistryKey(ExcludeContext Context, PUNICODE_STRING KeyPath, PExcludeEntryId EntryId, ExcludeEntryId ParentId); +NTSTATUS AddExcludeListRegistryValue(ExcludeContext Context, PUNICODE_STRING ValuePath, PExcludeEntryId EntryId, ExcludeEntryId ParentId); NTSTATUS RemoveExcludeListEntry(ExcludeContext Context, ExcludeEntryId EntryId); NTSTATUS RemoveAllExcludeListEntries(ExcludeContext Context); diff --git a/Hidden/FsFilter.c b/Hidden/FsFilter.c index c030150..a1c4d3a 100644 --- a/Hidden/FsFilter.c +++ b/Hidden/FsFilter.c @@ -783,7 +783,7 @@ NTSTATUS InitializeFSMiniFilter(PDRIVER_OBJECT DriverObject) for (i = 0; g_excludeFiles[i]; i++) { RtlInitUnicodeString(&str, g_excludeFiles[i]); - AddExcludeListFile(g_excludeFileContext, &str, &id); + AddExcludeListFile(g_excludeFileContext, &str, &id, 0); } CfgEnumConfigsTable(HideFilesTable, &LoadConfigFilesCallback, NULL); @@ -799,7 +799,7 @@ NTSTATUS InitializeFSMiniFilter(PDRIVER_OBJECT DriverObject) for (i = 0; g_excludeDirs[i]; i++) { RtlInitUnicodeString(&str, g_excludeDirs[i]); - AddExcludeListDirectory(g_excludeDirectoryContext, &str, &id); + AddExcludeListDirectory(g_excludeDirectoryContext, &str, &id, 0); } CfgEnumConfigsTable(HideDirsTable, &LoadConfigDirsCallback, NULL); @@ -871,7 +871,7 @@ NTSTATUS AddHiddenFile(PUNICODE_STRING FilePath, PULONGLONG ObjId) } DbgPrint("FsFilter1!" __FUNCTION__ ": add file:%wZ\n", &normalized); - status = AddExcludeListFile(g_excludeFileContext, &normalized, ObjId); + status = AddExcludeListFile(g_excludeFileContext, &normalized, ObjId, 0); ExFreePoolWithTag(normalized.Buffer, FSFILTER_ALLOC_TAG); @@ -913,7 +913,7 @@ NTSTATUS AddHiddenDir(PUNICODE_STRING DirPath, PULONGLONG ObjId) } DbgPrint("FsFilter1!" __FUNCTION__ ": add dir:%wZ\n", &normalized); - status = AddExcludeListDirectory(g_excludeDirectoryContext, &normalized, ObjId); + status = AddExcludeListDirectory(g_excludeDirectoryContext, &normalized, ObjId, 0); ExFreePoolWithTag(normalized.Buffer, FSFILTER_ALLOC_TAG); return status; diff --git a/Hidden/RegFilter.c b/Hidden/RegFilter.c index e46fe31..52e9262 100644 --- a/Hidden/RegFilter.c +++ b/Hidden/RegFilter.c @@ -7,6 +7,7 @@ #include "PsMonitor.h" #include "Configs.h" #include "Driver.h" +#include #define FILTER_ALLOC_TAG 'FRlF' @@ -600,18 +601,84 @@ NTSTATUS RegistryFilterCallback(PVOID CallbackContext, PVOID Argument1, PVOID Ar return status; } +NTSTATUS AddCurrentControlSetVariants(PUNICODE_STRING KeyPath, ExcludeContext Context, ULONGLONG ObjId, + NTSTATUS(*AddRoutine)(ExcludeContext, PUNICODE_STRING, PExcludeEntryId, ExcludeEntryId)) +{ + UNICODE_STRING currVersion, currVersionXXX, tail; + ULONGLONG objIds[2]; + NTSTATUS status; + BOOLEAN tailed; + + RtlInitUnicodeString(&currVersion, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet"); + if (!RtlPrefixUnicodeString(&currVersion, KeyPath, TRUE)) + return STATUS_SUCCESS; + + tailed = (KeyPath->Length >= currVersion.Length + sizeof(WCHAR)); + + // Does the path contain a valid CurrentControlSet\\ and not CurrentControlXYZ... ? + if (tailed && KeyPath->Buffer[currVersion.Length / sizeof(WCHAR)] != L'\\') + return STATUS_SUCCESS; + + currVersionXXX.Buffer = (LPWSTR)ExAllocatePoolWithTag(NonPagedPool, KeyPath->Length, FILTER_ALLOC_TAG); + currVersionXXX.Length = 0; + currVersionXXX.MaximumLength = KeyPath->Length; + + if (!currVersionXXX.Buffer) + return STATUS_NO_MEMORY; + + __try + { + // ControlSet001 + + if (tailed) + { + tail.Buffer = KeyPath->Buffer + (currVersion.Length / sizeof(WCHAR)) + 1; + tail.MaximumLength = tail.Length = KeyPath->Length - currVersion.Length - sizeof(WCHAR); + RtlUnicodeStringPrintf(&currVersionXXX, L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet001\\%wZ", &tail); + } + else + { + RtlInitUnicodeString(&currVersionXXX, L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet001"); + } + + status = AddRoutine(Context, &currVersionXXX, &objIds[0], ObjId); + if (!NT_SUCCESS(status)) + return status; + + // ControlSet002 + + if (tailed) + RtlUnicodeStringPrintf(&currVersionXXX, L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet002\\%wZ", &tail); + else + RtlInitUnicodeString(&currVersionXXX, L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet002"); + + status = AddRoutine(Context, &currVersionXXX, &objIds[1], ObjId); + if (!NT_SUCCESS(status)) + { + RemoveExcludeListEntry(Context, objIds[0]); + return status; + } + } + __finally + { + ExFreePoolWithTag(currVersionXXX.Buffer, FILTER_ALLOC_TAG); + } + + return STATUS_SUCCESS; +} + VOID LoadConfigRegKeysCallback(PUNICODE_STRING Str, PVOID Params) { - ExcludeContext context = (ExcludeContext)Params; ExcludeEntryId id; - AddExcludeListRegistryKey(context, Str, &id); + UNREFERENCED_PARAMETER(Params); + AddHiddenRegKey(Str, &id); } VOID LoadConfigRegValuesCallback(PUNICODE_STRING Str, PVOID Params) { - ExcludeContext context = (ExcludeContext)Params; ExcludeEntryId id; - AddExcludeListRegistryValue(context, Str, &id); + UNREFERENCED_PARAMETER(Params); + AddHiddenRegValue(Str, &id); } NTSTATUS InitializeRegistryFilter(PDRIVER_OBJECT DriverObject) @@ -633,10 +700,10 @@ NTSTATUS InitializeRegistryFilter(PDRIVER_OBJECT DriverObject) for (i = 0; g_excludeRegKeys[i]; i++) { RtlInitUnicodeString(&str, g_excludeRegKeys[i]); - AddExcludeListRegistryKey(g_excludeRegKeyContext, &str, &id); + AddHiddenRegKey(&str, &id); } - CfgEnumConfigsTable(HideRegKeysTable, &LoadConfigRegKeysCallback, g_excludeRegKeyContext); + CfgEnumConfigsTable(HideRegKeysTable, &LoadConfigRegKeysCallback, NULL); status = InitializeExcludeListContext(&g_excludeRegValueContext, ExcludeRegValue); if (!NT_SUCCESS(status)) @@ -649,10 +716,10 @@ NTSTATUS InitializeRegistryFilter(PDRIVER_OBJECT DriverObject) for (i = 0; g_excludeRegValues[i]; i++) { RtlInitUnicodeString(&str, g_excludeRegValues[i]); - AddExcludeListRegistryValue(g_excludeRegValueContext, &str, &id); + AddHiddenRegValue(&str, &id); } - CfgEnumConfigsTable(HideRegValuesTable, &LoadConfigRegValuesCallback, g_excludeRegValueContext); + CfgEnumConfigsTable(HideRegValuesTable, &LoadConfigRegValuesCallback, NULL); // Register registry filter @@ -692,7 +759,17 @@ NTSTATUS DestroyRegistryFilter() NTSTATUS AddHiddenRegKey(PUNICODE_STRING KeyPath, PULONGLONG ObjId) { - return AddExcludeListRegistryKey(g_excludeRegKeyContext, KeyPath, ObjId); + NTSTATUS status; + + status = AddExcludeListRegistryKey(g_excludeRegKeyContext, KeyPath, ObjId, 0); + if (NT_SUCCESS(status)) + { + status = AddCurrentControlSetVariants(KeyPath, g_excludeRegKeyContext, *ObjId, &AddExcludeListRegistryKey); + if (!NT_SUCCESS(status)) + RemoveHiddenRegKey(*ObjId); + } + + return status; } NTSTATUS RemoveHiddenRegKey(ULONGLONG ObjId) @@ -707,7 +784,17 @@ NTSTATUS RemoveAllHiddenRegKeys() NTSTATUS AddHiddenRegValue(PUNICODE_STRING ValuePath, PULONGLONG ObjId) { - return AddExcludeListRegistryValue(g_excludeRegValueContext, ValuePath, ObjId); + NTSTATUS status; + + status = AddExcludeListRegistryValue(g_excludeRegValueContext, ValuePath, ObjId, 0); + if (NT_SUCCESS(status)) + { + status = AddCurrentControlSetVariants(ValuePath, g_excludeRegValueContext, *ObjId, &AddExcludeListRegistryValue); + if (!NT_SUCCESS(status)) + RemoveHiddenRegValue(*ObjId); + } + + return status; } NTSTATUS RemoveHiddenRegValue(ULONGLONG ObjId)