mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
excellent progress :)
This commit is contained in:
parent
9e6b71e5df
commit
ef4127c167
18 changed files with 884 additions and 15 deletions
138
driver/callbacks.c
Normal file
138
driver/callbacks.c
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
#include "callbacks.h"
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "driver.h"
|
||||||
|
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
PQUEUE_HEAD report_queue = NULL;
|
||||||
|
|
||||||
|
VOID InitCallbackReportQueue( PBOOLEAN Status )
|
||||||
|
{
|
||||||
|
report_queue = QueueCreate();
|
||||||
|
|
||||||
|
if ( report_queue == NULL )
|
||||||
|
*Status = FALSE;
|
||||||
|
|
||||||
|
*Status = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID DeleteCallbackReportQueueHead()
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag( report_queue, QUEUE_POOL_TAG );
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID InsertReportToQueue( POPEN_HANDLE_FAILURE_REPORT Report )
|
||||||
|
{
|
||||||
|
QueuePush( report_queue, Report );
|
||||||
|
}
|
||||||
|
|
||||||
|
PVOID PopFirstReportFromQueue( report_queue )
|
||||||
|
{
|
||||||
|
return QueuePop( report_queue );
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID ObPostOpCallbackRoutine(
|
||||||
|
_In_ PVOID RegistrationContext,
|
||||||
|
_In_ POB_POST_OPERATION_INFORMATION OperationInformation
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
OB_PREOP_CALLBACK_STATUS ObPreOpCallbackRoutine(
|
||||||
|
_In_ PVOID RegistrationContext,
|
||||||
|
_In_ POB_PRE_OPERATION_INFORMATION OperationInformation
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER( RegistrationContext );
|
||||||
|
|
||||||
|
/* access mask to completely strip permissions */
|
||||||
|
ACCESS_MASK deny_access = SYNCHRONIZE | PROCESS_TERMINATE;
|
||||||
|
|
||||||
|
/* Access mask to be used for crss / lsass */
|
||||||
|
ACCESS_MASK downgrade_access = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This callback routine is executed in the context of the thread that
|
||||||
|
* is requesting to open said handle
|
||||||
|
*/
|
||||||
|
PEPROCESS process_creator = PsGetCurrentProcess();
|
||||||
|
PEPROCESS target_process = ( PEPROCESS )OperationInformation->Object;
|
||||||
|
|
||||||
|
LONG target_process_id = PsGetProcessId( target_process );
|
||||||
|
LONG process_creator_id = PsGetProcessId( process_creator );
|
||||||
|
|
||||||
|
LONG protected_process_id;
|
||||||
|
LONG parent_process_id;
|
||||||
|
|
||||||
|
GetProtectedProcessId( &protected_process_id );
|
||||||
|
GetProtectedProcessParentId( &parent_process_id );
|
||||||
|
|
||||||
|
LPCSTR process_creator_name = PsGetProcessImageFileName( process_creator );
|
||||||
|
LPCSTR target_process_name = PsGetProcessImageFileName( target_process );
|
||||||
|
|
||||||
|
if ( protected_process_id == target_process_id)
|
||||||
|
{
|
||||||
|
if ( !strcmp( process_creator_name, "lsass.exe" ) || !strcmp( process_creator_name, "csrss.exe" ) )
|
||||||
|
{
|
||||||
|
/* We will downgrade these handles later */
|
||||||
|
DEBUG_LOG( "Handles created by CSRSS and LSASS are allowed for now..." );
|
||||||
|
}
|
||||||
|
/* NOTE: try allowing only 1 handle from the proc creator */
|
||||||
|
else if ( parent_process_id == process_creator_id )
|
||||||
|
{
|
||||||
|
/* Allow handles created by the protected process' creator i.e explorer, cmd etc. */
|
||||||
|
DEBUG_LOG( "Process creator: %s handles are fine for now...", process_creator_name );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = deny_access;
|
||||||
|
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = deny_access;
|
||||||
|
DEBUG_LOG( "handle stripped from: %s", process_creator_name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OB_PREOP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID ProcessCreateNotifyRoutine(
|
||||||
|
_In_ HANDLE ParentId,
|
||||||
|
_In_ HANDLE ProcessId,
|
||||||
|
_In_ BOOLEAN Create
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PEPROCESS parent_process;
|
||||||
|
PEPROCESS target_process;
|
||||||
|
LONG parent_process_id;
|
||||||
|
LPCSTR target_process_name = NULL;
|
||||||
|
LPCSTR parent_process_name = NULL;
|
||||||
|
|
||||||
|
status = PsLookupProcessByProcessId( ParentId, &parent_process );
|
||||||
|
|
||||||
|
if ( !NT_SUCCESS( status ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
status = PsLookupProcessByProcessId( ProcessId, &target_process );
|
||||||
|
|
||||||
|
if ( !NT_SUCCESS( status ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
parent_process_name = PsGetProcessImageFileName( parent_process );
|
||||||
|
|
||||||
|
if ( !parent_process_name )
|
||||||
|
return;
|
||||||
|
|
||||||
|
target_process_name = PsGetProcessImageFileName( target_process );
|
||||||
|
|
||||||
|
if ( !target_process_name )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( !strcmp( target_process_name, "notepad.exe") )
|
||||||
|
{
|
||||||
|
parent_process_id = PsGetProcessId( target_process );
|
||||||
|
UpdateProtectedProcessId( parent_process_id );
|
||||||
|
LOG_INFO( "Protected process parent proc id: %lx", parent_process_id );
|
||||||
|
}
|
||||||
|
}
|
47
driver/callbacks.h
Normal file
47
driver/callbacks.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef CALLBACKS_H
|
||||||
|
#define CALLBACKS_H
|
||||||
|
|
||||||
|
#include <ntifs.h>
|
||||||
|
#include <wdftypes.h>
|
||||||
|
#include <wdf.h>
|
||||||
|
|
||||||
|
typedef struct _OPEN_HANDLE_FAILURE_REPORT
|
||||||
|
{
|
||||||
|
INT report_code;
|
||||||
|
INT is_kernel_handle;
|
||||||
|
LONG process_id;
|
||||||
|
LONG thread_id;
|
||||||
|
LONG desired_access;
|
||||||
|
CHAR process_name[ 64 ];
|
||||||
|
|
||||||
|
}OPEN_HANDLE_FAILURE_REPORT, *POPEN_HANDLE_FAILURE_REPORT;
|
||||||
|
|
||||||
|
//handle access masks
|
||||||
|
//https://learn.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
|
||||||
|
#define PROCESS_CREATE_PROCESS 0x0080
|
||||||
|
#define PROCESS_TERMINATE 0x0001
|
||||||
|
#define PROCESS_CREATE_THREAD 0x0002
|
||||||
|
#define PROCESS_DUP_HANDLE 0x0040
|
||||||
|
#define PROCESS_QUERY_INFORMATION 0x0400
|
||||||
|
#define PROCESS_QUERY_LIMITED_INFORMATION 0x1000
|
||||||
|
#define PROCESS_SET_INFORMATION 0x0200
|
||||||
|
#define PROCESS_SET_QUOTA 0x0100
|
||||||
|
#define PROCESS_SUSPEND_RESUME 0x0800
|
||||||
|
#define PROCESS_VM_OPERATION 0x0008
|
||||||
|
#define PROCESS_VM_READ 0x0010
|
||||||
|
#define PROCESS_VM_WRITE 0x0020
|
||||||
|
|
||||||
|
VOID ObPostOpCallbackRoutine(
|
||||||
|
_In_ PVOID RegistrationContext,
|
||||||
|
_In_ POB_POST_OPERATION_INFORMATION OperationInformation
|
||||||
|
);
|
||||||
|
|
||||||
|
OB_PREOP_CALLBACK_STATUS ObPreOpCallbackRoutine(
|
||||||
|
_In_ PVOID RegistrationContext,
|
||||||
|
_In_ POB_PRE_OPERATION_INFORMATION OperationInformation
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID InitCallbackReportQueue(PBOOLEAN Status);
|
||||||
|
VOID DeleteCallbackReportQueueHead();
|
||||||
|
|
||||||
|
#endif
|
344
driver/common.h
344
driver/common.h
|
@ -116,4 +116,348 @@ Thread Information Block: (GS register)
|
||||||
...
|
...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ntifs.h>
|
||||||
|
#include <wdftypes.h>
|
||||||
|
|
||||||
|
typedef struct _OBJECT_TYPE
|
||||||
|
{
|
||||||
|
LIST_ENTRY TypeList;
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
PVOID DefaultObject;
|
||||||
|
UCHAR Index;
|
||||||
|
ULONG TotalNumberOfObjects;
|
||||||
|
ULONG TotalNumberOfHandles;
|
||||||
|
ULONG HighWaterNumberOfObjects;
|
||||||
|
ULONG HighWaterNumberOfHandles;
|
||||||
|
PVOID TypeInfo; //_OBJECT_TYPE_INITIALIZER
|
||||||
|
EX_PUSH_LOCK TypeLock;
|
||||||
|
ULONG Key;
|
||||||
|
LIST_ENTRY CallbackList;
|
||||||
|
|
||||||
|
} OBJECT_TYPE, * POBJECT_TYPE;
|
||||||
|
|
||||||
|
typedef struct _PEB_LDR_DATA {
|
||||||
|
BYTE Reserved1[ 8 ];
|
||||||
|
PVOID Reserved2[ 3 ];
|
||||||
|
LIST_ENTRY InMemoryOrderModuleList;
|
||||||
|
} PEB_LDR_DATA, * PPEB_LDR_DATA;
|
||||||
|
|
||||||
|
typedef struct _LDR_DATA_TABLE_ENTRY {
|
||||||
|
PVOID Reserved1[ 2 ];
|
||||||
|
LIST_ENTRY InMemoryOrderLinks;
|
||||||
|
PVOID Reserved2[ 2 ];
|
||||||
|
PVOID DllBase;
|
||||||
|
PVOID Reserved3[ 2 ];
|
||||||
|
UNICODE_STRING FullDllName;
|
||||||
|
BYTE Reserved4[ 8 ];
|
||||||
|
PVOID Reserved5[ 3 ];
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4201) // we'll always use the Microsoft compiler
|
||||||
|
union {
|
||||||
|
ULONG CheckSum;
|
||||||
|
PVOID Reserved6;
|
||||||
|
} DUMMYUNIONNAME;
|
||||||
|
#pragma warning(pop)
|
||||||
|
ULONG TimeDateStamp;
|
||||||
|
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
|
||||||
|
|
||||||
|
typedef struct _PEB {
|
||||||
|
BYTE Reserved1[ 2 ];
|
||||||
|
BYTE BeingDebugged;
|
||||||
|
BYTE Reserved2[ 1 ];
|
||||||
|
PVOID Reserved3[ 2 ];
|
||||||
|
PPEB_LDR_DATA Ldr;
|
||||||
|
PVOID ProcessParameters;
|
||||||
|
PVOID Reserved4[ 3 ];
|
||||||
|
PVOID AtlThunkSListPtr;
|
||||||
|
PVOID Reserved5;
|
||||||
|
ULONG Reserved6;
|
||||||
|
PVOID Reserved7;
|
||||||
|
ULONG Reserved8;
|
||||||
|
ULONG AtlThunkSListPtr32;
|
||||||
|
PVOID Reserved9[ 45 ];
|
||||||
|
BYTE Reserved10[ 96 ];
|
||||||
|
PVOID PostProcessInitRoutine;
|
||||||
|
BYTE Reserved11[ 128 ];
|
||||||
|
PVOID Reserved12[ 1 ];
|
||||||
|
ULONG SessionId;
|
||||||
|
} PEB, * PPEB;
|
||||||
|
|
||||||
|
typedef struct _PEB32 {
|
||||||
|
UCHAR InheritedAddressSpace;
|
||||||
|
UCHAR ReadImageFileExecOptions;
|
||||||
|
UCHAR BeingDebugged;
|
||||||
|
UCHAR BitField;
|
||||||
|
ULONG Mutant;
|
||||||
|
ULONG ImageBaseAddress;
|
||||||
|
ULONG Ldr;
|
||||||
|
ULONG ProcessParameters;
|
||||||
|
ULONG SubSystemData;
|
||||||
|
ULONG ProcessHeap;
|
||||||
|
ULONG FastPebLock;
|
||||||
|
ULONG AtlThunkSListPtr;
|
||||||
|
ULONG IFEOKey;
|
||||||
|
ULONG CrossProcessFlags;
|
||||||
|
ULONG UserSharedInfoPtr;
|
||||||
|
ULONG SystemReserved;
|
||||||
|
ULONG AtlThunkSListPtr32;
|
||||||
|
ULONG ApiSetMap;
|
||||||
|
} PEB32, * PPEB32;
|
||||||
|
|
||||||
|
typedef struct _PEB_LDR_DATA32 {
|
||||||
|
ULONG Length;
|
||||||
|
UCHAR Initialized;
|
||||||
|
ULONG SsHandle;
|
||||||
|
LIST_ENTRY32 InLoadOrderModuleList;
|
||||||
|
LIST_ENTRY32 InMemoryOrderModuleList;
|
||||||
|
LIST_ENTRY32 InInitializationOrderModuleList;
|
||||||
|
} PEB_LDR_DATA32, * PPEB_LDR_DATA32;
|
||||||
|
|
||||||
|
typedef struct _LDR_DATA_TABLE_ENTRY32 {
|
||||||
|
LIST_ENTRY32 InLoadOrderLinks;
|
||||||
|
LIST_ENTRY32 InMemoryOrderLinks;
|
||||||
|
LIST_ENTRY32 InInitializationOrderLinks;
|
||||||
|
ULONG DllBase;
|
||||||
|
ULONG EntryPoint;
|
||||||
|
ULONG SizeOfImage;
|
||||||
|
UNICODE_STRING32 FullDllName;
|
||||||
|
UNICODE_STRING32 BaseDllName;
|
||||||
|
ULONG Flags;
|
||||||
|
USHORT LoadCount;
|
||||||
|
USHORT TlsIndex;
|
||||||
|
LIST_ENTRY32 HashLinks;
|
||||||
|
ULONG TimeDateStamp;
|
||||||
|
} LDR_DATA_TABLE_ENTRY32, * PLDR_DATA_TABLE_ENTRY32;
|
||||||
|
|
||||||
|
typedef struct _HANDLE_TABLE_ENTRY_INFO
|
||||||
|
{
|
||||||
|
ULONG AuditMask;
|
||||||
|
ULONG MaxRelativeAccessMask;
|
||||||
|
|
||||||
|
} HANDLE_TABLE_ENTRY_INFO, * PHANDLE_TABLE_ENTRY_INFO;
|
||||||
|
|
||||||
|
typedef union _EXHANDLE
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int TagBits : 2;
|
||||||
|
int Index : 30;
|
||||||
|
} u;
|
||||||
|
void* GenericHandleOverlay;
|
||||||
|
ULONG_PTR Value;
|
||||||
|
} EXHANDLE, * PEXHANDLE;
|
||||||
|
|
||||||
|
#pragma warning(disable : 4214 4201)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct _POOL_HEADER // Size=16
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned long PreviousSize : 8; // Size=4 Offset=0 BitOffset=0 BitCount=8
|
||||||
|
unsigned long PoolIndex : 8; // Size=4 Offset=0 BitOffset=8 BitCount=8
|
||||||
|
unsigned long BlockSize : 8; // Size=4 Offset=0 BitOffset=16 BitCount=8
|
||||||
|
unsigned long PoolType : 8; // Size=4 Offset=0 BitOffset=24 BitCount=8
|
||||||
|
};
|
||||||
|
unsigned long Ulong1; // Size=4 Offset=0
|
||||||
|
};
|
||||||
|
unsigned long PoolTag; // Size=4 Offset=4
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct _EPROCESS* ProcessBilled; // Size=8 Offset=8
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned short AllocatorBackTraceIndex; // Size=2 Offset=8
|
||||||
|
unsigned short PoolTagHash; // Size=2 Offset=10
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} POOL_HEADER, * PPOOL_HEADER;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
typedef struct _HANDLE_TABLE_ENTRY // Size=16
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
ULONG_PTR VolatileLowValue; // Size=8 Offset=0
|
||||||
|
ULONG_PTR LowValue; // Size=8 Offset=0
|
||||||
|
struct _HANDLE_TABLE_ENTRY_INFO* InfoTable; // Size=8 Offset=0
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG_PTR Unlocked : 1; // Size=8 Offset=0 BitOffset=0 BitCount=1
|
||||||
|
ULONG_PTR RefCnt : 16; // Size=8 Offset=0 BitOffset=1 BitCount=16
|
||||||
|
ULONG_PTR Attributes : 3; // Size=8 Offset=0 BitOffset=17 BitCount=3
|
||||||
|
ULONG_PTR ObjectPointerBits : 44; // Size=8 Offset=0 BitOffset=20 BitCount=44
|
||||||
|
};
|
||||||
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
|
ULONG_PTR HighValue; // Size=8 Offset=8
|
||||||
|
struct _HANDLE_TABLE_ENTRY* NextFreeHandleEntry; // Size=8 Offset=8
|
||||||
|
union _EXHANDLE LeafHandleValue; // Size=8 Offset=8
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG GrantedAccessBits : 25; // Size=4 Offset=8 BitOffset=0 BitCount=25
|
||||||
|
ULONG NoRightsUpgrade : 1; // Size=4 Offset=8 BitOffset=25 BitCount=1
|
||||||
|
ULONG Spare : 6; // Size=4 Offset=8 BitOffset=26 BitCount=6
|
||||||
|
};
|
||||||
|
};
|
||||||
|
ULONG TypeInfo; // Size=4 Offset=12
|
||||||
|
} HANDLE_TABLE_ENTRY, * PHANDLE_TABLE_ENTRY;
|
||||||
|
|
||||||
|
typedef struct _HANDLE_TABLE_FREE_LIST
|
||||||
|
{
|
||||||
|
EX_PUSH_LOCK FreeListLock;
|
||||||
|
PHANDLE_TABLE_ENTRY FirstFreeHandleEntry;
|
||||||
|
PHANDLE_TABLE_ENTRY LastFreeHandleEntry;
|
||||||
|
LONG HandleCount;
|
||||||
|
ULONG HighWaterMark;
|
||||||
|
} HANDLE_TABLE_FREE_LIST, * PHANDLE_TABLE_FREE_LIST;
|
||||||
|
|
||||||
|
typedef struct _HANDLE_TRACE_DB_ENTRY
|
||||||
|
{
|
||||||
|
CLIENT_ID ClientId;
|
||||||
|
PVOID Handle;
|
||||||
|
ULONG Type;
|
||||||
|
PVOID StackTrace[ 16 ];
|
||||||
|
|
||||||
|
} HANDLE_TRACE_DB_ENTRY, * PHANDLE_TRACE_DB_ENTRY;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _HANDLE_TRACE_DEBUG_INFO
|
||||||
|
{
|
||||||
|
LONG RefCount;
|
||||||
|
ULONG TableSize;
|
||||||
|
ULONG BitMaskFlags;
|
||||||
|
FAST_MUTEX CloseCompactionLock;
|
||||||
|
ULONG CurrentStackIndex;
|
||||||
|
HANDLE_TRACE_DB_ENTRY TraceDb[ 1 ];
|
||||||
|
|
||||||
|
} HANDLE_TRACE_DEBUG_INFO, * PHANDLE_TRACE_DEBUG_INFO;
|
||||||
|
|
||||||
|
typedef struct _HANDLE_TABLE
|
||||||
|
{
|
||||||
|
ULONG NextHandleNeedingPool;
|
||||||
|
LONG ExtraInfoPages;
|
||||||
|
ULONGLONG TableCode;
|
||||||
|
PEPROCESS QuotaProcess;
|
||||||
|
LIST_ENTRY HandleTableList;
|
||||||
|
ULONG UniqueProcessId;
|
||||||
|
union {
|
||||||
|
ULONG Flags;
|
||||||
|
struct {
|
||||||
|
UCHAR StrictFIFO : 1;
|
||||||
|
UCHAR EnableHandleExceptions : 1;
|
||||||
|
UCHAR Rundown : 1;
|
||||||
|
UCHAR Duplicated : 1;
|
||||||
|
UCHAR RaiseUMExceptionOnInvalidHandleClose : 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
EX_PUSH_LOCK HandleContentionEvent;
|
||||||
|
EX_PUSH_LOCK HandleTableLock;
|
||||||
|
union {
|
||||||
|
HANDLE_TABLE_FREE_LIST FreeLists[ 1 ];
|
||||||
|
UCHAR ActualEntry[ 32 ];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _HANDLE_TRACE_DEBUG_INFO* DebugInfo;
|
||||||
|
|
||||||
|
} HANDLE_TABLE, * PHANDLE_TABLE;
|
||||||
|
|
||||||
|
typedef BOOLEAN( *EX_ENUMERATE_HANDLE_ROUTINE )(
|
||||||
|
IN PHANDLE_TABLE_ENTRY HandleTableEntry,
|
||||||
|
IN HANDLE Handle,
|
||||||
|
IN PVOID EnumParameter
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _OBJECT_CREATE_INFORMATION
|
||||||
|
{
|
||||||
|
ULONG Attributes;
|
||||||
|
PVOID RootDirectory;
|
||||||
|
CHAR ProbeMode;
|
||||||
|
ULONG PagedPoolCharge;
|
||||||
|
ULONG NonPagedPoolCharge;
|
||||||
|
ULONG SecurityDescriptorCharge;
|
||||||
|
PVOID SecurityDescriptor;
|
||||||
|
struct _SECURITY_QUALITY_OF_SERVICE* SecurityQos;
|
||||||
|
struct _SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
|
||||||
|
|
||||||
|
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _OBJECT_HEADER
|
||||||
|
{
|
||||||
|
LONGLONG PointerCount;
|
||||||
|
union {
|
||||||
|
LONGLONG HandleCount;
|
||||||
|
PVOID NextToFree;
|
||||||
|
};
|
||||||
|
EX_PUSH_LOCK Lock;
|
||||||
|
UCHAR TypeIndex;
|
||||||
|
union {
|
||||||
|
UCHAR TraceFlags;
|
||||||
|
struct {
|
||||||
|
UCHAR DbgRefTrace : 1;
|
||||||
|
UCHAR DbgTracePermanent : 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
UCHAR InfoMask;
|
||||||
|
union {
|
||||||
|
UCHAR Flags;
|
||||||
|
struct {
|
||||||
|
UCHAR NewObject : 1;
|
||||||
|
UCHAR KernelObject : 1;
|
||||||
|
UCHAR KernelOnlyAccess : 1;
|
||||||
|
UCHAR ExclusiveObject : 1;
|
||||||
|
UCHAR PermanentObject : 1;
|
||||||
|
UCHAR DefaultSecurityQuota : 1;
|
||||||
|
UCHAR SingleHandleEntry : 1;
|
||||||
|
UCHAR DeletedInline : 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
ULONG Reserved;
|
||||||
|
union {
|
||||||
|
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
||||||
|
PVOID QuotaBlockCharged;
|
||||||
|
};
|
||||||
|
PVOID SecurityDescriptor;
|
||||||
|
QUAD Body;
|
||||||
|
} OBJECT_HEADER, * POBJECT_HEADER;
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
BOOLEAN
|
||||||
|
ExEnumHandleTable(
|
||||||
|
__in PHANDLE_TABLE HandleTable,
|
||||||
|
__in EX_ENUMERATE_HANDLE_ROUTINE EnumHandleProcedure,
|
||||||
|
__in PVOID EnumParameter,
|
||||||
|
__out_opt PHANDLE Handle
|
||||||
|
);
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
POBJECT_TYPE
|
||||||
|
NTAPI
|
||||||
|
ObGetObjectType(
|
||||||
|
_In_ PVOID Object
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _EX_PUSH_LOCK_WAIT_BLOCK* PEX_PUSH_LOCK_WAIT_BLOCK;
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
ExfUnblockPushLock(
|
||||||
|
_Inout_ PEX_PUSH_LOCK PushLock,
|
||||||
|
_Inout_opt_ PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock
|
||||||
|
);
|
||||||
|
|
||||||
|
LPCSTR
|
||||||
|
NTSYSAPI
|
||||||
|
NTAPI
|
||||||
|
PsGetProcessImageFileName(
|
||||||
|
PEPROCESS Process
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,6 +2,49 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "ioctl.h"
|
#include "ioctl.h"
|
||||||
|
#include "callbacks.h"
|
||||||
|
|
||||||
|
PVOID callback_registration_handle;
|
||||||
|
|
||||||
|
LONG protected_process_id;
|
||||||
|
LONG protected_process_parent_id;
|
||||||
|
KGUARDED_MUTEX mutex;
|
||||||
|
|
||||||
|
VOID UpdateProtectedProcessId(
|
||||||
|
_In_ LONG NewProcessId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
KeAcquireGuardedMutex( &mutex );
|
||||||
|
protected_process_id = NewProcessId;
|
||||||
|
KeReleaseGuardedMutex( &mutex );
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID GetProtectedProcessId(
|
||||||
|
_Out_ PLONG ProcessId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
KeAcquireGuardedMutex( &mutex );
|
||||||
|
*ProcessId = protected_process_id;
|
||||||
|
KeReleaseGuardedMutex( &mutex );
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID GetProtectedProcessParentId(
|
||||||
|
_Out_ PLONG ProcessId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
KeAcquireGuardedMutex( &mutex );
|
||||||
|
*ProcessId = protected_process_parent_id;
|
||||||
|
KeReleaseGuardedMutex( &mutex );
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID UpdateProtectedProcessParentId(
|
||||||
|
_In_ LONG NewProcessId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
KeAcquireGuardedMutex( &mutex );
|
||||||
|
protected_process_parent_id = NewProcessId;
|
||||||
|
KeReleaseGuardedMutex( &mutex );
|
||||||
|
}
|
||||||
|
|
||||||
VOID DriverUnload(
|
VOID DriverUnload(
|
||||||
_In_ PDRIVER_OBJECT DriverObject
|
_In_ PDRIVER_OBJECT DriverObject
|
||||||
|
@ -18,6 +61,7 @@ NTSTATUS DriverEntry(
|
||||||
{
|
{
|
||||||
UNREFERENCED_PARAMETER( RegistryPath );
|
UNREFERENCED_PARAMETER( RegistryPath );
|
||||||
|
|
||||||
|
BOOLEAN flag;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
status = IoCreateDevice(
|
status = IoCreateDevice(
|
||||||
|
@ -49,6 +93,43 @@ NTSTATUS DriverEntry(
|
||||||
DriverObject->MajorFunction[ IRP_MJ_DEVICE_CONTROL ] = DeviceControl;
|
DriverObject->MajorFunction[ IRP_MJ_DEVICE_CONTROL ] = DeviceControl;
|
||||||
DriverObject->DriverUnload = DriverUnload;
|
DriverObject->DriverUnload = DriverUnload;
|
||||||
|
|
||||||
|
KeInitializeGuardedMutex( &mutex );
|
||||||
|
|
||||||
|
InitCallbackReportQueue(&flag);
|
||||||
|
|
||||||
|
if ( !flag )
|
||||||
|
{
|
||||||
|
IoDeleteSymbolicLink( &DEVICE_SYMBOLIC_LINK );
|
||||||
|
IoDeleteDevice( DriverObject->DeviceObject );
|
||||||
|
return STATUS_FAILED_DRIVER_ENTRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
OB_CALLBACK_REGISTRATION callback_registration = { 0 };
|
||||||
|
OB_OPERATION_REGISTRATION operation_registration = { 0 };
|
||||||
|
|
||||||
|
operation_registration.ObjectType = PsProcessType;
|
||||||
|
operation_registration.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
|
||||||
|
operation_registration.PreOperation = ObPreOpCallbackRoutine;
|
||||||
|
operation_registration.PostOperation = ObPostOpCallbackRoutine;
|
||||||
|
|
||||||
|
callback_registration.Version = OB_FLT_REGISTRATION_VERSION;
|
||||||
|
callback_registration.OperationRegistration = &operation_registration;
|
||||||
|
callback_registration.OperationRegistrationCount = 1;
|
||||||
|
callback_registration.RegistrationContext = NULL;
|
||||||
|
|
||||||
|
status = ObRegisterCallbacks(
|
||||||
|
&callback_registration,
|
||||||
|
&callback_registration_handle
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !NT_SUCCESS( status ) )
|
||||||
|
{
|
||||||
|
DeleteCallbackReportQueueHead();
|
||||||
|
IoDeleteSymbolicLink( &DEVICE_SYMBOLIC_LINK );
|
||||||
|
IoDeleteDevice( DriverObject->DeviceObject );
|
||||||
|
return STATUS_FAILED_DRIVER_ENTRY;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_LOG( "DonnaAC Driver Entry Complete. type: %lx", DriverObject->DeviceObject->DeviceType );
|
DEBUG_LOG( "DonnaAC Driver Entry Complete. type: %lx", DriverObject->DeviceObject->DeviceType );
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
|
@ -8,4 +8,20 @@
|
||||||
UNICODE_STRING DEVICE_NAME = RTL_CONSTANT_STRING( L"\\Device\\DonnaAC" );
|
UNICODE_STRING DEVICE_NAME = RTL_CONSTANT_STRING( L"\\Device\\DonnaAC" );
|
||||||
UNICODE_STRING DEVICE_SYMBOLIC_LINK = RTL_CONSTANT_STRING( L"\\??\\DonnaAC" );
|
UNICODE_STRING DEVICE_SYMBOLIC_LINK = RTL_CONSTANT_STRING( L"\\??\\DonnaAC" );
|
||||||
|
|
||||||
|
VOID UpdateProtectedProcessId(
|
||||||
|
_In_ LONG NewProcessId
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID GetProtectedProcessId(
|
||||||
|
_Out_ PLONG ProcessId
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID GetProtectedProcessParentId(
|
||||||
|
_Out_ PLONG ProcessId
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID UpdateProtectedProcessParentId(
|
||||||
|
_In_ LONG NewProcessId
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -117,17 +117,21 @@
|
||||||
<FilesToPackage Include="$(TargetPath)" />
|
<FilesToPackage Include="$(TargetPath)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="callbacks.c" />
|
||||||
<ClCompile Include="driver.c" />
|
<ClCompile Include="driver.c" />
|
||||||
<ClCompile Include="ioctl.c" />
|
<ClCompile Include="ioctl.c" />
|
||||||
<ClCompile Include="modules.c" />
|
<ClCompile Include="modules.c" />
|
||||||
<ClCompile Include="nmi.c" />
|
<ClCompile Include="nmi.c" />
|
||||||
|
<ClCompile Include="queue.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="callbacks.h" />
|
||||||
<ClInclude Include="common.h" />
|
<ClInclude Include="common.h" />
|
||||||
<ClInclude Include="driver.h" />
|
<ClInclude Include="driver.h" />
|
||||||
<ClInclude Include="ioctl.h" />
|
<ClInclude Include="ioctl.h" />
|
||||||
<ClInclude Include="modules.h" />
|
<ClInclude Include="modules.h" />
|
||||||
<ClInclude Include="nmi.h" />
|
<ClInclude Include="nmi.h" />
|
||||||
|
<ClInclude Include="queue.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|
|
@ -36,6 +36,12 @@
|
||||||
<ClCompile Include="modules.c">
|
<ClCompile Include="modules.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="callbacks.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="queue.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="driver.h">
|
<ClInclude Include="driver.h">
|
||||||
|
@ -53,5 +59,11 @@
|
||||||
<ClInclude Include="modules.h">
|
<ClInclude Include="modules.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="callbacks.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="queue.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "nmi.h"
|
#include "nmi.h"
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
|
#include "driver.h"
|
||||||
|
|
||||||
NTSTATUS DeviceControl(
|
NTSTATUS DeviceControl(
|
||||||
_In_ PDRIVER_OBJECT DriverObject,
|
_In_ PDRIVER_OBJECT DriverObject,
|
||||||
|
@ -88,6 +89,13 @@ NTSTATUS DeviceControl(
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH:;
|
||||||
|
|
||||||
|
PDRIVER_INITIATION_INFORMATION information = ( PDRIVER_INITIATION_INFORMATION )Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
UpdateProtectedProcessId( information->protected_process_id );
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DEBUG_ERROR( "Invalid IOCTL passed to driver" );
|
DEBUG_ERROR( "Invalid IOCTL passed to driver" );
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -9,6 +9,13 @@
|
||||||
|
|
||||||
#define IOCCTL_RUN_NMI_CALLBACKS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2001, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
#define IOCCTL_RUN_NMI_CALLBACKS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2001, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
#define IOCTL_VALIDATE_DRIVER_OBJECTS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2002, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
#define IOCTL_VALIDATE_DRIVER_OBJECTS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2002, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2004, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
|
||||||
|
typedef struct _DRIVER_INITIATION_INFORMATION
|
||||||
|
{
|
||||||
|
LONG protected_process_id;
|
||||||
|
|
||||||
|
} DRIVER_INITIATION_INFORMATION, * PDRIVER_INITIATION_INFORMATION;
|
||||||
|
|
||||||
NTSTATUS DeviceControl(
|
NTSTATUS DeviceControl(
|
||||||
_In_ PDRIVER_OBJECT DriverObject,
|
_In_ PDRIVER_OBJECT DriverObject,
|
||||||
|
|
70
driver/queue.c
Normal file
70
driver/queue.c
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
PQUEUE_HEAD QueueCreate()
|
||||||
|
{
|
||||||
|
PQUEUE_HEAD head = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( PQUEUE_HEAD ), QUEUE_POOL_TAG );
|
||||||
|
|
||||||
|
if ( !head )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
head->end = NULL;
|
||||||
|
head->start = NULL;
|
||||||
|
|
||||||
|
KeInitializeSpinLock( head->lock );
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID QueuePush(
|
||||||
|
_In_ PQUEUE_HEAD Head,
|
||||||
|
_In_ PVOID Data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
KIRQL irql = KeGetCurrentIrql();
|
||||||
|
KeAcquireSpinLock( Head->lock, &irql );
|
||||||
|
|
||||||
|
PQUEUE_NODE temp = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( QUEUE_NODE ), QUEUE_POOL_TAG );
|
||||||
|
|
||||||
|
if ( !temp )
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
temp->data = Data;
|
||||||
|
temp->lock = Head->lock;
|
||||||
|
|
||||||
|
if ( Head->end != NULL )
|
||||||
|
Head->end->next = temp;
|
||||||
|
|
||||||
|
Head->end = temp;
|
||||||
|
|
||||||
|
if ( Head->start == NULL )
|
||||||
|
Head->start = temp;
|
||||||
|
|
||||||
|
end:
|
||||||
|
KeReleaseSpinLock( Head->lock, irql );
|
||||||
|
}
|
||||||
|
|
||||||
|
PVOID QueuePop(
|
||||||
|
_In_ PQUEUE_HEAD Head
|
||||||
|
)
|
||||||
|
{
|
||||||
|
KIRQL irql = KeGetCurrentIrql();
|
||||||
|
KeAcquireSpinLock( Head->lock, &irql );
|
||||||
|
|
||||||
|
PVOID data = NULL;
|
||||||
|
PQUEUE_NODE temp = Head->start;
|
||||||
|
|
||||||
|
if ( temp == NULL )
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
data = temp->data;
|
||||||
|
Head->start = temp->next;
|
||||||
|
|
||||||
|
if ( Head->end == temp )
|
||||||
|
Head->end = NULL;
|
||||||
|
|
||||||
|
ExFreePoolWithTag( temp, QUEUE_POOL_TAG );
|
||||||
|
|
||||||
|
end:
|
||||||
|
KeReleaseSpinLock( Head->lock, irql );
|
||||||
|
return data;
|
||||||
|
}
|
37
driver/queue.h
Normal file
37
driver/queue.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef QUEUE_H
|
||||||
|
#define QUEUE_H
|
||||||
|
|
||||||
|
#include <ntifs.h>
|
||||||
|
|
||||||
|
#define QUEUE_POOL_TAG 'qqqq'
|
||||||
|
|
||||||
|
typedef struct _QUEUE_NODE
|
||||||
|
{
|
||||||
|
struct _QUEUE_NODE* next;
|
||||||
|
PKSPIN_LOCK lock;
|
||||||
|
PVOID data;
|
||||||
|
|
||||||
|
}QUEUE_NODE, *PQUEUE_NODE;
|
||||||
|
|
||||||
|
typedef struct QUEUE_HEAD
|
||||||
|
{
|
||||||
|
struct _QUEUE_NODE* start;
|
||||||
|
struct _QUEUE_NODE* end;
|
||||||
|
PKSPIN_LOCK lock;
|
||||||
|
|
||||||
|
}QUEUE_HEAD, *PQUEUE_HEAD;
|
||||||
|
|
||||||
|
PQUEUE_NODE QueueCreate();
|
||||||
|
|
||||||
|
VOID QueuePush(
|
||||||
|
_In_ PQUEUE_HEAD Head,
|
||||||
|
_In_ PVOID Data
|
||||||
|
);
|
||||||
|
|
||||||
|
PVOID QueuePop(
|
||||||
|
_In_ PQUEUE_HEAD Head
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -10,16 +10,12 @@ namespace service
|
||||||
{
|
{
|
||||||
namespace Types
|
namespace Types
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public unsafe struct MODULE_VERIFICATION_CHECKSUM_FAILURE
|
public unsafe struct MODULE_VERIFICATION_CHECKSUM_FAILURE
|
||||||
{
|
{
|
||||||
[FieldOffset(0)]
|
|
||||||
public int ReportCode;
|
public int ReportCode;
|
||||||
[FieldOffset(0)]
|
|
||||||
public UInt64 ModuleBaseAddress;
|
public UInt64 ModuleBaseAddress;
|
||||||
[FieldOffset(0)]
|
|
||||||
public UInt64 ModuleSize;
|
public UInt64 ModuleSize;
|
||||||
[FieldOffset(0)]
|
|
||||||
public fixed char ModuleName[512];
|
public fixed char ModuleName[512];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.IO.Pipes;
|
using System.IO.Pipes;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using service.Types;
|
using service.Types;
|
||||||
|
|
||||||
|
@ -193,6 +194,19 @@ namespace service
|
||||||
Marshal.FreeHGlobal(ptr);
|
Marshal.FreeHGlobal(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
internal static extern bool GetNamedPipeClientProcessId(IntPtr Pipe, out uint ClientProcessId);
|
||||||
|
public static uint GetNamedPipeClientProcId(NamedPipeServerStream PipeServer)
|
||||||
|
{
|
||||||
|
UInt32 procId;
|
||||||
|
IntPtr pipeHandle = PipeServer.SafePipeHandle.DangerousGetHandle();
|
||||||
|
|
||||||
|
if (GetNamedPipeClientProcessId(pipeHandle, out procId))
|
||||||
|
return procId;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
|
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||||
|
|
|
@ -130,16 +130,92 @@ void kernelmode::Driver::VerifySystemModules()
|
||||||
free( buffer );
|
free( buffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernelmode::Driver::EnableObRegisterCallbacks()
|
/*
|
||||||
|
* HOW THIS WILL WORK:
|
||||||
|
*
|
||||||
|
* 1. On driver initiation, ObRegisterCallbacks will be registered
|
||||||
|
* 2. Each time a process that is not whitelisted tries to open a handle
|
||||||
|
* to our game we will store the report in an a report queue
|
||||||
|
* 3. the user mode app will then periodically query the driver asking
|
||||||
|
* how many pending reports there are
|
||||||
|
* 4. once the number is received, the app will allocate a buffer large enough
|
||||||
|
* for all the reports and once again call CompleteQueuedCallbackReports
|
||||||
|
* 5. This will then retrieve the reports into the buffer and from there
|
||||||
|
* we can iteratively report them the same way as we do with the system
|
||||||
|
* modules.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool kernelmode::Driver::QueueCallbackReportIrp(PHANDLE Event)
|
||||||
{
|
{
|
||||||
|
if ( !Event )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
OVERLAPPED io;
|
||||||
|
BOOLEAN status;
|
||||||
|
DWORD bytes_returned;
|
||||||
|
global::report_structures::OPEN_HANDLE_FAILURE_REPORT report;
|
||||||
|
|
||||||
|
io.hEvent = *Event;
|
||||||
|
|
||||||
|
status = DeviceIoControl(
|
||||||
|
this->driver_handle,
|
||||||
|
IOCTL_MONITOR_CALLBACKS_FOR_REPORTS,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&report,
|
||||||
|
sizeof( global::report_structures::OPEN_HANDLE_FAILURE_REPORT ),
|
||||||
|
&bytes_returned,
|
||||||
|
&io
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( status == NULL )
|
||||||
|
{
|
||||||
|
LOG_ERROR( "DeviceIoControl failed with status code 0x%x", GetLastError() );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
WaitForSingleObject( io.hEvent, INFINITE );
|
||||||
|
|
||||||
|
/* we EXPECTED to receive bytes so this is an error */
|
||||||
|
if ( bytes_returned == NULL )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernelmode::Driver::DisableObRegisterCallbacks()
|
void kernelmode::Driver::NotifyDriverOnProcessLaunch()
|
||||||
{
|
{
|
||||||
|
BOOLEAN status;
|
||||||
|
kernelmode::DRIVER_INITIATION_INFORMATION information;
|
||||||
|
information.protected_process_id = GetCurrentProcessId();
|
||||||
|
|
||||||
|
status = DeviceIoControl(
|
||||||
|
this->driver_handle,
|
||||||
|
IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH,
|
||||||
|
&information,
|
||||||
|
sizeof( kernelmode::DRIVER_INITIATION_INFORMATION ),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( status == NULL )
|
||||||
|
LOG_ERROR( "DeviceIoControl failed with status code 0x%x", GetLastError() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void kernelmode::Driver::CompleteQueuedCallbackReports()
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernelmode::Driver::EnableProcessLoadNotifyCallbacks()
|
void kernelmode::Driver::EnableProcessLoadNotifyCallbacks()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* note: no need for these since when the dll is loaded it will simply
|
||||||
|
* notify the driver.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernelmode::Driver::DisableProcessLoadNotifyCallbacks()
|
void kernelmode::Driver::DisableProcessLoadNotifyCallbacks()
|
||||||
|
@ -150,10 +226,6 @@ void kernelmode::Driver::ValidateKPRCBThreads()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernelmode::Driver::CheckForHypervisor()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void kernelmode::Driver::CheckDriverHeartbeat()
|
void kernelmode::Driver::CheckDriverHeartbeat()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#define IOCCTL_RUN_NMI_CALLBACKS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2001, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
#define IOCCTL_RUN_NMI_CALLBACKS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2001, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
#define IOCTL_VALIDATE_DRIVER_OBJECTS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2002, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
#define IOCTL_VALIDATE_DRIVER_OBJECTS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2002, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_MONITOR_CALLBACKS_FOR_REPORTS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2003, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_NOTIFY_DRIVER_ON_PROCESS_LAUNCH CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2004, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
|
||||||
namespace kernelmode
|
namespace kernelmode
|
||||||
{
|
{
|
||||||
|
@ -22,15 +24,20 @@ namespace kernelmode
|
||||||
|
|
||||||
void RunNmiCallbacks();
|
void RunNmiCallbacks();
|
||||||
void VerifySystemModules();
|
void VerifySystemModules();
|
||||||
void EnableObRegisterCallbacks();
|
bool QueueCallbackReportIrp( PHANDLE Event );
|
||||||
void DisableObRegisterCallbacks();
|
void NotifyDriverOnProcessLaunch();
|
||||||
|
void CompleteQueuedCallbackReports();
|
||||||
void EnableProcessLoadNotifyCallbacks();
|
void EnableProcessLoadNotifyCallbacks();
|
||||||
void DisableProcessLoadNotifyCallbacks();
|
void DisableProcessLoadNotifyCallbacks();
|
||||||
void ValidateKPRCBThreads();
|
void ValidateKPRCBThreads();
|
||||||
void CheckForHypervisor();
|
|
||||||
void CheckDriverHeartbeat();
|
void CheckDriverHeartbeat();
|
||||||
/* todo: driver integrity check */
|
/* todo: driver integrity check */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DRIVER_INITIATION_INFORMATION
|
||||||
|
{
|
||||||
|
LONG protected_process_id;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,3 +15,8 @@ void kernelmode::KManager::VerifySystemModules()
|
||||||
{
|
{
|
||||||
this->thread_pool->QueueJob( [ this ]() { this->driver_interface->VerifySystemModules(); } );
|
this->thread_pool->QueueJob( [ this ]() { this->driver_interface->VerifySystemModules(); } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kernelmode::KManager::MonitorCallbackReports()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace kernelmode
|
||||||
|
|
||||||
void RunNmiCallbacks();
|
void RunNmiCallbacks();
|
||||||
void VerifySystemModules();
|
void VerifySystemModules();
|
||||||
|
void MonitorCallbackReports();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace global
|
||||||
|
|
||||||
Report( std::shared_ptr<global::ThreadPool> ThreadPool, LPTSTR PipeName );
|
Report( std::shared_ptr<global::ThreadPool> ThreadPool, LPTSTR PipeName );
|
||||||
|
|
||||||
/* lock buffer, copy report, send to service then clear buffer */
|
/* lock buffer, attach header, copy report, send to service then clear buffer */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void ReportViolation( T* Report )
|
void ReportViolation( T* Report )
|
||||||
{
|
{
|
||||||
|
@ -105,6 +105,16 @@ namespace global
|
||||||
UINT64 driver_size;
|
UINT64 driver_size;
|
||||||
CHAR driver_name[ 128 ];
|
CHAR driver_name[ 128 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OPEN_HANDLE_FAILURE_REPORT
|
||||||
|
{
|
||||||
|
INT report_code;
|
||||||
|
INT is_kernel_handle;
|
||||||
|
LONG process_id;
|
||||||
|
LONG thread_id;
|
||||||
|
LONG desired_access;
|
||||||
|
CHAR process_name[ 64 ];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue