#include "precomp.h" static BOOLEAN g_RegFlter = FALSE; #define REG_TAG 'Reg1' typedef struct _REG_CONTEXT { PDRIVER_OBJECT DriverObject; UNICODE_STRING Altitude; LARGE_INTEGER Cookie; }REG_CONTEXT, * PREG_CONTEXT; REG_CONTEXT g_RegContext = { 0 }; LPCWSTR GetNotifyClassString( _In_ REG_NOTIFY_CLASS NotifyClass ) /*++ Routine Description: Converts from NotifyClass to a string Arguments: NotifyClass - value that identifies the type of registry operation that is being performed Return Value: Returns a string of the name of NotifyClass. --*/ { switch (NotifyClass) { case RegNtPreDeleteKey: return L"RegNtPreDeleteKey"; case RegNtPreSetValueKey: return L"RegNtPreSetValueKey"; case RegNtPreDeleteValueKey: return L"RegNtPreDeleteValueKey"; case RegNtPreSetInformationKey: return L"RegNtPreSetInformationKey"; case RegNtPreRenameKey: return L"RegNtPreRenameKey"; case RegNtPreEnumerateKey: return L"RegNtPreEnumerateKey"; case RegNtPreEnumerateValueKey: return L"RegNtPreEnumerateValueKey"; case RegNtPreQueryKey: return L"RegNtPreQueryKey"; case RegNtPreQueryValueKey: return L"RegNtPreQueryValueKey"; case RegNtPreQueryMultipleValueKey: return L"RegNtPreQueryMultipleValueKey"; case RegNtPreKeyHandleClose: return L"RegNtPreKeyHandleClose"; case RegNtPreCreateKeyEx: return L"RegNtPreCreateKeyEx"; case RegNtPreOpenKeyEx: return L"RegNtPreOpenKeyEx"; case RegNtPreFlushKey: return L"RegNtPreFlushKey"; case RegNtPreLoadKey: return L"RegNtPreLoadKey"; case RegNtPreUnLoadKey: return L"RegNtPreUnLoadKey"; case RegNtPreQueryKeySecurity: return L"RegNtPreQueryKeySecurity"; case RegNtPreSetKeySecurity: return L"RegNtPreSetKeySecurity"; case RegNtPreRestoreKey: return L"RegNtPreRestoreKey"; case RegNtPreSaveKey: return L"RegNtPreSaveKey"; case RegNtPreReplaceKey: return L"RegNtPreReplaceKey"; case RegNtPostDeleteKey: return L"RegNtPostDeleteKey"; case RegNtPostSetValueKey: return L"RegNtPostSetValueKey"; case RegNtPostDeleteValueKey: return L"RegNtPostDeleteValueKey"; case RegNtPostSetInformationKey: return L"RegNtPostSetInformationKey"; case RegNtPostRenameKey: return L"RegNtPostRenameKey"; case RegNtPostEnumerateKey: return L"RegNtPostEnumerateKey"; case RegNtPostEnumerateValueKey: return L"RegNtPostEnumerateValueKey"; case RegNtPostQueryKey: return L"RegNtPostQueryKey"; case RegNtPostQueryValueKey: return L"RegNtPostQueryValueKey"; case RegNtPostQueryMultipleValueKey: return L"RegNtPostQueryMultipleValueKey"; case RegNtPostKeyHandleClose: return L"RegNtPostKeyHandleClose"; case RegNtPostCreateKeyEx: return L"RegNtPostCreateKeyEx"; case RegNtPostOpenKeyEx: return L"RegNtPostOpenKeyEx"; case RegNtPostFlushKey: return L"RegNtPostFlushKey"; case RegNtPostLoadKey: return L"RegNtPostLoadKey"; case RegNtPostUnLoadKey: return L"RegNtPostUnLoadKey"; case RegNtPostQueryKeySecurity: return L"RegNtPostQueryKeySecurity"; case RegNtPostSetKeySecurity: return L"RegNtPostSetKeySecurity"; case RegNtPostRestoreKey: return L"RegNtPostRestoreKey"; case RegNtPostSaveKey: return L"RegNtPostSaveKey"; case RegNtPostReplaceKey: return L"RegNtPostReplaceKey"; case RegNtCallbackObjectContextCleanup: return L"RegNtCallbackObjectContextCleanup"; default: return L"Unsupported REG_NOTIFY_CLASS"; } } NTSTATUS RegFltCallback( __in PVOID CallbackContext, __in_opt PVOID Argument1, __in_opt PVOID Argument2 ) /*++ Routine Description: This is the registry callback we'll register to intercept all registry operations. Arguments: CallbackContext - The value that the driver passed to the Context parameter of CmRegisterCallbackEx when it registers this callback routine. Argument1 - A REG_NOTIFY_CLASS typed value that identifies the type of registry operation that is being performed and whether the callback is being called in the pre or post phase of processing. Argument2 - A pointer to a structure that contains information specific to the type of the registry operation. The structure type depends on the REG_NOTIFY_CLASS value of Argument1. Refer to MSDN for the mapping from REG_NOTIFY_CLASS to REG_XXX_KEY_INFORMATION. Return Value: Status returned from the helper callback routine or STATUS_SUCCESS if the registry operation did not originate from this process. --*/ { NTSTATUS Status = STATUS_SUCCESS; REG_NOTIFY_CLASS NotifyClass; //KPROCESSOR_MODE Mode = KernelMode; //PREG_PRE_OPEN_KEY_INFORMATION PreOpenKeyInfo; //PREG_POST_OPEN_KEY_INFORMATION PostOpenKeyInfo; //PREG_OPEN_KEY_INFORMATION PreOpenKeyInfoEx; PREG_POST_OPERATION_INFORMATION PostOpenKeyInfoEx; PREG_OPEN_KEY_INFORMATION PostPreOpenKeyInfoEx; WCHAR wszRegName[MAX_PATH] = { 0, }; CHAR process_name[50] = { 0, }; UNREFERENCED_PARAMETER(CallbackContext); UNREFERENCED_PARAMETER(Argument1); UNREFERENCED_PARAMETER(Argument2); NotifyClass = (REG_NOTIFY_CLASS)(ULONG_PTR)Argument1; //GetProcessName(process_name, (DWORD)PsGetCurrentProcessId()); if (!g_bs1Flt.IsRegProtect) { return Status; } UGetProcessName(process_name); if (!IsDefalutExceptRegProcess(process_name)) { //KLogEx(DEBUG_TRACE_INFO, "monitor (%s)\n", process_name); return Status; } else { } if (Argument2 != NULL) { KLogEx(DEBUG_TRACE_INFO, "NotifyClass-%S.\n", GetNotifyClassString(NotifyClass)); switch (NotifyClass) { /* case RegNtPreOpenKey: SHOW_DEBUG(("RegNtPreOpenKey!!")); PreOpenKeyInfo = (PREG_PRE_OPEN_KEY_INFORMATION)Argument2; if(PreOpenKeyInfo->CompleteName != NULL) SHOW_DEBUG(("PreOpenKeyInfo.CompleteName %wZ!!",PreOpenKeyInfo->CompleteName)); break; case RegNtPostOpenKey: SHOW_DEBUG(("RegNtPostOpenKey!!")); PostOpenKeyInfo = (PREG_POST_OPEN_KEY_INFORMATION)Argument2; if(PostOpenKeyInfo->CompleteName != NULL) SHOW_DEBUG(("PostOpenKeyInfo->CompleteName %wZ!!",PostOpenKeyInfo->CompleteName)); break; case RegNtPreOpenKeyEx: SHOW_DEBUG(("RegNtPreOpenKeyEx!!")); RtlInitUnicodeString(&KeyName, L"SOFTWARE\\KINGS\\KCD"); RtlInitUnicodeString(&KeyName2, L"SOFTWARE\\KINGS\\GuardZone"); PreOpenKeyInfoEx = (PREG_OPEN_KEY_INFORMATION)Argument2; if(PreOpenKeyInfoEx->CompleteName != NULL) { SHOW_DEBUG(("PreOpenKeyInfoEx->CompleteName [%wZ]!!",PreOpenKeyInfoEx->CompleteName)); if( (RtlEqualUnicodeString((PCUNICODE_STRING)&KeyName, (PCUNICODE_STRING)PreOpenKeyInfoEx->CompleteName, TRUE) == TRUE) || (RtlEqualUnicodeString((PCUNICODE_STRING)&KeyName, (PCUNICODE_STRING)PreOpenKeyInfoEx->CompleteName, TRUE) == TRUE) ) { SHOW_DEBUG(("°¡µåÁ¸ ·¹Áö½ºÆ®¸®¿¡ Á¢±ÙÇÏ¿© Â÷´ÜÇÔ!")); PreOpenKeyInfoEx->DesiredAccess = 0; return Status; } } break; */ case RegNtPostOpenKeyEx: PostOpenKeyInfoEx = (PREG_POST_OPERATION_INFORMATION)Argument2; if (PostOpenKeyInfoEx->Status == STATUS_OBJECT_NAME_NOT_FOUND) //. PreOpen-PostOpenÀÇ µ¿ÀÛ¿¡ ´ëÇÑ Status { KLogEx(DEBUG_TRACE_INFO, "Operation did not fail with status not found as expected. Post status: 0x%x\n", PostOpenKeyInfoEx->Status); break; } PostPreOpenKeyInfoEx = (PREG_OPEN_KEY_INFORMATION)(PostOpenKeyInfoEx->PreInformation); if (!PostPreOpenKeyInfoEx) break; if (!PostPreOpenKeyInfoEx->CompleteName) break; KLogEx(DEBUG_TRACE_INFO, "PostPreOpenKeyInfoEx, Length[%d] MaximumLength [%d]\n", PostPreOpenKeyInfoEx->CompleteName->Length, PostPreOpenKeyInfoEx->CompleteName->MaximumLength); if (PostPreOpenKeyInfoEx->CompleteName->Length < sizeof(WCHAR) * MAX_PATH) { memcpy(wszRegName, PostPreOpenKeyInfoEx->CompleteName->Buffer, PostPreOpenKeyInfoEx->CompleteName->Length); KLogEx(DEBUG_TRACE_INFO, "PostPreOpenKeyInfoEx, wszRegName[%S]\n", wszRegName); if (IsRegKey(wszRegName)) { if (!IsDefalutExceptRegProcess(process_name)) { KLogEx(DEBUG_TRACE_INFO, "monitor (%s)\n", process_name); return Status; } else { } KLogEx(DEBUG_TRACE_INFO, "PostPreOpenKeyInfoEx regdit access denined (%S)\n", wszRegName); PostOpenKeyInfoEx->ReturnStatus = STATUS_ACCESS_DENIED; return Status; } } break; default: break; } } return Status; } NTSTATUS StartRegFlt(__in PDRIVER_OBJECT DriverObject) { NTSTATUS Status = STATUS_SUCCESS; //LARGE_INTEGER Cookie; //UNICODE_STRING Altitude; UNREFERENCED_PARAMETER(DriverObject); if (g_RegFlter) { g_bs1Flt.IsRegProtect = TRUE; return STATUS_SUCCESS; } SetRegKeylist(REG_BS1_REGPATH_KEY_W); SetRegKeylist(REG_BS1_REGPATH_KEY_W_64); //SetRegKeylist(REG_BS1_ASSETID_REGPATH_KEY_W); //SetRegKeylist(REG_BS1_ASSETID_REGPATH_KEY_W_64); //SetRegKeylist(REG_MINIMAL_SAFEMODE_BS1SERVICE_KEY_W); //SetRegKeylist(REG_NETWORK_SAFEMODE_BS1SERVICE_KEY_W); //SetRegKeylist(REG_MINIMAL_SAFEMODE_BS1FLT_KEY_W); //SetRegKeylist(REG_NETWORK_SAFEMODE_BS1FLT_KEY_W); RtlInitUnicodeString(&g_RegContext.Altitude, REG_ALTITUDE); KLogEx(DEBUG_TRACE_INFO, "DriverObject(%p)\n", DriverObject); g_RegContext.DriverObject = DriverObject; Status = CmRegisterCallbackEx(RegFltCallback, &g_RegContext.Altitude, DriverObject, &g_RegContext, &g_RegContext.Cookie, NULL); if (!NT_SUCCESS(Status)) { KLogEx(DEBUG_TRACE_INFO, "CmRegisterCallback failed. Status 0x%x\n", Status); } else { g_RegFlter = TRUE; g_bs1Flt.IsRegProtect = TRUE; KLogEx(DEBUG_TRACE_INFO, "CmRegisterCallback succeeded\n"); } return Status; } VOID StopRegFlt() { NTSTATUS Status; if (!NT_SUCCESS(Status = CmUnRegisterCallback(g_RegContext.Cookie))) { KLogEx(DEBUG_TRACE_INFO, "CmUnRegisterCallback Failed (%x)\n", Status); return; } else { KLogEx(DEBUG_TRACE_INFO, "CmUnRegisterCallback succeeded\n"); } CleanupRegKeylist(); g_RegFlter = FALSE; g_bs1Flt.IsRegProtect = TRUE; }