BSOne.SFC/Tocsg.Module/Bs1Flt/bs1flt/bs1flt_reg.c

326 lines
10 KiB
C
Raw Blame History

#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(("<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);
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;
}