lil refactoring

This commit is contained in:
lhodges1 2024-01-15 12:01:14 +11:00
parent 643072e867
commit 267cbce0bf
15 changed files with 399 additions and 386 deletions

View file

@ -7,6 +7,7 @@
#include "thread.h"
#include "modules.h"
#include "imports.h"
#include "list.h"
STATIC
BOOLEAN
@ -66,6 +67,10 @@ UnregisterThreadCreateNotifyRoutine()
ImpPsRemoveCreateThreadNotifyRoutine(ThreadCreateNotifyRoutine);
}
/*
* While ExDeleteLookasideListEx already frees each item, we wanna allow ourselves to reduce the
* reference count to any objects we are referencing.
*/
VOID
CleanupProcessListOnDriverUnload()
{
@ -108,7 +113,8 @@ CleanupDriverListOnDriverUnload()
}
VOID
EnumerateThreadListWithCallbackRoutine(_In_ PVOID CallbackRoutine, _In_opt_ PVOID Context)
EnumerateThreadListWithCallbackRoutine(_In_ THREADLIST_CALLBACK_ROUTINE CallbackRoutine,
_In_opt_ PVOID Context)
{
PTHREAD_LIST_HEAD list = GetThreadList();
ImpKeAcquireGuardedMutex(&list->lock);
@ -120,8 +126,7 @@ EnumerateThreadListWithCallbackRoutine(_In_ PVOID CallbackRoutine, _In_opt_ PVOI
while (entry)
{
VOID (*callback_function_ptr)(PTHREAD_LIST_ENTRY, PVOID) = CallbackRoutine;
(*callback_function_ptr)(entry, Context);
CallbackRoutine(entry, Context);
entry = entry->list.Next;
}
@ -130,7 +135,8 @@ unlock:
}
VOID
EnumerateProcessListWithCallbackRoutine(_In_ PVOID CallbackRoutine, _In_opt_ PVOID Context)
EnumerateProcessListWithCallbackRoutine(_In_ PROCESSLIST_CALLBACK_ROUTINE CallbackRoutine,
_In_opt_ PVOID Context)
{
PPROCESS_LIST_HEAD list = GetProcessList();
ImpKeAcquireGuardedMutex(&list->lock);
@ -142,8 +148,7 @@ EnumerateProcessListWithCallbackRoutine(_In_ PVOID CallbackRoutine, _In_opt_ PVO
while (entry)
{
VOID (*callback_function_ptr)(PPROCESS_LIST_ENTRY, PVOID) = CallbackRoutine;
(*callback_function_ptr)(entry, Context);
CallbackRoutine(entry, Context);
entry = entry->list.Next;
}
@ -411,7 +416,7 @@ ProcessCreateNotifyRoutine(_In_ HANDLE ParentId, _In_ HANDLE ProcessId, _In_ BOO
PKPROCESS process = NULL;
PPROCESS_LIST_HEAD list = GetProcessList();
if (InterlockedExchange(&list->active, list->active) == FALSE)
if (!list->active)
return;
ImpPsLookupProcessByProcessId(ParentId, &parent);
@ -445,7 +450,7 @@ ProcessCreateNotifyRoutine(_In_ HANDLE ParentId, _In_ HANDLE ProcessId, _In_ BOO
ImpObDereferenceObject(entry->parent);
ImpObDereferenceObject(entry->process);
LookasideThreadListRemoveEntry(&list->start, entry, &list->lock);
LookasideListRemoveEntry(&list->start, entry, &list->lock);
}
}
@ -494,7 +499,7 @@ ThreadCreateNotifyRoutine(_In_ HANDLE ProcessId, _In_ HANDLE ThreadId, _In_ BOOL
ImpObDereferenceObject(entry->thread);
ImpObDereferenceObject(entry->owning_process);
LookasideThreadListRemoveEntry(&list->start, entry, &list->lock);
LookasideListRemoveEntry(&list->start, entry, &list->lock);
}
}
@ -503,11 +508,13 @@ ObPostOpCallbackRoutine(_In_ PVOID RegistrationContext,
_In_ POB_POST_OPERATION_INFORMATION OperationInformation)
{
PAGED_CODE();
UNREFERENCED_PARAMETER(RegistrationContext);
UNREFERENCED_PARAMETER(OperationInformation);
}
// https://www.sysnative.com/forums/threads/object-headers-handles-and-types.34987/
#define GET_OBJECT_HEADER_FROM_HANDLE(x) ((x << 4) | 0xffff000000000000);
OB_PREOP_CALLBACK_STATUS
ObPreOpCallbackRoutine(_In_ PVOID RegistrationContext,
_In_ POB_PRE_OPERATION_INFORMATION OperationInformation)
@ -642,6 +649,9 @@ ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY Ha
ImpExfUnblockPushLock(&HandleTable->HandleContentionEvent, NULL);
}
static UNICODE_STRING OBJECT_TYPE_PROCESS = RTL_CONSTANT_STRING(L"Process");
static UNICODE_STRING OBJECT_TYPE_THREAD = RTL_CONSTANT_STRING(L"Thread");
STATIC
BOOLEAN
EnumHandleCallback(_In_ PHANDLE_TABLE HandleTable,
@ -934,4 +944,62 @@ CleanupDriverTimerObjects(_Out_ PTIMER_OBJECT Timer)
ExFreePoolWithTag(Timer->dpc, POOL_TAG_DPC);
DEBUG_VERBOSE("Freed timer objects.");
}
VOID
UnregisterProcessObCallbacks()
{
PAGED_CODE();
PPROCESS_CONFIG config = GetProcessConfig();
AcquireDriverConfigLock();
if (config->callback_info.registration_handle)
{
ImpObUnRegisterCallbacks(config->callback_info.registration_handle);
config->callback_info.registration_handle = NULL;
}
ReleaseDriverConfigLock();
}
NTSTATUS
RegisterProcessObCallbacks()
{
PAGED_CODE();
NTSTATUS status = STATUS_UNSUCCESSFUL;
PPROCESS_CONFIG config = GetProcessConfig();
DEBUG_VERBOSE("Enabling ObRegisterCallbacks.");
AcquireDriverConfigLock();
OB_CALLBACK_REGISTRATION callback_registration = {0};
OB_OPERATION_REGISTRATION operation_registration = {0};
PCREATE_PROCESS_NOTIFY_ROUTINE_EX notify_routine = {0};
operation_registration.ObjectType = PsProcessType;
operation_registration.Operations |= OB_OPERATION_HANDLE_CREATE;
operation_registration.Operations |= 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 = ImpObRegisterCallbacks(&callback_registration,
&config->callback_info.registration_handle);
if (!NT_SUCCESS(status))
DEBUG_ERROR("ObRegisterCallbacks failed with status %x", status);
ReleaseDriverConfigLock();
return status;
}
VOID
InitialiseObCallbacksConfiguration(_Out_ PPROCESS_CONFIG ProcessConfig)
{
ImpKeInitializeGuardedMutex(&ProcessConfig->callback_info.lock);
}

View file

@ -1,10 +1,16 @@
#ifndef CALLBACKS_H
#define CALLBACKS_H
#include <ntifs.h>
#include <wdftypes.h>
#include <wdf.h>
#include "common.h"
#include "driver.h"
#include "common.h"
#include <wdf.h>
typedef void (*THREADLIST_CALLBACK_ROUTINE)(_In_ PTHREAD_LIST_ENTRY ThreadListEntry,
_In_opt_ PVOID Context);
typedef void (*PROCESSLIST_CALLBACK_ROUTINE)(_In_ PPROCESS_LIST_ENTRY ProcessListEntry,
_In_opt_ PVOID Context);
#define HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH 64
@ -19,31 +25,6 @@ typedef struct _OPEN_HANDLE_FAILURE_REPORT
} 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
// https://www.sysnative.com/forums/threads/object-headers-handles-and-types.34987/
#define GET_OBJECT_HEADER_FROM_HANDLE(x) ((x << 4) | 0xffff000000000000)
static const uintptr_t EPROCESS_IMAGE_FILE_NAME_OFFSET = 0x5a8;
static const uintptr_t EPROCESS_HANDLE_TABLE_OFFSET = 0x570;
static const uintptr_t EPROCESS_PLIST_ENTRY_OFFSET = 0x448;
static UNICODE_STRING OBJECT_TYPE_PROCESS = RTL_CONSTANT_STRING(L"Process");
static UNICODE_STRING OBJECT_TYPE_THREAD = RTL_CONSTANT_STRING(L"Thread");
#define DRIVER_PATH_LENGTH 0x100
#define SHA_256_HASH_LENGTH 32
@ -97,10 +78,12 @@ VOID
FindProcessListEntryByProcess(_In_ PKPROCESS Process, _Inout_ PPROCESS_LIST_ENTRY* Entry);
VOID
EnumerateThreadListWithCallbackRoutine(_In_ PVOID CallbackRoutine, _In_opt_ PVOID Context);
EnumerateThreadListWithCallbackRoutine(_In_ THREADLIST_CALLBACK_ROUTINE CallbackRoutine,
_In_opt_ PVOID Context);
VOID
EnumerateProcessListWithCallbackRoutine(_In_ PVOID CallbackRoutine, _In_opt_ PVOID Context);
EnumerateProcessListWithCallbackRoutine(_In_ PROCESSLIST_CALLBACK_ROUTINE CallbackRoutine,
_In_opt_ PVOID Context);
VOID
FindDriverEntryByBaseAddress(_In_ PVOID ImageBase, _Out_ PDRIVER_LIST_ENTRY* Entry);
@ -131,4 +114,13 @@ UnregisterImageLoadNotifyRoutine();
VOID
UnregisterThreadCreateNotifyRoutine();
VOID
UnregisterProcessObCallbacks();
NTSTATUS
RegisterProcessObCallbacks();
VOID
InitialiseObCallbacksConfiguration(_Out_ PPROCESS_CONFIG ProcessConfig);
#endif

View file

@ -89,18 +89,6 @@ typedef struct _PROCESS_LIST_ENTRY
} PROCESS_LIST_ENTRY, *PPROCESS_LIST_ENTRY;
#define DRIVER_PATH_MAX_LENGTH 512
#define MOTHERBOARD_SERIAL_CODE_LENGTH 64
#define DEVICE_DRIVE_0_SERIAL_CODE_LENGTH 64
#define MAX_REPORTS_PER_IRP 20
#define POOL_TAG_STRINGS 'strs'
#define IOCTL_STORAGE_QUERY_PROPERTY 0x002D1400
#define MAXIMUM_APC_CONTEXTS 10
/*
* ioctl_flag consists of the first 16 bits of the Function part of the CTL code
* cookie_value consists of a static 16 bit value generated by the user mode app on startup
@ -150,6 +138,18 @@ typedef enum _PROCESSOR_TYPE
#define VENDOR_STRING_MAX_LENGTH 256
#define DRIVER_PATH_MAX_LENGTH 512
#define MOTHERBOARD_SERIAL_CODE_LENGTH 64
#define DEVICE_DRIVE_0_SERIAL_CODE_LENGTH 64
#define MAX_REPORTS_PER_IRP 20
#define POOL_TAG_STRINGS 'strs'
#define IOCTL_STORAGE_QUERY_PROPERTY 0x002D1400
#define MAXIMUM_APC_CONTEXTS 10
typedef struct _SYSTEM_INFORMATION
{
CHAR motherboard_serial[MOTHERBOARD_SERIAL_CODE_LENGTH];
@ -184,6 +184,22 @@ typedef struct _IRP_QUEUE_ENTRY
} IRP_QUEUE_ENTRY, *PIRP_QUEUE_ENTRY;
/*
* This structure can change at anytime based on whether
* the target process to protect is open / closed / changes etc.
*/
typedef struct _PROCESS_CONFIG
{
BOOLEAN initialised;
ULONG um_handle;
PVOID km_handle;
PEPROCESS process;
OB_CALLBACKS_CONFIG callback_info;
UINT16 cookie;
KGUARDED_MUTEX lock;
} PROCESS_CONFIG, *PPROCESS_CONFIG;
#define NMI_CONTEXT_POOL '7331'
#define STACK_FRAMES_POOL 'loop'
#define INVALID_DRIVER_LIST_HEAD_POOL 'rwar'
@ -212,7 +228,7 @@ typedef struct _IRP_QUEUE_ENTRY
#define MODULES_REPORT_POOL_TAG 'modu'
#define POOL_TAG_LIST_ITEM 'tsil'
#define POOL_TAG_THREAD_LIST 'list'
#define POOL_TAG_PROCESS_LIST 'plis'
#define POOL_TAG_PROCESS_LIST 'plis'
#define POOL_TAG_DRIVER_LIST 'drvl'
#define POOL_TAG_IRP_QUEUE 'irpp'
#define POOL_TAG_TIMER 'time'
@ -242,6 +258,9 @@ typedef struct _IRP_QUEUE_ENTRY
#define EPROCESS_IMAGE_NAME_OFFSET 0x5a8
#define EPROCESS_PEB_OFFSET 0x550
#define EPROCESS_SECTION_BASE_OFFSET 0x520
#define EPROCESS_IMAGE_FILE_NAME_OFFSET 0x5a8
#define EPROCESS_HANDLE_TABLE_OFFSET 0x570
#define EPROCESS_PLIST_ENTRY_OFFSET 0x448
#define KPROCESS_THREADLIST_OFFSET 0x030
#define KPROCESS_DIRECTORY_TABLE_BASE_OFFSET 0x028
@ -1651,4 +1670,17 @@ PsGetNextProcessThread(IN PEPROCESS Process, IN PETHREAD Thread OPTIONAL);
#define SECONDS(seconds) (((signed __int64)(seconds)) * MILLISECONDS(1000L))
// 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_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
#endif

View file

@ -81,10 +81,6 @@ DrvLoadInitialiseDriverConfig(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_ST
# pragma alloc_text(PAGE, GetDriverConfigSystemInformation)
# pragma alloc_text(PAGE, RegistryPathQueryCallbackRoutine)
# pragma alloc_text(PAGE, TerminateProtectedProcessOnViolation)
# pragma alloc_text(PAGE, ProcCloseDisableObCallbacks)
# pragma alloc_text(PAGE, ProcCloseClearProcessConfiguration)
# pragma alloc_text(PAGE, ProcLoadEnableObCallbacks)
# pragma alloc_text(PAGE, ProcLoadInitialiseProcessConfig)
# pragma alloc_text(PAGE, DrvUnloadUnregisterObCallbacks)
# pragma alloc_text(PAGE, DrvUnloadFreeConfigStrings)
# pragma alloc_text(PAGE, DrvUnloadFreeSymbolicLink)
@ -93,28 +89,11 @@ DrvLoadInitialiseDriverConfig(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_ST
# pragma alloc_text(PAGE, DrvLoadEnableNotifyRoutines)
# pragma alloc_text(PAGE, DrvLoadEnableNotifyRoutines)
# pragma alloc_text(PAGE, DrvLoadInitialiseObCbConfig)
// # pragma alloc_text(PAGE, DrvLoadInitialiseReportQueue)
# pragma alloc_text(PAGE, DrvLoadInitialiseProcessConfig)
# pragma alloc_text(PAGE, DrvLoadInitialiseDriverConfig)
# pragma alloc_text(PAGE, ReadProcessInitialisedConfigFlag)
#endif
/*
* This structure can change at anytime based on whether
* the target process to protect is open / closed / changes etc.
*/
typedef struct _PROCESS_CONFIG
{
BOOLEAN initialised;
ULONG um_handle;
PVOID km_handle;
PEPROCESS process;
OB_CALLBACKS_CONFIG callback_info;
UINT16 cookie;
KGUARDED_MUTEX lock;
} PROCESS_CONFIG, *PPROCESS_CONFIG;
typedef struct _DRIVER_CONFIG
{
UNICODE_STRING unicode_driver_name;
@ -177,6 +156,12 @@ IsDriverUnloading()
g_DriverConfig->unload_in_progress);
}
PPROCESS_CONFIG
GetProcessConfig()
{
return &g_DriverConfig->process_config;
}
VOID
GetCallbackConfigStructure(_Out_ POB_CALLBACKS_CONFIG* CallbackConfiguration)
{
@ -309,22 +294,6 @@ GetProtectedProcessId(_Out_ PLONG ProcessId)
ImpKeReleaseGuardedMutex(&g_DriverConfig->process_config.lock);
}
VOID
ProcCloseDisableObCallbacks()
{
PAGED_CODE();
ImpKeAcquireGuardedMutex(&g_DriverConfig->process_config.callback_info.lock);
if (g_DriverConfig->process_config.callback_info.registration_handle)
{
ImpObUnRegisterCallbacks(
g_DriverConfig->process_config.callback_info.registration_handle);
g_DriverConfig->process_config.callback_info.registration_handle = NULL;
}
ImpKeReleaseGuardedMutex(&g_DriverConfig->process_config.callback_info.lock);
}
VOID
ProcCloseClearProcessConfiguration()
{
@ -339,50 +308,6 @@ ProcCloseClearProcessConfiguration()
ImpKeReleaseGuardedMutex(&g_DriverConfig->process_config.lock);
}
// VOID
// ImageLoadSetProcessId(_In_ HANDLE ProcessId)
//{
// ImpKeAcquireGuardedMutex(&process_config.lock);
// process_config.km_handle = (ULONG)ProcessId;
// ImpKeReleaseGuardedMutex(&process_config.lock);
// }
NTSTATUS
ProcLoadEnableObCallbacks()
{
PAGED_CODE();
NTSTATUS status = STATUS_UNSUCCESSFUL;
DEBUG_VERBOSE("Enabling ObRegisterCallbacks.");
ImpKeAcquireGuardedMutex(&g_DriverConfig->process_config.lock);
OB_CALLBACK_REGISTRATION callback_registration = {0};
OB_OPERATION_REGISTRATION operation_registration = {0};
PCREATE_PROCESS_NOTIFY_ROUTINE_EX notify_routine = {0};
operation_registration.ObjectType = PsProcessType;
operation_registration.Operations |= OB_OPERATION_HANDLE_CREATE;
operation_registration.Operations |= 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 = ImpObRegisterCallbacks(
&callback_registration,
&g_DriverConfig->process_config.callback_info.registration_handle);
if (!NT_SUCCESS(status))
DEBUG_ERROR("ObRegisterCallbacks failed with status %x", status);
ImpKeReleaseGuardedMutex(&g_DriverConfig->process_config.lock);
return status;
}
NTSTATUS
ProcLoadInitialiseProcessConfig(_In_ PIRP Irp)
{
@ -438,7 +363,7 @@ VOID
DrvUnloadUnregisterObCallbacks()
{
PAGED_CODE();
ProcCloseDisableObCallbacks();
UnregisterProcessObCallbacks();
}
STATIC
@ -641,14 +566,6 @@ DrvLoadSetupDriverLists()
return status;
}
STATIC
NTSTATUS
DrvLoadInitialiseObCbConfig()
{
PAGED_CODE();
ImpKeInitializeGuardedMutex(&g_DriverConfig->process_config.callback_info.lock);
}
STATIC
VOID
DrvLoadInitialiseReportQueue()
@ -665,6 +582,14 @@ DrvLoadInitialiseProcessConfig()
ImpKeInitializeGuardedMutex(&g_DriverConfig->process_config.lock);
}
STATIC
NTSTATUS
DrvLoadInitialiseObCbConfig()
{
PAGED_CODE();
InitialiseObCallbacksConfiguration(&g_DriverConfig->process_config);
}
/*
* Regular routines
*/

View file

@ -1,11 +1,10 @@
#ifndef DRIVER_H
#define DRIVER_H
#include <ntifs.h>
#include <wdftypes.h>
#include "common.h"
#include <wdf.h>
#include "common.h"
#include "queue.h"
#include "modules.h"
#include "integrity.h"
@ -29,12 +28,6 @@ QueryActiveApcContextsForCompletion();
VOID
TerminateProtectedProcessOnViolation();
NTSTATUS
ProcLoadEnableObCallbacks();
VOID
ProcCloseDisableObCallbacks();
VOID
ProcCloseClearProcessConfiguration();
@ -95,4 +88,7 @@ ReleaseDriverConfigLock();
BOOLEAN
IsDriverUnloading();
PPROCESS_CONFIG
GetProcessConfig();
#endif

View file

@ -251,6 +251,7 @@
<ClCompile Include="imports.c" />
<ClCompile Include="integrity.c" />
<ClCompile Include="ioctl.c" />
<ClCompile Include="list.c" />
<ClCompile Include="modules.c" />
<ClCompile Include="pool.c" />
<ClCompile Include="queue.c" />
@ -266,6 +267,7 @@
<ClInclude Include="imports.h" />
<ClInclude Include="integrity.h" />
<ClInclude Include="ioctl.h" />
<ClInclude Include="list.h" />
<ClInclude Include="modules.h" />
<ClInclude Include="pool.h" />
<ClInclude Include="queue.h" />

View file

@ -57,6 +57,9 @@
<ClCompile Include="apc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="list.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="driver.h">
@ -98,6 +101,9 @@
<ClInclude Include="apc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="list.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<MASM Include="arch.asm">

View file

@ -19,15 +19,6 @@ typedef struct _SYSTEM_MODULE_INFORMATION
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
// #pragma pack(1)
// typedef struct VERIFICATION_CONTEXT
//{
// // PSYSTEM_MODULE_INFORMATION module_info;
//
//
// } VERIFICATION_CONTEXT, *PVERIFICATION_CONTEXT;
// #pragma pack()
#define VERIFICATION_THREAD_COUNT 4
typedef struct _SYS_MODULE_VAL_CONTEXT
@ -101,11 +92,6 @@ ScanForSignature(_In_ PVOID BaseAddress,
_In_ LPCSTR Signature,
_In_ SIZE_T SignatureLength);
// NTSTATUS
// DetermineIfTestSigningIsEnabled(
// _Inout_ PBOOLEAN Result
//);
NTSTATUS
ValidateNtoskrnl();

View file

@ -9,6 +9,7 @@
#include "queue.h"
#include "hv.h"
#include "imports.h"
#include "list.h"
STATIC
NTSTATUS
@ -192,7 +193,6 @@ ValidateIrpInputBuffer(_In_ PIRP Irp, _In_ ULONG RequiredSize)
return STATUS_SUCCESS;
}
//_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
NTSTATUS
DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
{
@ -285,7 +285,7 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
goto end;
}
status = ProcLoadEnableObCallbacks();
status = RegisterProcessObCallbacks();
if (!NT_SUCCESS(status))
DEBUG_ERROR("EnableObCallbacks failed with status %x", status);
@ -381,7 +381,7 @@ DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
DEBUG_INFO("IOCTL_NOTIFY_DRIVER_ON_PROCESS_TERMINATION Received");
ProcCloseClearProcessConfiguration();
ProcCloseDisableObCallbacks();
UnregisterProcessObCallbacks();
break;
@ -538,7 +538,7 @@ DeviceClose(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
/* we also lose reports here, so sohuld pass em into the irp before freeing */
FreeGlobalReportQueueObjects();
ProcCloseClearProcessConfiguration();
ProcCloseDisableObCallbacks();
UnregisterProcessObCallbacks();
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;

View file

@ -12,15 +12,14 @@ typedef struct _DRIVER_INITIATION_INFORMATION
} DRIVER_INITIATION_INFORMATION, *PDRIVER_INITIATION_INFORMATION;
//_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
NTSTATUS
DeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp);
_Dispatch_type_(IRP_MJ_CLOSE) NTSTATUS
DeviceClose(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp);
NTSTATUS
DeviceClose(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp);
_Dispatch_type_(IRP_MJ_CREATE) NTSTATUS
DeviceCreate(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp);
NTSTATUS
DeviceCreate(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp);
NTSTATUS
ValidateIrpOutputBuffer(_In_ PIRP Irp, _In_ ULONG RequiredSize);

180
driver/list.c Normal file
View file

@ -0,0 +1,180 @@
#include "list.h"
#include "imports.h"
#include "driver.h"
/*
* Simple thread safe linked list implementation. All structures should begin
* with a SINGLE_LIST_ENTRY structure provided by the windows API. for example:
*
* typedef struct _LIST_ENTRY_STRUCTURE
* {
* SINGLE_LIST_ENTRY list;
* PVOID address;
* UINT32 data;
* ...
* };
*
* This common structure layout allows us to pass in a callback routine when freeing
* allowing immense flexibility to ensure we can free and/or deference any objects
* that are referenced in said object.
*
* I've opted to use a mutex rather then a spinlock since there are many times we
* enumerate the list for extended periods aswell as queue up many insertions at
* once.
*/
#define LIST_POOL_TAG 'list'
VOID
ListInit(_Inout_ PSINGLE_LIST_ENTRY Head, _Inout_ PKGUARDED_MUTEX Lock)
{
ImpKeInitializeGuardedMutex(Lock);
Head->Next = NULL;
}
VOID
ListInsert(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY NewEntry,
_In_ PKGUARDED_MUTEX Lock)
{
ImpKeAcquireGuardedMutex(Lock);
PSINGLE_LIST_ENTRY old_entry = Head->Next;
Head->Next = NewEntry;
NewEntry->Next = old_entry;
ImpKeReleaseGuardedMutex(Lock);
}
/*
* Assuming the SINGLE_LIST_ENTRY is the first item in the structure, we
* can pass a callback routine to be called before the free occurs. This
* allows us to dereference/free structure specific items whilst still allowing
* the list to remain flexible.
*/
BOOLEAN
ListFreeFirstEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_In_ PKGUARDED_MUTEX Lock,
_In_opt_ FREE_LIST_ITEM_CALLBACK CallbackRoutine)
{
BOOLEAN result = FALSE;
ImpKeAcquireGuardedMutex(Lock);
if (Head->Next)
{
PSINGLE_LIST_ENTRY entry = Head->Next;
if (CallbackRoutine)
CallbackRoutine(entry);
Head->Next = Head->Next->Next;
ImpExFreePoolWithTag(entry, POOL_TAG_THREAD_LIST);
result = TRUE;
}
ImpKeReleaseGuardedMutex(Lock);
return result;
}
/*
* If we are removing a specific entry, its assumed we have freed and/or dereferenced
* any fields in the structure.
*/
VOID
ListRemoveEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY Entry,
_In_ PKGUARDED_MUTEX Lock)
{
ImpKeAcquireGuardedMutex(Lock);
PSINGLE_LIST_ENTRY entry = Head->Next;
if (!entry)
goto unlock;
if (entry == Entry)
{
Head->Next = entry->Next;
ImpExFreePoolWithTag(Entry, POOL_TAG_THREAD_LIST);
goto unlock;
}
while (entry->Next)
{
if (entry->Next == Entry)
{
entry->Next = Entry->Next;
ImpExFreePoolWithTag(Entry, POOL_TAG_THREAD_LIST);
goto unlock;
}
entry = entry->Next;
}
unlock:
ImpKeReleaseGuardedMutex(Lock);
}
VOID
LookasideListRemoveEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY Entry,
_In_ PKGUARDED_MUTEX Lock)
{
ImpKeAcquireGuardedMutex(Lock);
PTHREAD_LIST_HEAD head = GetThreadList();
PSINGLE_LIST_ENTRY entry = Head->Next;
if (!entry)
goto unlock;
if (entry == Entry)
{
Head->Next = entry->Next;
ExFreeToLookasideListEx(&head->lookaside_list, Entry);
goto unlock;
}
while (entry->Next)
{
if (entry->Next == Entry)
{
entry->Next = Entry->Next;
ExFreeToLookasideListEx(&head->lookaside_list, Entry);
goto unlock;
}
entry = entry->Next;
}
unlock:
ImpKeReleaseGuardedMutex(Lock);
}
BOOLEAN
LookasideListFreeFirstEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_In_ PKGUARDED_MUTEX Lock,
_In_opt_ FREE_LIST_ITEM_CALLBACK CallbackRoutine)
{
ImpKeAcquireGuardedMutex(Lock);
PTHREAD_LIST_HEAD head = GetThreadList();
BOOLEAN result = FALSE;
if (Head->Next)
{
PSINGLE_LIST_ENTRY entry = Head->Next;
if (CallbackRoutine)
CallbackRoutine(entry);
Head->Next = Head->Next->Next;
ExFreeToLookasideListEx(&head->lookaside_list, entry);
result = TRUE;
}
ImpKeReleaseGuardedMutex(Lock);
return result;
}

36
driver/list.h Normal file
View file

@ -0,0 +1,36 @@
#ifndef LIST_H
#define LIST_H
#include "common.h"
typedef void (*FREE_LIST_ITEM_CALLBACK)(_In_ PVOID Entry);
VOID
LookasideListRemoveEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY Entry,
_In_ PKGUARDED_MUTEX Lock);
BOOLEAN
LookasideListFreeFirstEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_In_ PKGUARDED_MUTEX Lock,
_In_opt_ FREE_LIST_ITEM_CALLBACK CallbackRoutine);
VOID
ListInit(_Inout_ PSINGLE_LIST_ENTRY Head, _Inout_ PKGUARDED_MUTEX Lock);
VOID
ListInsert(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY NewEntry,
_In_ PKGUARDED_MUTEX Lock);
BOOLEAN
ListFreeFirstEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_In_ PKGUARDED_MUTEX Lock,
_In_opt_ FREE_LIST_ITEM_CALLBACK CallbackRoutine);
VOID
ListRemoveEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY Entry,
_In_ PKGUARDED_MUTEX Lock);
#endif

View file

@ -266,183 +266,4 @@ end:
DEBUG_VERBOSE("All reports moved into the IRP, sending to usermode.");
return STATUS_SUCCESS;
}
/*
* Simple thread safe linked list implementation. All structures should begin
* with a SINGLE_LIST_ENTRY structure provided by the windows API. for example:
*
* typedef struct _LIST_ENTRY_STRUCTURE
* {
* SINGLE_LIST_ENTRY list;
* PVOID address;
* UINT32 data;
* ...
* };
*
* This common structure layout allows us to pass in a callback routine when freeing
* allowing immense flexibility to ensure we can free and/or deference any objects
* that are referenced in said object.
*
* I've opted to use a mutex rather then a spinlock since there are many times we
* enumerate the list for extended periods aswell as queue up many insertions at
* once.
*/
VOID
ListInit(_Inout_ PSINGLE_LIST_ENTRY Head, _Inout_ PKGUARDED_MUTEX Lock)
{
ImpKeInitializeGuardedMutex(Lock);
Head->Next = NULL;
}
VOID
ListInsert(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY NewEntry,
_In_ PKGUARDED_MUTEX Lock)
{
ImpKeAcquireGuardedMutex(Lock);
PSINGLE_LIST_ENTRY old_entry = Head->Next;
Head->Next = NewEntry;
NewEntry->Next = old_entry;
ImpKeReleaseGuardedMutex(Lock);
}
/*
* Assuming the SINGLE_LIST_ENTRY is the first item in the structure, we
* can pass a callback routine to be called before the free occurs. This
* allows us to dereference/free structure specific items whilst still allowing
* the list to remain flexible.
*/
BOOLEAN
ListFreeFirstEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_In_ PKGUARDED_MUTEX Lock,
_In_opt_ PVOID CallbackRoutine)
{
BOOLEAN result = FALSE;
ImpKeAcquireGuardedMutex(Lock);
if (Head->Next)
{
PSINGLE_LIST_ENTRY entry = Head->Next;
if (CallbackRoutine)
{
VOID (*callback_function_ptr)(PVOID) = CallbackRoutine;
(*callback_function_ptr)(entry);
}
Head->Next = Head->Next->Next;
ImpExFreePoolWithTag(entry, POOL_TAG_THREAD_LIST);
result = TRUE;
}
ImpKeReleaseGuardedMutex(Lock);
return result;
}
/*
* If we are removing a specific entry, its assumed we have freed and/or dereferenced
* any fields in the structure.
*/
VOID
ListRemoveEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY Entry,
_In_ PKGUARDED_MUTEX Lock)
{
ImpKeAcquireGuardedMutex(Lock);
PSINGLE_LIST_ENTRY entry = Head->Next;
if (!entry)
goto unlock;
if (entry == Entry)
{
Head->Next = entry->Next;
ImpExFreePoolWithTag(Entry, POOL_TAG_THREAD_LIST);
goto unlock;
}
while (entry->Next)
{
if (entry->Next == Entry)
{
entry->Next = Entry->Next;
ImpExFreePoolWithTag(Entry, POOL_TAG_THREAD_LIST);
goto unlock;
}
entry = entry->Next;
}
unlock:
ImpKeReleaseGuardedMutex(Lock);
}
VOID
LookasideThreadListRemoveEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY Entry,
_In_ PKGUARDED_MUTEX Lock)
{
ImpKeAcquireGuardedMutex(Lock);
PTHREAD_LIST_HEAD head = GetThreadList();
PSINGLE_LIST_ENTRY entry = Head->Next;
if (!entry)
goto unlock;
if (entry == Entry)
{
Head->Next = entry->Next;
ExFreeToLookasideListEx(&head->lookaside_list, Entry);
goto unlock;
}
while (entry->Next)
{
if (entry->Next == Entry)
{
entry->Next = Entry->Next;
ExFreeToLookasideListEx(&head->lookaside_list, Entry);
goto unlock;
}
entry = entry->Next;
}
unlock:
ImpKeReleaseGuardedMutex(Lock);
}
BOOLEAN
LookasideListFreeFirstEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_In_ PKGUARDED_MUTEX Lock,
_In_opt_ PVOID CallbackRoutine)
{
ImpKeAcquireGuardedMutex(Lock);
PTHREAD_LIST_HEAD head = GetThreadList();
BOOLEAN result = FALSE;
if (Head->Next)
{
PSINGLE_LIST_ENTRY entry = Head->Next;
if (CallbackRoutine)
{
VOID (*callback_function_ptr)(PVOID) = CallbackRoutine;
(*callback_function_ptr)(entry);
}
Head->Next = Head->Next->Next;
ExFreeToLookasideListEx(&head->lookaside_list, entry);
result = TRUE;
}
ImpKeReleaseGuardedMutex(Lock);
return result;
}

View file

@ -50,8 +50,6 @@ typedef struct _REPORT_HEADER
} REPORT_HEADER, *PREPORT_HEADER;
#define LIST_POOL_TAG 'list'
VOID
QueuePush(_Inout_ PQUEUE_HEAD Head, _In_ PVOID Data);
@ -70,35 +68,7 @@ HandlePeriodicGlobalReportQueueQuery(_Out_ PIRP Irp);
NTSTATUS
HandlePeriodicGlobalReportQueueQuery(_Out_ PIRP Irp);
VOID
ListInit(_Inout_ PSINGLE_LIST_ENTRY Head, _Inout_ PKGUARDED_MUTEX Lock);
VOID
ListInsert(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY NewEntry,
_In_ PKGUARDED_MUTEX Lock);
BOOLEAN
ListFreeFirstEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_In_ PKGUARDED_MUTEX Lock,
_In_opt_ PVOID CallbackRoutine);
VOID
ListRemoveEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY Entry,
_In_ PKGUARDED_MUTEX Lock);
VOID
FreeGlobalReportQueueObjects();
VOID
LookasideThreadListRemoveEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY Entry,
_In_ PKGUARDED_MUTEX Lock);
BOOLEAN
LookasideListFreeFirstEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_In_ PKGUARDED_MUTEX Lock,
_In_opt_ PVOID CallbackRoutine);
#endif

View file

@ -29,7 +29,7 @@ typedef struct _KPRCB_THREAD_VALIDATION_CTX
{
UINT64 thread;
BOOLEAN thread_found_in_pspcidtable;
//BOOLEAN thread_found_in_kthreadlist;
// BOOLEAN thread_found_in_kthreadlist;
BOOLEAN finished;
} KPRCB_THREAD_VALIDATION_CTX, *PKPRCB_THREAD_VALIDATION_CTX;