Improved support of the HKLM\System\CurrentControlSet tree

This commit is contained in:
JKornev 2017-04-02 03:06:55 +03:00
parent fe8bd1ed45
commit 5b3cf5932f
4 changed files with 154 additions and 30 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -7,6 +7,7 @@
#include "PsMonitor.h"
#include "Configs.h"
#include "Driver.h"
#include <Ntstrsafe.h>
#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)