Add files via upload

This commit is contained in:
PYDT authored and GitHub committed 2025-08-23 22:04:11 +08:00
1 parent 8295e6bb5b
commit 868eddfd2b
5 files changed
+416 -24

No files matched your search

+28 -17
View File
@@ -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(&regAlt, regAltBuf);
status = CmRegisterCallbackEx(RegistryProtectCallback, &regAlt, 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;
}
}
+22 -1
View File
@@ -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);
+3 -6
View File
@@ -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)
+232
View File
@@ -0,0 +1,232 @@
#include <ntifs.h>
#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(&reg, &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;
}
}
+131
View File
@@ -0,0 +1,131 @@
#include <ntifs.h>
#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;
}