This commit is contained in:
lhodges1 2023-08-21 19:45:00 +10:00
parent 614d59c1f2
commit 5163bc14dd
7 changed files with 65 additions and 55 deletions

View file

@ -5,46 +5,55 @@
#include "queue.h" #include "queue.h"
PQUEUE_HEAD report_queue = NULL; QUEUE_HEAD head = { 0 };
QUEUE_HEAD test_queue = { 0 };
/*
* This mutex is to prevent a new item being pushed to the queue
* while the HandlePeriodicCallbackReportQueue is iterating through
* the objects. This can be an issue because the spinlock is released
* after each report is placed in the IRP buffer which means a new report
* can be pushed into the queue before the next iteration can take ownership
* of the spinlock.
*/
KGUARDED_MUTEX mutex; KGUARDED_MUTEX mutex;
VOID InitCallbackReportQueue( PBOOLEAN Status ) VOID InitCallbackReportQueue(
_In_ PBOOLEAN Status
)
{ {
//report_queue = QueueCreate(); head.start = NULL;
head.end = NULL;
head.entries = 0;
test_queue.start = NULL; KeInitializeSpinLock( &head.lock );
test_queue.end = NULL;
test_queue.entries = 0;
KeInitializeSpinLock( &test_queue.lock );
KeInitializeGuardedMutex( &mutex ); KeInitializeGuardedMutex( &mutex );
//if ( report_queue == NULL )
//{
// *Status = FALSE;
// return;
//}
*Status = TRUE; *Status = TRUE;
} }
//VOID DeleteCallbackReportQueueHead()
//{
// ExFreePoolWithTag( report_queue, QUEUE_POOL_TAG );
//}
VOID InsertReportToQueue( VOID InsertReportToQueue(
_In_ POPEN_HANDLE_FAILURE_REPORT Report _In_ POPEN_HANDLE_FAILURE_REPORT Report
) )
{ {
QueuePush( &test_queue, Report ); KeAcquireGuardedMutex( &mutex );
QueuePush( &head, Report );
KeReleaseGuardedMutex( &mutex );
} }
POPEN_HANDLE_FAILURE_REPORT PopFirstReportFromQueue() VOID FreeQueueObjectsAndCleanup()
{ {
return QueuePop( &test_queue ); KeAcquireGuardedMutex( &mutex );
PVOID report = QueuePop(&head );
if ( report == NULL )
goto end;
while ( report != NULL )
report = QueuePop( &head );
end:
KeReleaseGuardedMutex( &mutex );
} }
NTSTATUS HandlePeriodicCallbackReportQueue( NTSTATUS HandlePeriodicCallbackReportQueue(
@ -56,7 +65,7 @@ NTSTATUS HandlePeriodicCallbackReportQueue(
OPEN_HANDLE_FAILURE_REPORT_HEADER header; OPEN_HANDLE_FAILURE_REPORT_HEADER header;
KeAcquireGuardedMutex( &mutex ); KeAcquireGuardedMutex( &mutex );
report = PopFirstReportFromQueue(); report = QueuePop( &head );
if ( report == NULL ) if ( report == NULL )
{ {
@ -79,11 +88,12 @@ NTSTATUS HandlePeriodicCallbackReportQueue(
sizeof( OPEN_HANDLE_FAILURE_REPORT ) sizeof( OPEN_HANDLE_FAILURE_REPORT )
); );
report = PopFirstReportFromQueue(); report = QueuePop( &head );
count += 1; count += 1;
} }
end: end:
header.count = count; header.count = count;
RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer, &header, sizeof( OPEN_HANDLE_FAILURE_REPORT_HEADER )); RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer, &header, sizeof( OPEN_HANDLE_FAILURE_REPORT_HEADER ));
KeReleaseGuardedMutex( &mutex ); KeReleaseGuardedMutex( &mutex );

View file

@ -55,8 +55,9 @@ OB_PREOP_CALLBACK_STATUS ObPreOpCallbackRoutine(
_In_ POB_PRE_OPERATION_INFORMATION OperationInformation _In_ POB_PRE_OPERATION_INFORMATION OperationInformation
); );
VOID InitCallbackReportQueue(PBOOLEAN Status); VOID InitCallbackReportQueue(
VOID DeleteCallbackReportQueueHead(); _In_ PBOOLEAN Status
);
NTSTATUS HandlePeriodicCallbackReportQueue( NTSTATUS HandlePeriodicCallbackReportQueue(
_In_ PIRP Irp _In_ PIRP Irp
@ -68,4 +69,6 @@ VOID ProcessCreateNotifyRoutine(
_In_ BOOLEAN Create _In_ BOOLEAN Create
); );
VOID FreeQueueObjectsAndCleanup();
#endif #endif

View file

@ -55,6 +55,7 @@ VOID DriverUnload(
{ {
PsSetCreateProcessNotifyRoutine( ProcessCreateNotifyRoutine, TRUE ); PsSetCreateProcessNotifyRoutine( ProcessCreateNotifyRoutine, TRUE );
ObUnRegisterCallbacks( callback_registration_handle ); ObUnRegisterCallbacks( callback_registration_handle );
FreeQueueObjectsAndCleanup();
IoDeleteSymbolicLink( &DEVICE_SYMBOLIC_LINK ); IoDeleteSymbolicLink( &DEVICE_SYMBOLIC_LINK );
IoDeleteDevice( DriverObject->DeviceObject ); IoDeleteDevice( DriverObject->DeviceObject );
} }
@ -105,7 +106,7 @@ NTSTATUS DriverEntry(
{ {
UNREFERENCED_PARAMETER( RegistryPath ); UNREFERENCED_PARAMETER( RegistryPath );
BOOLEAN flag; BOOLEAN flag = FALSE;
NTSTATUS status; NTSTATUS status;
HANDLE handle; HANDLE handle;
@ -164,7 +165,6 @@ NTSTATUS DriverEntry(
if ( !NT_SUCCESS( status ) ) if ( !NT_SUCCESS( status ) )
{ {
DEBUG_ERROR( "failed to launch thread to start tings" ); DEBUG_ERROR( "failed to launch thread to start tings" );
//DeleteCallbackReportQueueHead();
IoDeleteSymbolicLink( &DEVICE_SYMBOLIC_LINK ); IoDeleteSymbolicLink( &DEVICE_SYMBOLIC_LINK );
IoDeleteDevice( DriverObject->DeviceObject ); IoDeleteDevice( DriverObject->DeviceObject );
return STATUS_FAILED_DRIVER_ENTRY; return STATUS_FAILED_DRIVER_ENTRY;

View file

@ -82,9 +82,9 @@ NTSTATUS DeviceControl(
/* KeWaitForSingleObject with infinite time must be called from IRQL <= APC_LEVEL */ /* KeWaitForSingleObject with infinite time must be called from IRQL <= APC_LEVEL */
PAGED_CODE(); PAGED_CODE();
DEBUG_LOG( "waiting for thread to finish" );
KeWaitForSingleObject( thread, Executive, KernelMode, FALSE, NULL ); KeWaitForSingleObject( thread, Executive, KernelMode, FALSE, NULL );
DEBUG_LOG( "THREAD FINISHED" );
ZwClose( handle ); ZwClose( handle );
ObDereferenceObject( thread ); ObDereferenceObject( thread );
@ -131,6 +131,7 @@ NTSTATUS DeviceCreate(
_In_ PIRP Irp _In_ PIRP Irp
) )
{ {
DEBUG_LOG( "Handle opened to DonnaAC" );
IoCompleteRequest( Irp, IO_NO_INCREMENT ); IoCompleteRequest( Irp, IO_NO_INCREMENT );
return Irp->IoStatus.Status; return Irp->IoStatus.Status;
} }

View file

@ -3,6 +3,8 @@
#include "modules.h" #include "modules.h"
#include "common.h" #include "common.h"
#define NMI_DELAY 100 * 10000
typedef struct _NMI_POOLS typedef struct _NMI_POOLS
{ {
PVOID thread_data_pool; PVOID thread_data_pool;
@ -208,7 +210,7 @@ NTSTATUS LaunchNonMaskableInterrupt(
} }
LARGE_INTEGER delay = { 0 }; LARGE_INTEGER delay = { 0 };
delay.QuadPart -= 100 * 10000; delay.QuadPart -= NMI_DELAY;
for ( ULONG core = 0; core < NumCores; core++ ) for ( ULONG core = 0; core < NumCores; core++ )
{ {

View file

@ -1,24 +1,20 @@
#include "queue.h" #include "queue.h"
/* //PQUEUE_HEAD QueueCreate()
* Basic thread-safe queue implementation that can be used to create queues for any data. //{
*/ // PQUEUE_HEAD head = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( PQUEUE_HEAD ), QUEUE_POOL_TAG );
//
PQUEUE_HEAD QueueCreate() // if ( !head )
{ // return NULL;
PQUEUE_HEAD head = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( PQUEUE_HEAD ), QUEUE_POOL_TAG ); //
// head->end = NULL;
if ( !head ) // head->start = NULL;
return NULL; // head->entries = 0;
//
head->end = NULL; // KeInitializeSpinLock( &head->lock );
head->start = NULL; //
head->entries = 0; // return head;
//}
KeInitializeSpinLock( &head->lock );
return head;
}
VOID QueuePush( VOID QueuePush(
_In_ PQUEUE_HEAD Head, _In_ PQUEUE_HEAD Head,

View file

@ -21,8 +21,6 @@ typedef struct QUEUE_HEAD
}QUEUE_HEAD, *PQUEUE_HEAD; }QUEUE_HEAD, *PQUEUE_HEAD;
PQUEUE_HEAD QueueCreate();
VOID QueuePush( VOID QueuePush(
_In_ PQUEUE_HEAD Head, _In_ PQUEUE_HEAD Head,
_In_ PVOID Data _In_ PVOID Data