219 lines
8.3 KiB
C++
219 lines
8.3 KiB
C++
#include "DriverCommon.h"
|
|
|
|
static PVOID ObRegistrationHandle = NULL;
|
|
static OB_CALLBACK_REGISTRATION ObRegistration;
|
|
static OB_OPERATION_REGISTRATION ObCallbacks[2];
|
|
|
|
static BOOLEAN IsSystemImage(PUNICODE_STRING FullImageName) {
|
|
if (!FullImageName || !FullImageName->Buffer) return FALSE;
|
|
|
|
if (WildcardMatch(L"*\\Windows\\System32\\*", FullImageName->Buffer, FullImageName->Length) ||
|
|
WildcardMatch(L"*\\Windows\\SysWOW64\\*", FullImageName->Buffer, FullImageName->Length) ||
|
|
WildcardMatch(L"*\\Windows\\WinSxS\\*", FullImageName->Buffer, FullImageName->Length) ||
|
|
WildcardMatch(L"*\\Windows\\Microsoft.NET\\*", FullImageName->Buffer, FullImageName->Length) ||
|
|
WildcardMatch(L"*\\Common Files\\Microsoft Shared\\*", FullImageName->Buffer, FullImageName->Length) ||
|
|
WildcardMatch(L"*\\Program Files*\\*", FullImageName->Buffer, FullImageName->Length)) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
VOID ImageLoadNotify(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo) {
|
|
UNREFERENCED_PARAMETER(ImageInfo);
|
|
|
|
if (KeGetCurrentIrql() > APC_LEVEL) return;
|
|
if (!FullImageName || !FullImageName->Buffer) return;
|
|
if (ProcessId == (HANDLE)0) return;
|
|
|
|
if (IsSystemImage(FullImageName)) return;
|
|
|
|
if (IsTargetProtected(ProcessId)) {
|
|
if (CheckFileExtensionRule(FullImageName)) {
|
|
SendMessageToUser(6001, (ULONG)(ULONG_PTR)ProcessId, FullImageName->Buffer, FullImageName->Length);
|
|
}
|
|
}
|
|
}
|
|
|
|
static BOOLEAN IsCriticalSystemProcess(HANDLE ProcessId) {
|
|
if (ProcessId == (HANDLE)4) return TRUE;
|
|
|
|
if (KeGetCurrentIrql() != PASSIVE_LEVEL) return FALSE;
|
|
|
|
NTSTATUS status;
|
|
BOOLEAN isCritical = FALSE;
|
|
PEPROCESS Process = NULL;
|
|
PUNICODE_STRING imageFileName = NULL;
|
|
|
|
status = PsLookupProcessByProcessId(ProcessId, &Process);
|
|
if (!NT_SUCCESS(status)) return FALSE;
|
|
|
|
status = SeLocateProcessImageName(Process, &imageFileName);
|
|
|
|
if (NT_SUCCESS(status) && imageFileName && imageFileName->Buffer) {
|
|
if (WildcardMatch(L"*\\Windows\\System32\\csrss.exe", imageFileName->Buffer, imageFileName->Length) ||
|
|
WildcardMatch(L"*\\Windows\\System32\\lsass.exe", imageFileName->Buffer, imageFileName->Length) ||
|
|
WildcardMatch(L"*\\Windows\\System32\\services.exe", imageFileName->Buffer, imageFileName->Length) ||
|
|
WildcardMatch(L"*\\Windows\\System32\\wininit.exe", imageFileName->Buffer, imageFileName->Length) ||
|
|
WildcardMatch(L"*\\Windows\\System32\\smss.exe", imageFileName->Buffer, imageFileName->Length)) {
|
|
isCritical = TRUE;
|
|
}
|
|
ExFreePool(imageFileName);
|
|
}
|
|
|
|
ObDereferenceObject(Process);
|
|
return isCritical;
|
|
}
|
|
|
|
static BOOLEAN IsBlacklistedAdminTool(HANDLE ProcessId) {
|
|
if (KeGetCurrentIrql() != PASSIVE_LEVEL) return FALSE;
|
|
|
|
NTSTATUS status;
|
|
BOOLEAN isBlacklisted = FALSE;
|
|
PEPROCESS Process = NULL;
|
|
PUNICODE_STRING imageFileName = NULL;
|
|
|
|
status = PsLookupProcessByProcessId(ProcessId, &Process);
|
|
if (!NT_SUCCESS(status)) return FALSE;
|
|
|
|
status = SeLocateProcessImageName(Process, &imageFileName);
|
|
|
|
if (NT_SUCCESS(status) && imageFileName) {
|
|
if (imageFileName->Buffer) {
|
|
if (WildcardMatch(L"*Taskmgr.exe", imageFileName->Buffer, imageFileName->Length) ||
|
|
WildcardMatch(L"*taskkill.exe", imageFileName->Buffer, imageFileName->Length) ||
|
|
WildcardMatch(L"*ProcessHacker.exe", imageFileName->Buffer, imageFileName->Length) ||
|
|
WildcardMatch(L"*procmon.exe", imageFileName->Buffer, imageFileName->Length)) {
|
|
isBlacklisted = TRUE;
|
|
}
|
|
}
|
|
ExFreePool(imageFileName);
|
|
}
|
|
|
|
ObDereferenceObject(Process);
|
|
return isBlacklisted;
|
|
}
|
|
|
|
static OB_PREOP_CALLBACK_STATUS PreOpenProcess(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation) {
|
|
UNREFERENCED_PARAMETER(RegistrationContext);
|
|
|
|
if (OperationInformation->KernelHandle) return OB_PREOP_SUCCESS;
|
|
|
|
PEPROCESS TargetProcess = (PEPROCESS)OperationInformation->Object;
|
|
if (!TargetProcess) return OB_PREOP_SUCCESS;
|
|
|
|
HANDLE TargetPid = PsGetProcessId(TargetProcess);
|
|
HANDLE SourcePid = PsGetCurrentProcessId();
|
|
|
|
if (SourcePid == TargetPid) return OB_PREOP_SUCCESS;
|
|
if ((ULONG)(ULONG_PTR)SourcePid == GlobalData.PyasPid) return OB_PREOP_SUCCESS;
|
|
if (SourcePid == (HANDLE)4) return OB_PREOP_SUCCESS;
|
|
|
|
if (IsTargetProtected(TargetPid)) {
|
|
if (IsCriticalSystemProcess(SourcePid)) return OB_PREOP_SUCCESS;
|
|
|
|
BOOLEAN bIsTrusted = IsProcessTrusted(SourcePid);
|
|
|
|
if (bIsTrusted) {
|
|
if (IsBlacklistedAdminTool(SourcePid)) {
|
|
bIsTrusted = FALSE;
|
|
}
|
|
}
|
|
|
|
if (bIsTrusted) return OB_PREOP_SUCCESS;
|
|
|
|
ACCESS_MASK DenyMask = PROCESS_TERMINATE |
|
|
PROCESS_VM_OPERATION |
|
|
PROCESS_VM_WRITE |
|
|
PROCESS_CREATE_THREAD |
|
|
PROCESS_VM_READ |
|
|
PROCESS_DUP_HANDLE |
|
|
PROCESS_SUSPEND_RESUME |
|
|
PROCESS_SET_INFORMATION |
|
|
PROCESS_SET_QUOTA;
|
|
|
|
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= (ACCESS_MASK)(~DenyMask);
|
|
|
|
if (OperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE) {
|
|
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= (ACCESS_MASK)(~DenyMask);
|
|
}
|
|
}
|
|
|
|
return OB_PREOP_SUCCESS;
|
|
}
|
|
|
|
static OB_PREOP_CALLBACK_STATUS PreOpenThread(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation) {
|
|
UNREFERENCED_PARAMETER(RegistrationContext);
|
|
|
|
if (OperationInformation->KernelHandle) return OB_PREOP_SUCCESS;
|
|
|
|
PETHREAD TargetThread = (PETHREAD)OperationInformation->Object;
|
|
if (!TargetThread) return OB_PREOP_SUCCESS;
|
|
|
|
PEPROCESS TargetProcess = IoThreadToProcess(TargetThread);
|
|
if (!TargetProcess) return OB_PREOP_SUCCESS;
|
|
|
|
HANDLE TargetPid = PsGetProcessId(TargetProcess);
|
|
HANDLE SourcePid = PsGetCurrentProcessId();
|
|
|
|
if (SourcePid == TargetPid) return OB_PREOP_SUCCESS;
|
|
if ((ULONG)(ULONG_PTR)SourcePid == GlobalData.PyasPid) return OB_PREOP_SUCCESS;
|
|
if (SourcePid == (HANDLE)4) return OB_PREOP_SUCCESS;
|
|
|
|
if (IsTargetProtected(TargetPid)) {
|
|
if (IsCriticalSystemProcess(SourcePid)) return OB_PREOP_SUCCESS;
|
|
|
|
BOOLEAN bIsTrusted = IsProcessTrusted(SourcePid);
|
|
|
|
if (bIsTrusted) {
|
|
if (IsBlacklistedAdminTool(SourcePid)) {
|
|
bIsTrusted = FALSE;
|
|
}
|
|
}
|
|
|
|
if (bIsTrusted) return OB_PREOP_SUCCESS;
|
|
|
|
ACCESS_MASK DenyMask = THREAD_TERMINATE |
|
|
THREAD_SUSPEND_RESUME |
|
|
THREAD_SET_CONTEXT |
|
|
THREAD_SET_INFORMATION |
|
|
THREAD_SET_THREAD_TOKEN;
|
|
|
|
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= (ACCESS_MASK)(~DenyMask);
|
|
|
|
if (OperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE) {
|
|
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= (ACCESS_MASK)(~DenyMask);
|
|
}
|
|
}
|
|
|
|
return OB_PREOP_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS InitializeProcessProtection() {
|
|
static UNICODE_STRING Altitude = { 0 };
|
|
RtlInitUnicodeString(&Altitude, L"320000");
|
|
|
|
ObCallbacks[0].ObjectType = PsProcessType;
|
|
ObCallbacks[0].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
|
|
ObCallbacks[0].PreOperation = PreOpenProcess;
|
|
ObCallbacks[0].PostOperation = NULL;
|
|
|
|
ObCallbacks[1].ObjectType = PsThreadType;
|
|
ObCallbacks[1].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
|
|
ObCallbacks[1].PreOperation = PreOpenThread;
|
|
ObCallbacks[1].PostOperation = NULL;
|
|
|
|
ObRegistration.Version = OB_FLT_REGISTRATION_VERSION;
|
|
ObRegistration.OperationRegistrationCount = 2;
|
|
ObRegistration.Altitude = Altitude;
|
|
ObRegistration.RegistrationContext = NULL;
|
|
ObRegistration.OperationRegistration = ObCallbacks;
|
|
|
|
return ObRegisterCallbacks(&ObRegistration, &ObRegistrationHandle);
|
|
}
|
|
|
|
VOID UninitializeProcessProtection() {
|
|
if (ObRegistrationHandle) {
|
|
ObUnRegisterCallbacks(ObRegistrationHandle);
|
|
ObRegistrationHandle = NULL;
|
|
}
|
|
} |