From 9e89ad1da0a4e482057b4afa8cac8633dcf59a32 Mon Sep 17 00:00:00 2001 From: JKornev <8bit.dosninja@gmail.com> Date: Fri, 30 Jul 2021 13:36:00 +0300 Subject: [PATCH] Added an ability to configure hiding processes over a registry --- Hidden/Configs.c | 6 ++++++ Hidden/Configs.h | 1 + Hidden/PsMonitor.c | 23 ++++++++++++++++++----- HiddenCLI/HiddenCLI.cpp | 6 +++--- HiddenCLI/Hide.cpp | 27 +++++++++++++++++++-------- 5 files changed, 47 insertions(+), 16 deletions(-) diff --git a/Hidden/Configs.c b/Hidden/Configs.c index 94a16cd..68850c1 100644 --- a/Hidden/Configs.c +++ b/Hidden/Configs.c @@ -12,6 +12,7 @@ typedef struct _HidConfigContext { UNICODE_STRING hideRegValues; UNICODE_STRING ignoreImages; UNICODE_STRING protectImages; + UNICODE_STRING hideImages; } HidConfigContext, *PHidConfigContext; PHidConfigContext g_configContext = NULL; @@ -59,6 +60,7 @@ NTSTATUS InitializeConfigs(PUNICODE_STRING RegistryPath) QueryAndAllocRegistryData(hkey, L"Hid_IgnoredImages", REG_MULTI_SZ, &config.ignoreImages, NULL); QueryAndAllocRegistryData(hkey, L"Hid_ProtectedImages", REG_MULTI_SZ, &config.protectImages, NULL); + QueryAndAllocRegistryData(hkey, L"Hid_HideImages", REG_MULTI_SZ, &config.hideImages, NULL); ZwClose(hkey); @@ -135,6 +137,9 @@ NTSTATUS CfgEnumConfigsTable(enum CfgMultiStringTables Table, CfgMultiStringCall case ProtectImagesTable: table = &g_configContext->protectImages; break; + case HideImagesTable: + table = &g_configContext->hideImages; + break; default: return STATUS_INVALID_VARIANT; } @@ -182,6 +187,7 @@ VOID ReleaseConfigContext(PHidConfigContext context) ReleaseRegistryData(&context->hideRegValues); ReleaseRegistryData(&context->ignoreImages); ReleaseRegistryData(&context->protectImages); + ReleaseRegistryData(&context->hideImages); } NTSTATUS GetRegistryDWORD(HANDLE hKey, LPCWSTR Value, PULONG Data, ULONG Default) diff --git a/Hidden/Configs.h b/Hidden/Configs.h index 72a0aab..243a9ea 100644 --- a/Hidden/Configs.h +++ b/Hidden/Configs.h @@ -15,6 +15,7 @@ enum CfgMultiStringTables { HideRegValuesTable, IgnoreImagesTable, ProtectImagesTable, + HideImagesTable, MaxTableEntries, }; diff --git a/Hidden/PsMonitor.c b/Hidden/PsMonitor.c index 84b538c..602be82 100644 --- a/Hidden/PsMonitor.c +++ b/Hidden/PsMonitor.c @@ -617,6 +617,18 @@ VOID LoadIgnoredRulesCallback(PUNICODE_STRING Str, PVOID Params) AddExcludedImage(&path, inherit, FALSE, &ruleId); } +VOID LoadHiddenRulesCallback(PUNICODE_STRING Str, PVOID Params) +{ + UNICODE_STRING path; + ULONG inherit; + PsRuleEntryId ruleId; + + UNREFERENCED_PARAMETER(Params); + + if (NT_SUCCESS(ParsePsConfigEntry(Str, &path, &inherit))) + AddHiddenImage(&path, inherit, FALSE, &ruleId); +} + NTSTATUS InitializePsMonitor(PDRIVER_OBJECT DriverObject) { const USHORT maxBufSize = 512; @@ -726,14 +738,15 @@ NTSTATUS InitializePsMonitor(PDRIVER_OBJECT DriverObject) return status; } - //TODO: load hidden config + // Load entries from the config + CfgEnumConfigsTable(HideImagesTable, &LoadHiddenRulesCallback, NULL); // Process table ExInitializeFastMutex(&g_processTableLock); KeInitializeGuardedMutex(&g_activeProcListLock); - status = InitializeProcessTable(CheckProcessFlags); + status = InitializeProcessTable(&CheckProcessFlags); if (!NT_SUCCESS(status)) { DestroyPsRuleListContext(g_excludeProcessRules); @@ -775,7 +788,7 @@ NTSTATUS InitializePsMonitor(PDRIVER_OBJECT DriverObject) // Register rocess create\destroy callback - status = PsSetCreateProcessNotifyRoutineEx(CreateProcessNotifyCallback, FALSE); + status = PsSetCreateProcessNotifyRoutineEx(&CreateProcessNotifyCallback, FALSE); if (!NT_SUCCESS(status)) { LogError("Error, process notify registartion failed with code:%08x", status); @@ -808,14 +821,14 @@ NTSTATUS DestroyPsMonitor() g_obRegCallback = NULL; } - PsSetCreateProcessNotifyRoutineEx(CreateProcessNotifyCallback, TRUE); + PsSetCreateProcessNotifyRoutineEx(&CreateProcessNotifyCallback, TRUE); DestroyPsRuleListContext(g_excludeProcessRules); DestroyPsRuleListContext(g_protectProcessRules); DestroyPsRuleListContext(g_hideProcessRules); ExAcquireFastMutex(&g_processTableLock); - ClearProcessTable(CleanupHiddenProcessCallback); + ClearProcessTable(&CleanupHiddenProcessCallback); ExReleaseFastMutex(&g_processTableLock); g_psMonitorInited = FALSE; diff --git a/HiddenCLI/HiddenCLI.cpp b/HiddenCLI/HiddenCLI.cpp index 92561c1..aaee7aa 100644 --- a/HiddenCLI/HiddenCLI.cpp +++ b/HiddenCLI/HiddenCLI.cpp @@ -55,7 +55,7 @@ bool PrintUsage(Arguments& args) L"commands:\n" L"\n" L" /state \n" - L" Enable or disable hidden\n" + L" Turn on\\off hidden\n" L"\n" L" /query state\n" L" Get enforcement state\n" @@ -70,13 +70,13 @@ bool PrintUsage(Arguments& args) L" Hide process by its PID\n" L"\n" L" /unhide all\n" - L" Unhide all filesystem or registry object by selected type\n" + L" Unhide all filesystem, registry or process object by selected type\n" L"\n" L" /unhide <%ruleid%>\n" L" Unhide all filesystem or registry object by selected type and rule ID\n" L"\n" L" /unhide pid <%pid%>\n" - L" Unhide a specific process by it's PID\n" + L" Unhide a specific process by PID\n" L"\n" L" /ignore image [inherit:] [apply:] <%path%>\n" L" Set rule that allows to see hidden filesystem and registry objects for\n" diff --git a/HiddenCLI/Hide.cpp b/HiddenCLI/Hide.cpp index d4da786..221734d 100644 --- a/HiddenCLI/Hide.cpp +++ b/HiddenCLI/Hide.cpp @@ -123,36 +123,46 @@ void CommandHide::InstallCommand(RegistryKey& configKey) vector commands; const wchar_t* valueName; HidStatus status; - wstring entry; + wstring entry, normilized; - entry.insert(0, m_path.size() + HID_NORMALIZATION_OVERHEAD, L'\0'); + normilized.insert(0, m_path.size() + HID_NORMALIZATION_OVERHEAD, L'\0'); switch (m_hideType) { case EObjTypes::TypeFile: valueName = L"Hid_HideFsFiles"; - status = Hid_NormalizeFilePath(m_path.c_str(), const_cast(entry.c_str()), entry.size()); + status = Hid_NormalizeFilePath(m_path.c_str(), const_cast(normilized.c_str()), normilized.size()); break; case EObjTypes::TypeDir: valueName = L"Hid_HideFsDirs"; - status = Hid_NormalizeFilePath(m_path.c_str(), const_cast(entry.c_str()), entry.size()); + status = Hid_NormalizeFilePath(m_path.c_str(), const_cast(normilized.c_str()), normilized.size()); break; case EObjTypes::TypeRegKey: valueName = L"Hid_HideRegKeys"; - status = Hid_NormalizeRegistryPath(m_regRootType, m_path.c_str(), const_cast(entry.c_str()), entry.size()); + status = Hid_NormalizeRegistryPath(m_regRootType, m_path.c_str(), const_cast(normilized.c_str()), normilized.size()); break; case EObjTypes::TypeRegVal: valueName = L"Hid_HideRegValues"; - status = Hid_NormalizeRegistryPath(m_regRootType, m_path.c_str(), const_cast(entry.c_str()), entry.size()); + status = Hid_NormalizeRegistryPath(m_regRootType, m_path.c_str(), const_cast(normilized.c_str()), normilized.size()); break; case EObjTypes::TypePsImg: - valueName = L"Hid_HidePsImages"; - status = Hid_NormalizeFilePath(m_image.c_str(), const_cast(entry.c_str()), entry.size()); + valueName = L"Hid_HideImages"; + status = Hid_NormalizeFilePath(m_image.c_str(), const_cast(normilized.c_str()), normilized.size()); break; default: throw WException(ERROR_UNKNOWN_COMPONENT, L"Internal error, invalid type for command 'hide'"); } + if (!HID_STATUS_SUCCESSFUL(status)) + throw WException(HID_STATUS_CODE(status), L"Error, can't normalize path, 'hide' rejected"); + + entry += normilized.c_str(); + if (m_hideType == EObjTypes::TypePsImg) + { + entry += L";"; + entry += ConvertInheritTypeToUnicode(m_inheritType); + } + configKey.GetMultiStrValue(valueName, commands); commands.push_back(entry); configKey.SetMultiStrValue(valueName, commands); @@ -168,6 +178,7 @@ void CommandHide::UninstallCommand(RegistryKey& configKey) try { configKey.RemoveValue(L"Hid_HideFsDirs"); } catch (...) { errors++; } try { configKey.RemoveValue(L"Hid_HideRegKeys"); } catch (...) { errors++; } try { configKey.RemoveValue(L"Hid_HideRegValues"); } catch (...) { errors++; } + try { configKey.RemoveValue(L"Hid_HideImages"); } catch (...) { errors++; } if (errors < 4) g_stderr << L"Uninstall 'hide' successful" << endl;