Add files via upload
This commit is contained in:
5 files changed
+416
-24
No files matched your search
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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)
|
||||
|
||||
@@ -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(®, &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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user