321 lines
10 KiB
C
321 lines
10 KiB
C
#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);
|
||
///. 141014 <20><>å<EFBFBD>̳<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>μ<EFBFBD><CEBC><EFBFBD><EFBFBD><EFBFBD> <20>ƴϸ<C6B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʵ<EFBFBD><CAB5><EFBFBD> <20><>.
|
||
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(("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!"));
|
||
PreOpenKeyInfoEx->DesiredAccess = 0;
|
||
|
||
return Status;
|
||
}
|
||
}
|
||
|
||
break;
|
||
*/
|
||
|
||
case RegNtPostOpenKeyEx:
|
||
|
||
PostOpenKeyInfoEx = (PREG_POST_OPERATION_INFORMATION)Argument2;
|
||
|
||
if (PostOpenKeyInfoEx->Status == STATUS_OBJECT_NAME_NOT_FOUND) //. PreOpen-PostOpen<65><6E> <20><><EFBFBD>ۿ<EFBFBD> <20><><EFBFBD><EFBFBD> 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);
|
||
|
||
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)
|
||
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();
|
||
} |