From ab451e0eee3a8b9cc549b0c287c56a9ab96cb594 Mon Sep 17 00:00:00 2001
From: lhodges1 <lachiehodges7785@gmail.com>
Date: Fri, 25 Aug 2023 01:10:40 +1000
Subject: [PATCH] BLAH

---
 driver/callbacks.c |  1 +
 driver/driver.c    | 26 ++++++++++++++++++++++++--
 driver/driver.h    |  8 ++++++--
 driver/integrity.c |  2 ++
 driver/ioctl.c     | 13 ++++++++++++-
 driver/ioctl.h     |  2 +-
 user/km/driver.cpp | 24 ++++++++++++++++++++++++
 user/km/driver.h   |  9 +++++----
 user/main.cpp      |  2 +-
 9 files changed, 76 insertions(+), 11 deletions(-)

diff --git a/driver/callbacks.c b/driver/callbacks.c
index ad601b6..6bee62e 100644
--- a/driver/callbacks.c
+++ b/driver/callbacks.c
@@ -512,6 +512,7 @@ NTSTATUS InitiateDriverCallbacks()
 
 VOID UnregisterCallbacksOnProcessTermination()
 {
+	DEBUG_LOG( "Process closed, unregistering callbacks" );
 	KeAcquireGuardedMutex( &configuration.mutex );
 	ObUnRegisterCallbacks( configuration.registration_handle );
 	configuration.registration_handle = NULL;
diff --git a/driver/driver.c b/driver/driver.c
index fd9a793..d004a43 100644
--- a/driver/driver.c
+++ b/driver/driver.c
@@ -13,8 +13,17 @@ DRIVER_CONFIG config = { 0 };
 UNICODE_STRING DEVICE_NAME = RTL_CONSTANT_STRING( L"\\Device\\DonnaAC" );
 UNICODE_STRING DEVICE_SYMBOLIC_LINK = RTL_CONSTANT_STRING( L"\\??\\DonnaAC" );
 
+VOID ReadInitialisedConfigFlag(
+	_Out_ PBOOLEAN Flag
+)
+{
+	KeAcquireGuardedMutex( &config.lock );
+	*Flag = config.initialised;
+	KeReleaseGuardedMutex( &config.lock );
+}
+
 VOID GetProtectedProcessEProcess( 
-	_In_ PEPROCESS Process 
+	_Out_ PEPROCESS Process 
 )
 {
 	KeAcquireGuardedMutex( &config.lock );
@@ -23,7 +32,7 @@ VOID GetProtectedProcessEProcess(
 }
 
 VOID GetProtectedProcessId( 
-	_In_ PLONG ProcessId 
+	_Out_ PLONG ProcessId 
 )
 {
 	KeAcquireGuardedMutex( &config.lock );
@@ -33,6 +42,7 @@ VOID GetProtectedProcessId(
 
 VOID ClearDriverConfigOnProcessTermination()
 {
+	DEBUG_LOG( "Process closed, clearing driver configuration" );
 	KeAcquireGuardedMutex( &config.lock );
 	config.protected_process_id = NULL;
 	config.protected_process_eprocess = NULL;
@@ -55,10 +65,18 @@ NTSTATUS InitialiseDriverConfigOnProcessLaunch(
 	if ( !NT_SUCCESS( status ) )
 		return status;
 
+	/*
+	* acquire the mutex here to prevent a race condition if an unknown party trys 
+	* to fuzz our IOCTL codes whilst the target process launches.
+	*/
+	KeAcquireGuardedMutex( &config.lock );
+
 	config.protected_process_eprocess = eprocess;
 	config.protected_process_id = information->protected_process_id;
 	config.initialised = TRUE;
 
+	KeReleaseGuardedMutex( &config.lock );
+
 	Irp->IoStatus.Status = status;
 
 	return status;
@@ -86,6 +104,10 @@ NTSTATUS DriverEntry(
 
 	KeInitializeGuardedMutex( &config.lock );
 
+	config.initialised = FALSE;
+	config.protected_process_eprocess = NULL;
+	config.protected_process_id = NULL;
+
 	status = IoCreateDevice(
 		DriverObject,
 		NULL,
diff --git a/driver/driver.h b/driver/driver.h
index d1d91d4..c53db7c 100644
--- a/driver/driver.h
+++ b/driver/driver.h
@@ -19,12 +19,16 @@ NTSTATUS InitialiseDriverConfigOnProcessLaunch(
 );
 
 VOID GetProtectedProcessEProcess(
-	_In_ PEPROCESS Process
+	_Out_ PEPROCESS Process
 );
 
 
 VOID GetProtectedProcessId(
-	_In_ PLONG ProcessId
+	_Out_ PLONG ProcessId
+);
+
+VOID ReadInitialisedConfigFlag(
+	_Out_ PBOOLEAN Flag
 );
 
 
diff --git a/driver/integrity.c b/driver/integrity.c
index b36bba8..46e25f0 100644
--- a/driver/integrity.c
+++ b/driver/integrity.c
@@ -43,6 +43,8 @@ NTSTATUS GetDriverImageSize(
 * analyse the executable sections from there. Until I find a better way to enumerate
 * kernel memory without having to walk the pages tables to check the EDB bit this 
 * is how I will be doing it. c:
+* 
+* TODO: We will hash this based on timestamp sent from the server.
 */
 NTSTATUS CopyDriverExecutableRegions(
 	_In_ PIRP Irp
diff --git a/driver/ioctl.c b/driver/ioctl.c
index eb7782c..d185d1c 100644
--- a/driver/ioctl.c
+++ b/driver/ioctl.c
@@ -21,6 +21,17 @@ NTSTATUS DeviceControl(
 	PIO_STACK_LOCATION stack_location = IoGetCurrentIrpStackLocation( Irp );
 	HANDLE handle;
 	PKTHREAD thread;
+	BOOLEAN security_flag = FALSE;
+
+	/*
+	* The purpose of this is to prevent programs from opening a handle to our driver
+	* and trying to fuzz the IOCTL access or codes. This definitely isnt a perfect 
+	* solution though... xD
+	*/
+	ReadInitialisedConfigFlag( &security_flag );
+
+	if ( security_flag == FALSE )
+		goto end;
 
 	switch ( stack_location->Parameters.DeviceIoControl.IoControlCode )
 	{
@@ -190,7 +201,7 @@ NTSTATUS DeviceControl(
 
 		break;
 
-	case IOCTL_CLEAR_CONFIG_ON_PROCESS_CLOSE:
+	case IOCTL_NOTIFY_DRIVER_ON_PROCESS_TERMINATION:
 
 		ClearDriverConfigOnProcessTermination();
 		UnregisterCallbacksOnProcessTermination();
diff --git a/driver/ioctl.h b/driver/ioctl.h
index 41dfe82..86933bc 100644
--- a/driver/ioctl.h
+++ b/driver/ioctl.h
@@ -15,7 +15,7 @@
 #define IOCTL_ENUMERATE_HANDLE_TABLES CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2007, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2008, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define IOCTL_REQUEST_TOTAL_MODULE_SIZE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2009, METHOD_BUFFERED, FILE_ANY_ACCESS)
-#define IOCTL_CLEAR_CONFIG_ON_PROCESS_CLOSE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2010, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_NOTIFY_DRIVER_ON_PROCESS_TERMINATION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2010, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
 typedef struct _DRIVER_INITIATION_INFORMATION
 {
diff --git a/user/km/driver.cpp b/user/km/driver.cpp
index 937000f..c46191c 100644
--- a/user/km/driver.cpp
+++ b/user/km/driver.cpp
@@ -24,6 +24,11 @@ kernelmode::Driver::Driver( LPCWSTR DriverName, std::shared_ptr<global::Client>
 	this->NotifyDriverOnProcessLaunch();
 }
 
+kernelmode::Driver::~Driver()
+{
+	this->NotifyDriverOnProcessTermination();
+}
+
 VOID kernelmode::Driver::RunNmiCallbacks()
 {
 	BOOLEAN status;
@@ -356,6 +361,25 @@ ULONG kernelmode::Driver::RequestTotalModuleSize()
 	return module_size;
 }
 
+VOID kernelmode::Driver::NotifyDriverOnProcessTermination()
+{
+	BOOLEAN status;
+	
+	status = DeviceIoControl(
+		this->driver_handle,
+		IOCTL_NOTIFY_DRIVER_ON_PROCESS_TERMINATION,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		NULL
+	);
+
+	if ( status == NULL )
+		LOG_ERROR( "NotifyDriverOnProcessTermination failed with status %x", status );
+}
+
 VOID kernelmode::Driver::ValidateKPRCBThreads()
 {
 
diff --git a/user/km/driver.h b/user/km/driver.h
index 2e3723e..d86ee39 100644
--- a/user/km/driver.h
+++ b/user/km/driver.h
@@ -8,14 +8,13 @@
 
 #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_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)
 #define IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2005, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define IOCTL_PERFORM_VIRTUALIZATION_CHECK CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2006, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define IOCTL_ENUMERATE_HANDLE_TABLES CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2007, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2008, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define IOCTL_REQUEST_TOTAL_MODULE_SIZE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2009, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
+#define IOCTL_NOTIFY_DRIVER_ON_PROCESS_TERMINATION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2010, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
 #define MAX_HANDLE_REPORTS_PER_IRP 10
 
@@ -29,18 +28,20 @@ namespace kernelmode
 
 		VOID QueryReportQueue();
 		ULONG RequestTotalModuleSize();
+		VOID NotifyDriverOnProcessLaunch();
+		VOID CheckDriverHeartbeat();
+		VOID NotifyDriverOnProcessTermination();
 
 	public:
 
 		Driver(LPCWSTR DriverName, std::shared_ptr<global::Client> ReportInterface );
+		~Driver();
 
 		VOID RunNmiCallbacks();
 		VOID VerifySystemModules();
 		VOID RunCallbackReportQueue();
-		VOID NotifyDriverOnProcessLaunch();
 		VOID DetectSystemVirtualization();
 		VOID ValidateKPRCBThreads();
-		VOID CheckDriverHeartbeat();
 		VOID CheckHandleTableEntries();
 		VOID RequestModuleExecutableRegions();
 		/* todo: driver integrity check */
diff --git a/user/main.cpp b/user/main.cpp
index 81f3d4f..9a00af8 100644
--- a/user/main.cpp
+++ b/user/main.cpp
@@ -31,7 +31,7 @@ DWORD WINAPI Init(HINSTANCE hinstDLL)
     //kmanager.MonitorCallbackReports();
     //kmanager.RunNmiCallbacks();
     //kmanager.VerifySystemModules();
-    kmanager.RequestModuleExecutableRegionsForIntegrityCheck();
+    //kmanager.RequestModuleExecutableRegionsForIntegrityCheck();
     //kmanager.MonitorCallbackReports();
 
     //umanager.ValidateProcessModules();