From 868eddfd2b9cb7bd6a3c5c40ed01920edbad0fdf Mon Sep 17 00:00:00 2001 From: PYDT <85057800+87owo@users.noreply.github.com> Date: Sat, 23 Aug 2025 22:04:11 +0800 Subject: [PATCH] Add files via upload --- Plugins/Filter/DriverEntry.c | 45 +++--- Plugins/Filter/DriverEntry.h | 23 ++- Plugins/Filter/ProtectInject.c | 9 +- Plugins/Filter/ProtectProcess.c | 232 +++++++++++++++++++++++++++++++ Plugins/Filter/ProtectRegistry.c | 131 +++++++++++++++++ 5 files changed, 416 insertions(+), 24 deletions(-) create mode 100644 Plugins/Filter/ProtectProcess.c create mode 100644 Plugins/Filter/ProtectRegistry.c diff --git a/Plugins/Filter/DriverEntry.c b/Plugins/Filter/DriverEntry.c index 0886503..3e1b124 100644 --- a/Plugins/Filter/DriverEntry.c +++ b/Plugins/Filter/DriverEntry.c @@ -183,7 +183,7 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { UNICODE_STRING guardName = RTL_CONSTANT_STRING(L"\\Device\\PYAS_Driver_Guard"); NTSTATUS gs = IoCreateDevice(DriverObject, 0, &guardName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_GuardDevice); - if (!NT_SUCCESS(gs)) + if (!NT_SUCCESS(gs)) return STATUS_DEVICE_BUSY; } { @@ -194,13 +194,12 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) g_DeviceName.Length = (USHORT)(wcslen(g_DeviceName.Buffer) * sizeof(WCHAR)); } NTSTATUS status = IoCreateDevice(DriverObject, 0, &g_DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_ControlDeviceObject); - if (!NT_SUCCESS(status)) + if (!NT_SUCCESS(status)) return status; DriverObject->DriverUnload = DriverUnload; - for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; ++i) + for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; ++i) DriverObject->MajorFunction[i] = CombinedDispatch; - g_ControlDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; IoDeleteSymbolicLink(&g_SymLink); { @@ -231,38 +230,50 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) RtlInitUnicodeString(®Alt, regAltBuf); status = CmRegisterCallbackEx(RegistryProtectCallback, ®Alt, DriverObject, NULL, &g_CmRegHandle, NULL); - if (NT_SUCCESS(status)) + if (NT_SUCCESS(status)) g_CmRegActive = TRUE; } InitImageProtect(); InitInjectProtect(); InitRemoteProtect(); InitScreenProtect(); + { + NTSTATUS ps = InitProcessProtect(); + if (!NT_SUCCESS(ps)) { + CHAR b[64] = { 0 }; + RtlStringCchPrintfA(b, RTL_NUMBER_OF(b), "PROC_INIT | 0x%08X", ps); + SendPipeLog(b, strlen(b)); + } + else { + static CHAR ok[] = "PROC_INIT | 0x00000000"; + SendPipeLog(ok, sizeof(ok) - 1); + } + } AttachFsFilters(DriverObject); AttachDiskFilters(DriverObject); - return STATUS_SUCCESS; } VOID DriverUnload(PDRIVER_OBJECT DriverObject) { UNREFERENCED_PARAMETER(DriverObject); - + g_Unloading = TRUE; if (g_SymLinkCreated) { IoDeleteSymbolicLink(&g_SymLink); - g_SymLinkCreated = FALSE; + g_SymLinkCreated = FALSE; } - if (g_CmRegActive) { - CmUnRegisterCallback(g_CmRegHandle); - g_CmRegActive = FALSE; + if (g_CmRegActive) { + CmUnRegisterCallback(g_CmRegHandle); + g_CmRegActive = FALSE; } UninitInjectProtect(); UninitImageProtect(); UninitRemoteProtect(); UninitScreenProtect(); + UninitProcessProtect(); ExWaitForRundownProtectionRelease(&g_Rundown); - + if (InterlockedCompareExchange(&g_LogWorkCount, 0, 0) != 0) { KeResetEvent(&g_LogDrainEvent); while (InterlockedCompareExchange(&g_LogWorkCount, 0, 0) != 0) @@ -276,16 +287,16 @@ VOID DriverUnload(PDRIVER_OBJECT DriverObject) } } g_MbrFilterCount = 0; - if (DiskDrvObj) { - ObDereferenceObject(DiskDrvObj); - DiskDrvObj = NULL; + if (DiskDrvObj) { + ObDereferenceObject(DiskDrvObj); + DiskDrvObj = NULL; } - if (g_ControlDeviceObject) { + if (g_ControlDeviceObject) { IoDeleteDevice(g_ControlDeviceObject); g_ControlDeviceObject = NULL; } if (g_GuardDevice) { IoDeleteDevice(g_GuardDevice); - g_GuardDevice = NULL; + g_GuardDevice = NULL; } } diff --git a/Plugins/Filter/DriverEntry.h b/Plugins/Filter/DriverEntry.h index 4a6d889..c073a3e 100644 --- a/Plugins/Filter/DriverEntry.h +++ b/Plugins/Filter/DriverEntry.h @@ -10,6 +10,9 @@ #ifndef POOL_FLAG_NON_PAGED #define POOL_FLAG_NON_PAGED 0x00000001 #endif +#ifndef PROCESS_TERMINATE +#define PROCESS_TERMINATE 0x0001 +#endif #ifndef PROCESS_CREATE_THREAD #define PROCESS_CREATE_THREAD 0x0002 #endif @@ -43,12 +46,27 @@ #ifndef PROCESS_SET_LIMITED_INFORMATION #define PROCESS_SET_LIMITED_INFORMATION 0x2000 #endif +#ifndef THREAD_TERMINATE +#define THREAD_TERMINATE 0x0001 +#endif +#ifndef THREAD_SUSPEND_RESUME +#define THREAD_SUSPEND_RESUME 0x0002 +#endif +#ifndef THREAD_SET_CONTEXT +#define THREAD_SET_CONTEXT 0x0010 +#endif #ifndef THREAD_IMPERSONATE #define THREAD_IMPERSONATE 0x0100 #endif #ifndef THREAD_DIRECT_IMPERSONATION #define THREAD_DIRECT_IMPERSONATION 0x0200 #endif +#ifndef JOB_OBJECT_ASSIGN_PROCESS +#define JOB_OBJECT_ASSIGN_PROCESS 0x0001 +#endif +#ifndef JOB_OBJECT_TERMINATE +#define JOB_OBJECT_TERMINATE 0x0008 +#endif #ifndef FILE_DISPOSITION_DELETE #define FILE_DISPOSITION_DELETE 0x00000001 #endif @@ -56,6 +74,7 @@ typedef unsigned int UINT; #endif +extern POBJECT_TYPE* PsJobType; extern volatile LONG g_LogWorkCount; extern BOOLEAN g_Unloading; extern KEVENT g_LogDrainEvent; @@ -97,7 +116,7 @@ static __forceinline PVOID PYAS_ExAllocatePool2(ULONG f, SIZE_T s, ULONG t) { static __forceinline VOID PYAS_ExFreePool2(PVOID a, ULONG t, PVOID h, ULONG f) { UNREFERENCED_PARAMETER(h); UNREFERENCED_PARAMETER(f); - + static _pyas_ExFreePool2 p2 = 0; if (!p2) { UNICODE_STRING n = RTL_CONSTANT_STRING(L"ExFreePool2"); @@ -127,6 +146,7 @@ VOID UninitImageProtect(VOID); VOID UninitInjectProtect(VOID); VOID UninitRemoteProtect(VOID); VOID UninitScreenProtect(VOID); +VOID UninitProcessProtect(VOID); NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess( _In_ HANDLE ProcessHandle, @@ -153,5 +173,6 @@ NTSTATUS InitImageProtect(VOID); NTSTATUS InitInjectProtect(VOID); NTSTATUS InitRemoteProtect(VOID); NTSTATUS InitScreenProtect(VOID); +NTSTATUS InitProcessProtect(VOID); BOOLEAN GetProcessImagePathByPid(HANDLE pid, PUNICODE_STRING ProcessImagePath); diff --git a/Plugins/Filter/ProtectInject.c b/Plugins/Filter/ProtectInject.c index 74b94ce..1f0eab9 100644 --- a/Plugins/Filter/ProtectInject.c +++ b/Plugins/Filter/ProtectInject.c @@ -11,7 +11,7 @@ static VOID LogAnsi3(PCSTR tag, ULONG upid, PUNICODE_STRING s1, PUNICODE_STRING ANSI_STRING a1 = { 0 }, a2 = { 0 }; CHAR buf[1024] = { 0 }; RtlUnicodeStringToAnsiString(&a1, s1, TRUE); - if (s2) + if (s2) RtlUnicodeStringToAnsiString(&a2, s2, TRUE); RtlStringCchPrintfA(buf, RTL_NUMBER_OF(buf), "%s | %u | %s | %s", tag, upid, a1.Buffer ? a1.Buffer : "", a2.Buffer ? a2.Buffer : ""); SendPipeLog(buf, strlen(buf)); @@ -118,7 +118,7 @@ static OB_PREOP_CALLBACK_STATUS PreThreadCallback(PVOID RegistrationContext, POB cexe.Buffer = cbuf; cexe.MaximumLength = sizeof(cbuf); - if (logok) + if (logok) GetProcessImagePathByPid(cur, &cexe); if (logok && IsWhitelist(&cexe)) { ExReleaseRundownProtection(&g_Rundown); @@ -145,11 +145,8 @@ static OB_PREOP_CALLBACK_STATUS PreThreadCallback(PVOID RegistrationContext, POB NTSTATUS InitInjectProtect(VOID) { - static WCHAR obAltBuf[32]; static UNICODE_STRING obAlt; - LARGE_INTEGER t = KeQueryPerformanceCounter(NULL); - RtlStringCchPrintfW(obAltBuf, RTL_NUMBER_OF(obAltBuf), L"385000.%I64x", t.QuadPart); - RtlInitUnicodeString(&obAlt, obAltBuf); + RtlInitUnicodeString(&obAlt, L"385000"); g_ObOps = (POB_OPERATION_REGISTRATION)ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(OB_OPERATION_REGISTRATION) * 2, 'bOpr'); if (!g_ObOps) diff --git a/Plugins/Filter/ProtectProcess.c b/Plugins/Filter/ProtectProcess.c new file mode 100644 index 0000000..ee3bd96 --- /dev/null +++ b/Plugins/Filter/ProtectProcess.c @@ -0,0 +1,232 @@ +#include +#include "DriverEntry.h" + +typedef union _PS_PROTECTION { + UCHAR Level; + struct { + UCHAR Type : 3; + UCHAR Audit : 1; + UCHAR Signer : 4; + }Flags; +}PS_PROTECTION, * PPS_PROTECTION; + +typedef struct _OBCTX { + POBJECT_TYPE ProcessType; + POBJECT_TYPE ThreadType; +}OBCTX, * POBCTX; + +static PVOID g_PsSetProcessProtection = NULL; +static BOOLEAN g_ProcNotifyEnabled = FALSE; +static PVOID g_ObCookie = NULL; +static OBCTX g_ObCtx = { 0 }; +static HANDLE g_ProtectedPid = NULL; + +static BOOLEAN EndsWithNameA(PCSTR s, PCSTR name) { + if (!s || !name) { + return FALSE; + } + SIZE_T n = strlen(s); + SIZE_T m = strlen(name); + if (n < m) { + return FALSE; + } + return _stricmp(s + (n - m), name) == 0; +} + +static BOOLEAN EndsWithNameUS(PUNICODE_STRING s, const wchar_t* name) { + if (!s || !s->Buffer || s->Length == 0 || !name) { + return FALSE; + } + SIZE_T n = s->Length / sizeof(WCHAR); + SIZE_T m = wcslen(name); + if (n < m) { + return FALSE; + } + return _wcsnicmp(s->Buffer + (n - m), name, m) == 0; +} + +static BOOLEAN IsTargetProcess(PEPROCESS p) { + if (!p) { + return FALSE; + } + HANDLE pid = PsGetProcessId(p); + WCHAR buf[512] = { 0 }; + UNICODE_STRING img = { 0 }; + img.Buffer = buf; + img.MaximumLength = sizeof(buf); + if (GetProcessImagePathByPid(pid, &img)) { + if (EndsWithNameUS(&img, L"PYAS.exe")) { + return TRUE; + } + return FALSE; + } + return EndsWithNameA(PsGetProcessImageFileName(p), "PYAS.exe"); +} + +static NTSTATUS SetPPL31(PEPROCESS p) { + if (!g_PsSetProcessProtection) { + return STATUS_PROCEDURE_NOT_FOUND; + } + PS_PROTECTION pr = { 0 }; + pr.Level = 0x31; + ((VOID(NTAPI*)(PEPROCESS, PS_PROTECTION))g_PsSetProcessProtection)(p, pr); + return STATUS_SUCCESS; +} + +static VOID LogSet(HANDLE pid, NTSTATUS st) { + CHAR b[128] = { 0 }; + RtlStringCchPrintfA(b, RTL_NUMBER_OF(b), "PROC_PPL_SET | %u | 0x31 | 0x%08X", (ULONG)(ULONG_PTR)pid, st); + SendPipeLog(b, strlen(b)); +} + +static VOID UpdateProtectedPid(HANDLE pid) { + InterlockedExchangePointer((PVOID*)&g_ProtectedPid, pid); +} + +static VOID BootstrapExisting(VOID) { + typedef PEPROCESS(NTAPI* PFN_PsGetNextProcess)(PEPROCESS); + UNICODE_STRING n = RTL_CONSTANT_STRING(L"PsGetNextProcess"); + PFN_PsGetNextProcess fp = (PFN_PsGetNextProcess)MmGetSystemRoutineAddress(&n); + if (!fp) { + return; + } + PEPROCESS p = fp(NULL); + while (p) { + if (IsTargetProcess(p)) { + HANDLE pid = PsGetProcessId(p); + NTSTATUS s = SetPPL31(p); + UpdateProtectedPid(pid); + LogSet(pid, s); + } + PEPROCESS nx = fp(p); + ObDereferenceObject(p); + p = nx; + } +} + +static VOID StripProcessAccess(POB_PRE_OPERATION_INFORMATION Info) { + ACCESS_MASK d = PROCESS_TERMINATE | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_SET_INFORMATION | PROCESS_SET_LIMITED_INFORMATION | PROCESS_SUSPEND_RESUME | PROCESS_DUP_HANDLE; + if (Info->Operation == OB_OPERATION_HANDLE_CREATE) { + Info->Parameters->CreateHandleInformation.DesiredAccess &= ~d; + } + else { + Info->Parameters->DuplicateHandleInformation.DesiredAccess &= ~d; + } +} + +static VOID StripThreadAccess(POB_PRE_OPERATION_INFORMATION Info) { + ACCESS_MASK d = THREAD_TERMINATE | THREAD_SUSPEND_RESUME | THREAD_SET_CONTEXT | THREAD_IMPERSONATE | THREAD_DIRECT_IMPERSONATION; + if (Info->Operation == OB_OPERATION_HANDLE_CREATE) { + Info->Parameters->CreateHandleInformation.DesiredAccess &= ~d; + } + else { + Info->Parameters->DuplicateHandleInformation.DesiredAccess &= ~d; + } +} + +static OB_PREOP_CALLBACK_STATUS ObPreOperation(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION Info) { + UNREFERENCED_PARAMETER(RegistrationContext); + if (g_Unloading) { + return OB_PREOP_SUCCESS; + } + if (!ExAcquireRundownProtection(&g_Rundown)) { + return OB_PREOP_SUCCESS; + } + if (Info->ObjectType == g_ObCtx.ProcessType) { + PEPROCESS pe = (PEPROCESS)Info->Object; + HANDLE tpid = PsGetProcessId(pe); + if (g_ProtectedPid && tpid == g_ProtectedPid) { + if (PsGetCurrentProcessId() != g_ProtectedPid) { + StripProcessAccess(Info); + } + } + } + else if (Info->ObjectType == g_ObCtx.ThreadType) { + PETHREAD th = (PETHREAD)Info->Object; + HANDLE owner = PsGetThreadProcessId(th); + if (g_ProtectedPid && owner == g_ProtectedPid) { + if (PsGetCurrentProcessId() != g_ProtectedPid) { + StripThreadAccess(Info); + } + } + } + ExReleaseRundownProtection(&g_Rundown); + return OB_PREOP_SUCCESS; +} + +static NTSTATUS InitObCallbacks(VOID) +{ + g_ObCtx.ProcessType = *PsProcessType; + g_ObCtx.ThreadType = *PsThreadType; + + OB_OPERATION_REGISTRATION ops[2] = { 0 }; + ops[0].ObjectType = PsProcessType; + ops[0].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE; + ops[0].PreOperation = ObPreOperation; + ops[1].ObjectType = PsThreadType; + ops[1].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE; + ops[1].PreOperation = ObPreOperation; + + UNICODE_STRING alt; + RtlInitUnicodeString(&alt, L"385100"); + + OB_CALLBACK_REGISTRATION reg = { 0 }; + reg.Version = OB_FLT_REGISTRATION_VERSION; + reg.OperationRegistrationCount = 2; + reg.RegistrationContext = NULL; + reg.Altitude = alt; + reg.OperationRegistration = ops; + return ObRegisterCallbacks(®, &g_ObCookie); +} + +static VOID ProcessNotifyEx(PEPROCESS Process, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo) { + if (g_Unloading) { + return; + } + if (!ExAcquireRundownProtection(&g_Rundown)) { + return; + } + if (CreateInfo) { + UNICODE_STRING img = { 0 }; + if (CreateInfo->ImageFileName) { + img = *CreateInfo->ImageFileName; + } + if ((img.Buffer && EndsWithNameUS(&img, L"PYAS.exe")) || (!img.Buffer && IsTargetProcess(Process))) { + NTSTATUS s = SetPPL31(Process); + UpdateProtectedPid(ProcessId); + LogSet(ProcessId, s); + } + } + else { + if (g_ProtectedPid && ProcessId == g_ProtectedPid) { + UpdateProtectedPid(NULL); + } + } + ExReleaseRundownProtection(&g_Rundown); +} + +NTSTATUS InitProcessProtect(VOID) { + UNICODE_STRING n = RTL_CONSTANT_STRING(L"PsSetProcessProtection"); + g_PsSetProcessProtection = MmGetSystemRoutineAddress(&n); + + NTSTATUS s = InitObCallbacks(); + if (!NT_SUCCESS(s)) + return s; + + s = PsSetCreateProcessNotifyRoutineEx(ProcessNotifyEx, FALSE); + if (NT_SUCCESS(s)) + g_ProcNotifyEnabled = TRUE; + BootstrapExisting(); + return STATUS_SUCCESS; +} + +VOID UninitProcessProtect(VOID) { + if (g_ProcNotifyEnabled) { + PsSetCreateProcessNotifyRoutineEx(ProcessNotifyEx, TRUE); + g_ProcNotifyEnabled = FALSE; + } + if (g_ObCookie) { + ObUnRegisterCallbacks(g_ObCookie); + g_ObCookie = NULL; + } +} diff --git a/Plugins/Filter/ProtectRegistry.c b/Plugins/Filter/ProtectRegistry.c new file mode 100644 index 0000000..40d8d77 --- /dev/null +++ b/Plugins/Filter/ProtectRegistry.c @@ -0,0 +1,131 @@ +#include +#include "DriverEntry.h" +#include "ProtectMatch.h" + +static BOOLEAN QueryRegPathFromObject(PVOID KeyObject, PUNICODE_STRING OutPath, POBJECT_NAME_INFORMATION* OutInfo) +{ + ULONG len = 0; + NTSTATUS s = ObQueryNameString(KeyObject, NULL, 0, &len); + if (s != STATUS_INFO_LENGTH_MISMATCH) + return FALSE; + + POBJECT_NAME_INFORMATION p = (POBJECT_NAME_INFORMATION)ExAllocatePool2(POOL_FLAG_NON_PAGED, len, 'rgeR'); + if (!p) + return FALSE; + + s = ObQueryNameString(KeyObject, p, len, &len); + if (!NT_SUCCESS(s) || !p->Name.Buffer || p->Name.Length == 0) { + ExFreePool2(p, 'rgeR', NULL, 0); + return FALSE; + } + *OutInfo = p; + OutPath->Buffer = p->Name.Buffer; + OutPath->Length = p->Name.Length; + OutPath->MaximumLength = p->Name.Length; + return TRUE; +} + +static VOID LogAnsi3(PCSTR tag, ULONG upid, PUNICODE_STRING s1, PUNICODE_STRING s2) +{ + ANSI_STRING a1 = { 0 }, a2 = { 0 }; + CHAR buf[1024] = { 0 }; + RtlUnicodeStringToAnsiString(&a1, s1, TRUE); + if (s2) + RtlUnicodeStringToAnsiString(&a2, s2, TRUE); + RtlStringCchPrintfA(buf, RTL_NUMBER_OF(buf), "%s | %u | %s | %s", tag, upid, a1.Buffer ? a1.Buffer : "", a2.Buffer ? a2.Buffer : ""); + SendPipeLog(buf, strlen(buf)); + RtlFreeAnsiString(&a1); + RtlFreeAnsiString(&a2); +} + +NTSTATUS RegistryProtectCallback(PVOID ctx, PVOID arg1, PVOID arg2) +{ + UNREFERENCED_PARAMETER(ctx); + if (g_Unloading) + return STATUS_SUCCESS; + if (!ExAcquireRundownProtection(&g_Rundown)) + return STATUS_SUCCESS; + + REG_NOTIFY_CLASS type = (REG_NOTIFY_CLASS)(ULONG_PTR)arg1; + NTSTATUS status = STATUS_SUCCESS; + UNICODE_STRING checkReg = { 0 }; + POBJECT_NAME_INFORMATION nameInfo = NULL; + + UNICODE_STRING exe = { 0 }; + WCHAR exeBuf[260] = { 0 }; + exe.Buffer = exeBuf; + exe.MaximumLength = sizeof(exeBuf); + exe.Length = 0; + + HANDLE pid = PsGetCurrentProcessId(); + if (pid == (HANDLE)0 || pid == (HANDLE)4) { + ExReleaseRundownProtection(&g_Rundown); + return STATUS_SUCCESS; + } + PUNICODE_STRING valueName = NULL; + BOOLEAN need_log = FALSE; + BOOLEAN canQuery = (KeGetCurrentIrql() == PASSIVE_LEVEL); + + if (type == RegNtPreSetValueKey) { + PREG_SET_VALUE_KEY_INFORMATION s = (PREG_SET_VALUE_KEY_INFORMATION)arg2; + valueName = s->ValueName; + if (canQuery) + QueryRegPathFromObject(s->Object, &checkReg, &nameInfo); + } + else if (type == RegNtPreDeleteValueKey) { + PREG_DELETE_VALUE_KEY_INFORMATION d = (PREG_DELETE_VALUE_KEY_INFORMATION)arg2; + valueName = d->ValueName; + if (canQuery) + QueryRegPathFromObject(d->Object, &checkReg, &nameInfo); + } + else if (type == RegNtPreDeleteKey) { + PREG_DELETE_KEY_INFORMATION d = (PREG_DELETE_KEY_INFORMATION)arg2; + if (canQuery) + QueryRegPathFromObject(d->Object, &checkReg, &nameInfo); + } + else if (type == RegNtPreRenameKey) { + PREG_RENAME_KEY_INFORMATION r = (PREG_RENAME_KEY_INFORMATION)arg2; + if (canQuery) + QueryRegPathFromObject(r->Object, &checkReg, &nameInfo); + } + else if (type == RegNtPreCreateKeyEx) { + PREG_CREATE_KEY_INFORMATION c = (PREG_CREATE_KEY_INFORMATION)arg2; + if (c->CompleteName) + checkReg = *c->CompleteName; + } + else if (type == RegNtPreReplaceKey) { + PREG_REPLACE_KEY_INFORMATION rk = (PREG_REPLACE_KEY_INFORMATION)arg2; + if (canQuery) + QueryRegPathFromObject(rk->Object, &checkReg, &nameInfo); + } + else if (type == RegNtPreSaveKey) { + PREG_SAVE_KEY_INFORMATION sk = (PREG_SAVE_KEY_INFORMATION)arg2; + if (canQuery) + QueryRegPathFromObject(sk->Object, &checkReg, &nameInfo); + } + else if (type == RegNtPreRestoreKey) { + PREG_RESTORE_KEY_INFORMATION res = (PREG_RESTORE_KEY_INFORMATION)arg2; + if (canQuery) + QueryRegPathFromObject(res->Object, &checkReg, &nameInfo); + } + else if (type == RegNtPreLoadKey) { + PREG_LOAD_KEY_INFORMATION lk = (PREG_LOAD_KEY_INFORMATION)arg2; + if (lk->KeyName) + checkReg = *lk->KeyName; + } + + if (checkReg.Buffer || (valueName && valueName->Buffer)) { + if (canQuery) + GetProcessImagePathByPid(pid, &exe); + if (IsRegistryBlock(&checkReg, valueName, &exe)) { + need_log = TRUE; + status = STATUS_ACCESS_DENIED; + } + } + if (nameInfo) + ExFreePool2(nameInfo, 'rgeR', NULL, 0); + if (need_log) + LogAnsi3("REG_BLOCK", (ULONG)(ULONG_PTR)pid, &exe, &checkReg); + ExReleaseRundownProtection(&g_Rundown); + return status; +}