360 lines
11 KiB
C++
360 lines
11 KiB
C++
#pragma once
|
|
#include <fltKernel.h>
|
|
#include <ntddk.h>
|
|
#include <ntdddisk.h>
|
|
#include <ntddscsi.h>
|
|
#include <ntstrsafe.h>
|
|
|
|
constexpr auto PYAS_PORT_NAME = L"\\PYAS_Output_Pipe";
|
|
constexpr auto MAX_PATH_LEN = 1024;
|
|
constexpr auto PYAS_POOL_TAG = 'SAYP';
|
|
constexpr auto PYAS_OB_ALTITUDE = L"320000.4101";
|
|
constexpr auto PYAS_CONNECTION_MAGIC = 0x53415950;
|
|
constexpr auto PYAS_CONNECTION_VERSION = 1;
|
|
|
|
#ifndef PROCESS_TERMINATE
|
|
#define PROCESS_TERMINATE (0x0001)
|
|
#endif
|
|
#ifndef PROCESS_CREATE_THREAD
|
|
#define PROCESS_CREATE_THREAD (0x0002)
|
|
#endif
|
|
#ifndef PROCESS_VM_OPERATION
|
|
#define PROCESS_VM_OPERATION (0x0008)
|
|
#endif
|
|
#ifndef PROCESS_VM_READ
|
|
#define PROCESS_VM_READ (0x0010)
|
|
#endif
|
|
#ifndef PROCESS_VM_WRITE
|
|
#define PROCESS_VM_WRITE (0x0020)
|
|
#endif
|
|
#ifndef PROCESS_DUP_HANDLE
|
|
#define PROCESS_DUP_HANDLE (0x0040)
|
|
#endif
|
|
#ifndef PROCESS_CREATE_PROCESS
|
|
#define PROCESS_CREATE_PROCESS (0x0080)
|
|
#endif
|
|
#ifndef PROCESS_SET_INFORMATION
|
|
#define PROCESS_SET_INFORMATION (0x0200)
|
|
#endif
|
|
#ifndef PROCESS_QUERY_INFORMATION
|
|
#define PROCESS_QUERY_INFORMATION (0x0400)
|
|
#endif
|
|
#ifndef PROCESS_SUSPEND_RESUME
|
|
#define PROCESS_SUSPEND_RESUME (0x0800)
|
|
#endif
|
|
#ifndef PROCESS_QUERY_LIMITED_INFORMATION
|
|
#define PROCESS_QUERY_LIMITED_INFORMATION (0x1000)
|
|
#endif
|
|
#ifndef PROCESS_SET_QUOTA
|
|
#define PROCESS_SET_QUOTA (0x0100)
|
|
#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_SET_INFORMATION
|
|
#define THREAD_SET_INFORMATION (0x0020)
|
|
#endif
|
|
#ifndef THREAD_SET_THREAD_TOKEN
|
|
#define THREAD_SET_THREAD_TOKEN (0x0080)
|
|
#endif
|
|
#ifndef THREAD_IMPERSONATE
|
|
#define THREAD_IMPERSONATE (0x0100)
|
|
#endif
|
|
#ifndef THREAD_DIRECT_IMPERSONATION
|
|
#define THREAD_DIRECT_IMPERSONATION (0x0200)
|
|
#endif
|
|
#ifndef POOL_FLAG_NON_PAGED
|
|
#define POOL_FLAG_NON_PAGED 0x0000000000000040UI64
|
|
#endif
|
|
|
|
#ifndef FSCTL_MANAGE_BYPASS_IO
|
|
#define FSCTL_MANAGE_BYPASS_IO CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 188, METHOD_NEITHER, FILE_ANY_ACCESS)
|
|
|
|
typedef enum _FS_BPIO_OPERATIONS {
|
|
FS_BPIO_OP_ENABLE = 1,
|
|
FS_BPIO_OP_DISABLE = 2,
|
|
FS_BPIO_OP_QUERY = 3,
|
|
FS_BPIO_OP_VOLUME_STACK_PAUSE = 4,
|
|
FS_BPIO_OP_VOLUME_STACK_RESUME = 5,
|
|
FS_BPIO_OP_STREAM_PAUSE = 6,
|
|
FS_BPIO_OP_STREAM_RESUME = 7,
|
|
FS_BPIO_OP_GET_INFO = 8
|
|
} FS_BPIO_OPERATIONS;
|
|
|
|
typedef struct _FS_BPIO_INPUT {
|
|
FS_BPIO_OPERATIONS Operation;
|
|
ULONG InFlags;
|
|
ULONGLONG Reserved1;
|
|
ULONGLONG Reserved2;
|
|
} FS_BPIO_INPUT, * PFS_BPIO_INPUT;
|
|
|
|
typedef struct _FS_BPIO_OUTPUT {
|
|
FS_BPIO_OPERATIONS Operation;
|
|
ULONG OutFlags;
|
|
ULONGLONG Reserved1;
|
|
ULONGLONG Reserved2;
|
|
NTSTATUS Status;
|
|
} FS_BPIO_OUTPUT, * PFS_BPIO_OUTPUT;
|
|
#endif
|
|
|
|
|
|
typedef enum _PYAS_DRIVER_STATE {
|
|
PyasDriverStateCold = 0,
|
|
PyasDriverStateStarting = 1,
|
|
PyasDriverStateRunning = 2,
|
|
PyasDriverStateStopping = 3,
|
|
PyasDriverStateStopRetry = 4,
|
|
PyasDriverStateStopped = 5
|
|
} PYAS_DRIVER_STATE;
|
|
|
|
typedef struct _PYAS_MESSAGE {
|
|
ULONG MessageCode;
|
|
ULONG ProcessId;
|
|
WCHAR Path[MAX_PATH_LEN];
|
|
} PYAS_MESSAGE, * PPYAS_MESSAGE;
|
|
|
|
typedef enum _PYAS_COMMAND {
|
|
PyasCommandAddWhitelist = 1,
|
|
PyasCommandRemoveWhitelist = 2,
|
|
PyasCommandLoadRuleFile = 3,
|
|
PyasCommandClearRules = 4,
|
|
PyasCommandAuthorizeUnload = 5,
|
|
PyasCommandRevokeUnload = 6,
|
|
PyasCommandQueryState = 7
|
|
} PYAS_COMMAND;
|
|
|
|
typedef struct _PYAS_USER_MESSAGE {
|
|
ULONG Command;
|
|
WCHAR Path[MAX_PATH_LEN];
|
|
} PYAS_USER_MESSAGE, * PPYAS_USER_MESSAGE;
|
|
|
|
typedef struct _PYAS_CONNECTION_CONTEXT {
|
|
ULONG Size;
|
|
ULONG Version;
|
|
ULONG Magic;
|
|
ULONG ProcessId;
|
|
} PYAS_CONNECTION_CONTEXT, * PPYAS_CONNECTION_CONTEXT;
|
|
|
|
typedef struct _DRIVER_DATA {
|
|
PDRIVER_OBJECT DriverObject;
|
|
PFLT_FILTER FilterHandle;
|
|
PFLT_PORT ServerPort;
|
|
PFLT_PORT ClientPort;
|
|
PEPROCESS PyasProcess;
|
|
ULONG PyasPid;
|
|
LARGE_INTEGER Cookie;
|
|
KSPIN_LOCK PortMutex;
|
|
KSPIN_LOCK TrackerMutex;
|
|
KSPIN_LOCK PidLock;
|
|
BOOLEAN Initialized;
|
|
volatile LONG DriverState;
|
|
volatile LONG UnloadAuthorized;
|
|
volatile LONG PortStopping;
|
|
volatile LONG ClientCloseActive;
|
|
EX_RUNDOWN_REF PortRundown;
|
|
KEVENT CleanupCompleteEvent;
|
|
PVOID ObRegistrationHandle;
|
|
UNICODE_STRING ClientImagePath;
|
|
WCHAR ClientImagePathBuffer[MAX_PATH_LEN];
|
|
} DRIVER_DATA, * PDRIVER_DATA;
|
|
|
|
typedef struct _RULE_NODE {
|
|
struct _RULE_NODE* Next;
|
|
UNICODE_STRING Pattern;
|
|
} RULE_NODE, * PRULE_NODE;
|
|
|
|
typedef enum _RULE_CATEGORY {
|
|
RuleCategoryProcess,
|
|
RuleCategoryFile,
|
|
RuleCategoryRegistry,
|
|
RuleCategoryDevice,
|
|
RuleCategoryMemory,
|
|
RuleCategoryThread,
|
|
RuleCategoryUnknown
|
|
} RULE_CATEGORY;
|
|
|
|
#define OP_WRITE 0x00000001
|
|
#define OP_DELETE 0x00000002
|
|
#define OP_CREATE 0x00000004
|
|
#define OP_EXECUTE 0x00000008
|
|
#define OP_RENAME 0x00000010
|
|
#define OP_IOCTL 0x00000020
|
|
#define OP_VM_READ 0x00000040
|
|
#define OP_VM_WRITE 0x00000080
|
|
#define OP_TERMINATE 0x00000100
|
|
#define OP_SUSPEND_RESUME 0x00000200
|
|
#define OP_DUP_HANDLE 0x00000400
|
|
#define OP_SET_INFORMATION 0x00000800
|
|
#define OP_VM_OPERATION 0x00001000
|
|
#define OP_CREATE_THREAD 0x00002000
|
|
#define OP_THREAD_SET_CONTEXT 0x00004000
|
|
#define OP_THREAD_SET_TOKEN 0x00008000
|
|
#define OP_CREATE_PROCESS 0x00010000
|
|
#define OP_IMAGE_LOAD 0x00020000
|
|
#define OP_IMPERSONATE 0x00040000
|
|
|
|
#define PYAS_HANDLE_CREATE 0x00000001
|
|
#define PYAS_HANDLE_DUPLICATE 0x00000002
|
|
|
|
#define PYAS_OBJECT_PROCESS 0x00000001
|
|
#define PYAS_OBJECT_THREAD 0x00000002
|
|
|
|
#define PYAS_MEMORY_PRIVATE 0x00000001
|
|
#define PYAS_MEMORY_MAPPED 0x00000002
|
|
#define PYAS_MEMORY_IMAGE 0x00000004
|
|
|
|
#define PYAS_PROTECT_EXECUTE 0x00000001
|
|
#define PYAS_PROTECT_EXECUTE_WRITE 0x00000002
|
|
|
|
typedef enum _RULE_TRI_STATE {
|
|
RuleTriAny = 0,
|
|
RuleTriTrue = 1,
|
|
RuleTriFalse = 2
|
|
} RULE_TRI_STATE;
|
|
|
|
typedef enum _RULE_OPERATION_MATCH {
|
|
RuleOperationAny = 0,
|
|
RuleOperationAll = 1
|
|
} RULE_OPERATION_MATCH;
|
|
|
|
typedef struct _DYNAMIC_RULE {
|
|
ULONG Code;
|
|
BOOLEAN Kill;
|
|
ULONG Priority;
|
|
RULE_CATEGORY Category;
|
|
ULONG Operations;
|
|
RULE_OPERATION_MATCH OperationMatch;
|
|
BOOLEAN Invalid;
|
|
|
|
PRULE_NODE Initiator;
|
|
PRULE_NODE InitiatorExclude;
|
|
PRULE_NODE InitiatorParent;
|
|
PRULE_NODE InitiatorParentExclude;
|
|
PRULE_NODE InitiatorProcessTree;
|
|
PRULE_NODE InitiatorProcessTreeExclude;
|
|
PRULE_NODE Target;
|
|
PRULE_NODE TargetExclude;
|
|
PRULE_NODE TargetProcessTree;
|
|
PRULE_NODE TargetProcessTreeExclude;
|
|
PRULE_NODE Creator;
|
|
PRULE_NODE CreatorExclude;
|
|
PRULE_NODE Parent;
|
|
PRULE_NODE ParentExclude;
|
|
PRULE_NODE CommandLine;
|
|
PRULE_NODE CommandLineExclude;
|
|
PRULE_NODE Extensions;
|
|
|
|
ULONG HandleTypes;
|
|
ULONG ObjectTypes;
|
|
ULONG MinimumRiskScore;
|
|
ULONG MaximumRiskScore;
|
|
ULONG ThreadMemoryTypes;
|
|
ULONG ThreadMemoryProtections;
|
|
ULONGLONG MinimumRegionSize;
|
|
ULONGLONG MaximumRegionSize;
|
|
RULE_TRI_STATE ParentMismatch;
|
|
RULE_TRI_STATE FileOpenNameAvailable;
|
|
RULE_TRI_STATE SubsystemProcess;
|
|
|
|
ULONG Threshold;
|
|
ULONG TimeWindow;
|
|
|
|
struct _DYNAMIC_RULE* Next;
|
|
} DYNAMIC_RULE, * PDYNAMIC_RULE;
|
|
|
|
BOOLEAN EvaluateDeviceRule(HANDLE ProcessId, PULONG OutCode, PBOOLEAN OutKill);
|
|
|
|
extern DRIVER_DATA GlobalData;
|
|
|
|
FLT_PREOP_CALLBACK_STATUS ProtectFile_PreCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext);
|
|
FLT_PREOP_CALLBACK_STATUS ProtectFile_PreWrite(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext);
|
|
FLT_PREOP_CALLBACK_STATUS ProtectFile_PreSetInfo(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext);
|
|
FLT_PREOP_CALLBACK_STATUS ProtectFile_FileSystemControl(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext);
|
|
FLT_PREOP_CALLBACK_STATUS ProtectFile_SetSecurity(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext);
|
|
FLT_PREOP_CALLBACK_STATUS ProtectBoot_PreDeviceControl(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext);
|
|
|
|
NTSTATUS InitializeRegistryProtection(PDRIVER_OBJECT DriverObject);
|
|
NTSTATUS UninitializeRegistryProtection();
|
|
|
|
NTSTATUS InitializeProcessProtection();
|
|
NTSTATUS UninitializeProcessProtection();
|
|
BOOLEAN GetProcessRelation(HANDLE ProcessId, PHANDLE ParentProcessId, PHANDLE CreatorProcessId);
|
|
|
|
NTSTATUS InitializeMemoryProtection(PDRIVER_OBJECT DriverObject);
|
|
NTSTATUS UninitializeMemoryProtection(BOOLEAN WaitWithoutTimeout);
|
|
|
|
NTSTATUS LoadRulesFromDisk(PUNICODE_STRING RegistryPath);
|
|
VOID UnloadRules();
|
|
|
|
NTSTATUS InitializeRulesEngine();
|
|
VOID UninitializeRulesEngine();
|
|
|
|
VOID AddDynamicWhitelist(PUNICODE_STRING RuleStr);
|
|
VOID RemoveDynamicWhitelist(PUNICODE_STRING RuleStr);
|
|
|
|
NTSTATUS LoadRuleFile(PCUNICODE_STRING FilePath);
|
|
VOID ClearDynamicRules();
|
|
|
|
VOID ProcessNotifyCallbackEx(PEPROCESS Process, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo);
|
|
NTSTATUS GetProcessImageName(HANDLE ProcessId, PUNICODE_STRING* ImageName);
|
|
|
|
ULONG SafeGetPyasPid();
|
|
VOID SafeSetPyasPid(ULONG Pid);
|
|
|
|
BOOLEAN IsProcessTrusted(HANDLE ProcessId);
|
|
BOOLEAN WildcardMatch(PCWSTR Pattern, PCWSTR String, USHORT StringLengthBytes);
|
|
|
|
BOOLEAN EvaluateProcessCreateRule(
|
|
HANDLE CreatorPid,
|
|
HANDLE ParentPid,
|
|
HANDLE ProcessId,
|
|
PCUNICODE_STRING TargetPath,
|
|
PCUNICODE_STRING CommandLine,
|
|
BOOLEAN FileOpenNameAvailable,
|
|
BOOLEAN IsSubsystemProcess,
|
|
PULONG OutCode,
|
|
PBOOLEAN OutKill
|
|
);
|
|
BOOLEAN EvaluateProcessAccessRule(
|
|
HANDLE SourcePid,
|
|
HANDLE TargetPid,
|
|
ULONG RequestedOperations,
|
|
ULONG HandleType,
|
|
ULONG ObjectType,
|
|
PULONG DeniedOperations,
|
|
PULONG OutCode,
|
|
PBOOLEAN OutKill
|
|
);
|
|
BOOLEAN EvaluateThreadRule(
|
|
HANDLE SourcePid,
|
|
HANDLE TargetPid,
|
|
PVOID StartAddress,
|
|
ULONG MemoryType,
|
|
ULONG MemoryProtection,
|
|
SIZE_T RegionSize,
|
|
PULONG OutCode,
|
|
PBOOLEAN OutKill
|
|
);
|
|
BOOLEAN EvaluateImageLoadRule(HANDLE ProcessId, PCUNICODE_STRING ImagePath, PIMAGE_INFO ImageInfo, PULONG OutCode, PBOOLEAN OutKill);
|
|
BOOLEAN EvaluateProcessRule(HANDLE ProcessId, PCUNICODE_STRING TargetPath, PCUNICODE_STRING CommandLine, PULONG OutCode, PBOOLEAN OutKill);
|
|
BOOLEAN EvaluateFileRule(HANDLE ProcessId, PCUNICODE_STRING TargetPath, ULONG Operation, PVOID WriteBuffer, ULONG WriteLength, PULONG OutCode, PBOOLEAN OutKill);
|
|
BOOLEAN EvaluateRegistryRule(HANDLE ProcessId, PCUNICODE_STRING KeyName, ULONG Operation, PULONG OutCode, PBOOLEAN OutKill);
|
|
BOOLEAN EvaluateMemoryRule(HANDLE SourcePid, HANDLE TargetPid, ULONG Operation, PULONG OutCode, PBOOLEAN OutKill);
|
|
BOOLEAN EvaluateProcessHandleRule(HANDLE SourcePid, HANDLE TargetPid, ULONG Operation, PULONG OutCode, PBOOLEAN OutKill);
|
|
|
|
VOID QueueRuleProcessTermination(HANDLE ProcessId, BOOLEAN Kill);
|
|
NTSTATUS SendMessageToUser(ULONG Code, ULONG Pid, PWCHAR Path, USHORT PathSize);
|
|
|
|
FORCEINLINE PVOID PyasAllocate(SIZE_T Size) {
|
|
return ExAllocatePool2(POOL_FLAG_NON_PAGED, Size, PYAS_POOL_TAG);
|
|
}
|
|
|
|
FORCEINLINE VOID PyasFree(PVOID Ptr) {
|
|
if (Ptr) ExFreePoolWithTag(Ptr, PYAS_POOL_TAG);
|
|
} |