Skip to content

Commit

Permalink
Improved support of the HKLM\System\CurrentControlSet tree
Browse files Browse the repository at this point in the history
  • Loading branch information
JKornev committed Apr 2, 2017
1 parent fe8bd1e commit 5b3cf59
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 30 deletions.
61 changes: 49 additions & 12 deletions Hidden/ExcludeList.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,19 @@ 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;

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

Expand Down Expand Up @@ -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;
Expand All @@ -70,36 +73,34 @@ 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;
PEXCLUDE_FILE_LIST_ENTRY entry, head;
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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions Hidden/ExcludeList.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions Hidden/FsFilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down
107 changes: 97 additions & 10 deletions Hidden/RegFilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "PsMonitor.h"
#include "Configs.h"
#include "Driver.h"
#include <Ntstrsafe.h>

#define FILTER_ALLOC_TAG 'FRlF'

Expand Down Expand Up @@ -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)
Expand All @@ -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))
Expand All @@ -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

Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down

0 comments on commit 5b3cf59

Please sign in to comment.