fix apc free deadlock ting

This commit is contained in:
lhodges1 2023-09-27 14:22:14 +10:00
parent a49f1a6f9c
commit 41f6036640
18 changed files with 273 additions and 152 deletions

View file

@ -8,7 +8,9 @@
CALLBACK_CONFIGURATION configuration = { 0 };
VOID ObPostOpCallbackRoutine(
STATIC
VOID
ObPostOpCallbackRoutine(
_In_ PVOID RegistrationContext,
_In_ POB_POST_OPERATION_INFORMATION OperationInformation
)
@ -16,7 +18,9 @@ VOID ObPostOpCallbackRoutine(
}
OB_PREOP_CALLBACK_STATUS ObPreOpCallbackRoutine(
STATIC
OB_PREOP_CALLBACK_STATUS
ObPreOpCallbackRoutine(
_In_ PVOID RegistrationContext,
_In_ POB_PRE_OPERATION_INFORMATION OperationInformation
)
@ -156,7 +160,9 @@ end:
//}
/* stolen from ReactOS xD */
VOID NTAPI ExUnlockHandleTableEntry(
VOID
NTAPI
ExUnlockHandleTableEntry(
IN PHANDLE_TABLE HandleTable,
IN PHANDLE_TABLE_ENTRY HandleTableEntry
)
@ -171,7 +177,9 @@ VOID NTAPI ExUnlockHandleTableEntry(
ExfUnblockPushLock( &HandleTable->HandleContentionEvent, NULL );
}
BOOLEAN EnumHandleCallback(
STATIC
BOOLEAN
EnumHandleCallback(
_In_ PHANDLE_TABLE HandleTable,
_In_ PHANDLE_TABLE_ENTRY Entry,
_In_ HANDLE Handle,
@ -319,7 +327,8 @@ end:
return FALSE;
}
NTSTATUS EnumerateProcessHandles(
NTSTATUS
EnumerateProcessHandles(
_In_ PEPROCESS Process
)
{
@ -364,7 +373,8 @@ NTSTATUS EnumerateProcessHandles(
* The Context argument is simply a pointer to a user designed context structure
* which is passed to the callback function.
*/
VOID EnumerateProcessListWithCallbackFunction(
VOID
EnumerateProcessListWithCallbackFunction(
_In_ PVOID Function,
_In_opt_ PVOID Context
)
@ -395,7 +405,8 @@ VOID EnumerateProcessListWithCallbackFunction(
} while ( process_list_entry != process_list_head->Blink);
}
NTSTATUS InitiateDriverCallbacks()
NTSTATUS
InitiateDriverCallbacks()
{
NTSTATUS status;
@ -441,7 +452,8 @@ NTSTATUS InitiateDriverCallbacks()
return status;
}
VOID UnregisterCallbacksOnProcessTermination()
VOID
UnregisterCallbacksOnProcessTermination()
{
DEBUG_LOG( "Process closed, unregistering callbacks" );
KeAcquireGuardedMutex( &configuration.mutex );

View file

@ -51,17 +51,23 @@ 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" );
VOID NTAPI ExUnlockHandleTableEntry(
VOID
NTAPI
ExUnlockHandleTableEntry(
IN PHANDLE_TABLE HandleTable,
IN PHANDLE_TABLE_ENTRY HandleTableEntry
);
VOID ObPostOpCallbackRoutine(
STATIC
VOID
ObPostOpCallbackRoutine(
_In_ PVOID RegistrationContext,
_In_ POB_POST_OPERATION_INFORMATION OperationInformation
);
OB_PREOP_CALLBACK_STATUS ObPreOpCallbackRoutine(
STATIC
OB_PREOP_CALLBACK_STATUS
ObPreOpCallbackRoutine(
_In_ PVOID RegistrationContext,
_In_ POB_PRE_OPERATION_INFORMATION OperationInformation
);
@ -72,19 +78,21 @@ OB_PREOP_CALLBACK_STATUS ObPreOpCallbackRoutine(
// _In_ BOOLEAN Create
//);
VOID EnumerateProcessListWithCallbackFunction(
VOID
EnumerateProcessListWithCallbackFunction(
_In_ PVOID Function,
_In_opt_ PVOID Context
);
NTSTATUS EnumerateProcessHandles(
NTSTATUS
EnumerateProcessHandles(
_In_ PEPROCESS Process
);
NTSTATUS InitiateDriverCallbacks();
NTSTATUS
InitiateDriverCallbacks();
VOID UnregisterCallbacksOnProcessTermination();
VOID UnregisterCallbacksOnProcessTermination();
VOID
UnregisterCallbacksOnProcessTermination();
#endif

View file

@ -58,7 +58,7 @@ unlock:
}
/*
* No need to hold the lock here as it thread freeing the APCs will
* No need to hold the lock here as the thread freeing the APCs will
* already hold the configuration lock. We also dont want to release and
* reclaim the lock before calling this function since we need to ensure
* we hold the lock during the entire decrement and free process.
@ -128,60 +128,56 @@ FreeApcAndDecrementApcCount(
context->count -= 1;
switch ( ContextId )
{
case APC_CONTEXT_ID_STACKWALK:
if ( context->count > 0 )
goto end;
PAPC_STACKWALK_CONTEXT stackwalk_context = ( PAPC_STACKWALK_CONTEXT )context;
FreeApcStackwalkApcContextInformation( stackwalk_context );
FreeApcContextStructure( stackwalk_context );
break;
}
end:
KeReleaseGuardedMutex( &driver_config.lock );
}
//NTSTATUS
//QueryActiveApcContextsForCompletion()
//{
// DEBUG_LOG( "Querying active apc contexts" );
//
// KeAcquireGuardedMutex( &driver_config.lock );
//
// for ( INT index = 0; index < 10; index++ )
// {
// PAPC_CONTEXT_HEADER entry = NULL;
// GetApcContextByIndex( &entry, index );
//
// /* ensure we dont try to unlock a null entry */
// if ( entry == NULL )
// continue;
//
// DEBUG_LOG( "APC Context id: %lx", entry->context_id );
// DEBUG_LOG( "Actice Apc Count: %i", entry->count );
//
// if ( entry->count > 0 )
// goto end;
//
// switch ( entry->context_id )
// {
// case APC_CONTEXT_ID_STACKWALK:
// FreeApcStackwalkApcContextInformation( entry );
// FreeApcContextStructure( entry );
// break;
// }
// }
//end:
//
// KeReleaseGuardedMutex( &driver_config.lock );
// return STATUS_SUCCESS;
//}
/*
* The reason we use a query model rather then checking the count of queued APCs
* after each APC free and decrement is that the lock can get acquired by more freeing
* threads then active APCs at the time meaning the context structures will be freed
* while APCs are still in the progress of being queued or executed as those creational
* threads dont hold the lock therefore cannot increase the count.
*/
NTSTATUS
QueryActiveApcContextsForCompletion()
{
for ( INT index = 0; index < 10; index++ )
{
PAPC_CONTEXT_HEADER entry = NULL;
GetApcContextByIndex( &entry, index );
/* acquire mutex after we get the context to prevent thread deadlock */
KeAcquireGuardedMutex( &driver_config.lock );
if ( entry == NULL )
{
KeReleaseGuardedMutex( &driver_config.lock );
continue;
}
DEBUG_LOG( "APC Context Id: %lx", entry->context_id );
DEBUG_LOG( "Active APC Count: %i", entry->count );
if ( entry->count > 0 || entry->allocation_in_progress == TRUE )
{
KeReleaseGuardedMutex( &driver_config.lock );
continue;
}
switch ( entry->context_id )
{
case APC_CONTEXT_ID_STACKWALK:
FreeApcStackwalkApcContextInformation( entry );
FreeApcContextStructure( entry );
break;
}
KeReleaseGuardedMutex( &driver_config.lock );
}
return STATUS_SUCCESS;
}
VOID
InsertApcContext(
@ -582,7 +578,7 @@ DriverUnload(
{
//PsSetCreateProcessNotifyRoutine( ProcessCreateNotifyRoutine, TRUE );
//QueryActiveApcContextsForCompletion();
FreeAllApcContextStructures();
//FreeAllApcContextStructures();
CleanupDriverConfigOnUnload();
IoDeleteDevice( DriverObject->DeviceObject );
}

View file

@ -125,6 +125,9 @@ FreeApcAndDecrementApcCount(
_In_ LONG ContextId
);
NTSTATUS
QueryActiveApcContextsForCompletion();
VOID TerminateProtectedProcessOnViolation();
VOID ClearProcessConfigOnProcessTermination();

View file

@ -19,7 +19,9 @@
* reference: https://secret.club/2020/01/12/battleye-hypervisor-detection.html
*/
INT APERFMsrTimingCheck()
STATIC
INT
APERFMsrTimingCheck()
{
KAFFINITY new_affinity = { 0 };
KAFFINITY old_affinity = { 0 };
@ -78,7 +80,8 @@ INT APERFMsrTimingCheck()
return aperf_delta == 0 ? TRUE : FALSE;
}
NTSTATUS PerformVirtualizationDetection(
NTSTATUS
PerformVirtualizationDetection(
_In_ PIRP Irp
)
{

View file

@ -11,10 +11,13 @@ typedef struct _HYPERVISOR_DETECTION_REPORT
}HYPERVISOR_DETECTION_REPORT, *PHYPERVISOR_DETECTION_REPORT;
NTSTATUS PerformVirtualizationDetection(
NTSTATUS
PerformVirtualizationDetection(
_In_ PIRP Irp
);
extern INT TestINVDEmulation();
extern
INT
TestINVDEmulation();
#endif

View file

@ -17,7 +17,8 @@ typedef struct _INTEGRITY_CHECK_HEADER
* note: this can be put into its own function wihtout an IRP as argument then it can be used
* in both the get driver image ioctl handler and the CopyDriverExecvutableRegions func
*/
NTSTATUS GetDriverImageSize(
NTSTATUS
GetDriverImageSize(
_In_ PIRP Irp
)
{
@ -47,7 +48,9 @@ NTSTATUS GetDriverImageSize(
return status;
}
NTSTATUS GetModuleInformationByName(
STATIC
NTSTATUS
GetModuleInformationByName(
_In_ PRTL_MODULE_EXTENDED_INFO ModuleInfo,
_In_ LPCSTR ModuleName
)
@ -86,7 +89,9 @@ NTSTATUS GetModuleInformationByName(
return status;
}
NTSTATUS StoreModuleExecutableRegionsInBuffer(
STATIC
NTSTATUS
StoreModuleExecutableRegionsInBuffer(
_In_ PVOID* Buffer,
_In_ PVOID ModuleBase,
_In_ SIZE_T ModuleSize,
@ -209,7 +214,9 @@ NTSTATUS StoreModuleExecutableRegionsInBuffer(
return status;
}
NTSTATUS MapDiskImageIntoVirtualAddressSpace(
STATIC
NTSTATUS
MapDiskImageIntoVirtualAddressSpace(
_In_ PHANDLE SectionHandle,
_In_ PVOID* Section,
_In_ PUNICODE_STRING Path,
@ -314,7 +321,9 @@ NTSTATUS MapDiskImageIntoVirtualAddressSpace(
return status;
}
NTSTATUS ComputeHashOfBuffer(
STATIC
NTSTATUS
ComputeHashOfBuffer(
_In_ PVOID Buffer,
_In_ ULONG BufferSize,
_In_ PVOID* HashResult,
@ -495,7 +504,8 @@ end:
* 4. hash both buffers
* 5. compare
*/
NTSTATUS VerifyInMemoryImageVsDiskImage(
NTSTATUS
VerifyInMemoryImageVsDiskImage(
//_In_ PIRP Irp
)
{
@ -672,7 +682,8 @@ end:
return status;
}
NTSTATUS RetrieveInMemoryModuleExecutableSections(
NTSTATUS
RetrieveInMemoryModuleExecutableSections(
_In_ PIRP Irp
)
{
@ -732,7 +743,9 @@ NTSTATUS RetrieveInMemoryModuleExecutableSections(
*
* source: https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf
*/
VOID GetNextSMBIOSStructureInTable(
STATIC
VOID
GetNextSMBIOSStructureInTable(
_In_ PSMBIOS_TABLE_HEADER* CurrentStructure
)
{
@ -763,7 +776,9 @@ VOID GetNextSMBIOSStructureInTable(
* Here we count the number of strings by incrementing the string_count each time we pass a null terminator
* so we know when we're at the beginning of the target string.
*/
NTSTATUS GetStringAtIndexFromSMBIOSTable(
STATIC
NTSTATUS
GetStringAtIndexFromSMBIOSTable(
_In_ PSMBIOS_TABLE_HEADER Table,
_In_ INT Index,
_In_ PVOID Buffer,
@ -808,7 +823,8 @@ NTSTATUS GetStringAtIndexFromSMBIOSTable(
return STATUS_NOT_FOUND;
}
NTSTATUS ParseSMBIOSTable(
NTSTATUS
ParseSMBIOSTable(
_In_ PVOID ConfigMotherboardSerialNumber,
_In_ SIZE_T ConfigMotherboardSerialNumberMaxSize
)
@ -906,7 +922,8 @@ end:
* 5. With the 2 buffers that contain both images executable regions, we hash them and compare
* for anomalies.
*/
NTSTATUS ValidateProcessLoadedModule(
NTSTATUS
ValidateProcessLoadedModule(
_In_ PIRP Irp
)
{
@ -1054,7 +1071,8 @@ end:
* TODO: Query PhysicalDrive%n to get the serial numbers for all harddrives, can use the command
* "wmic diskdrive" check in console.
*/
NTSTATUS GetHardDiskDriveSerialNumber(
NTSTATUS
GetHardDiskDriveSerialNumber(
_In_ PVOID ConfigDrive0Serial,
_In_ SIZE_T ConfigDrive0MaxSize
)

View file

@ -29,34 +29,36 @@ typedef struct _PROCESS_MODULE_VALIDATION_RESULT
}PROCESS_MODULE_VALIDATION_RESULT, *PPROCESS_MODULE_VALIDATION_RESULT;
NTSTATUS CopyDriverExecutableRegions(
NTSTATUS
GetDriverImageSize(
_In_ PIRP Irp
);
NTSTATUS GetDriverImageSize(
_In_ PIRP Irp
);
NTSTATUS VerifyInMemoryImageVsDiskImage(
NTSTATUS
VerifyInMemoryImageVsDiskImage(
//_In_ PIRP Irp
);
NTSTATUS RetrieveInMemoryModuleExecutableSections(
NTSTATUS
RetrieveInMemoryModuleExecutableSections(
_In_ PIRP Irp
);
NTSTATUS ParseSMBIOSTable(
_In_ PVOID ConfigMotherboardSerialNumber,
_In_ SIZE_T ConfigMotherboardSerialMaxNumberSize
);
NTSTATUS ValidateProcessLoadedModule(
NTSTATUS
ValidateProcessLoadedModule(
_In_ PIRP Irp
);
NTSTATUS GetHardDiskDriveSerialNumber(
NTSTATUS
GetHardDiskDriveSerialNumber(
_In_ PVOID ConfigDrive0Serial,
_In_ SIZE_T ConfigDrive0MaxSize
);
NTSTATUS
ParseSMBIOSTable(
_In_ PVOID ConfigMotherboardSerialNumber,
_In_ SIZE_T ConfigMotherboardSerialNumberMaxSize
);
#endif

View file

@ -12,7 +12,8 @@
#include "hv.h"
NTSTATUS DeviceControl(
NTSTATUS
DeviceControl(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PIRP Irp
)
@ -124,6 +125,11 @@ NTSTATUS DeviceControl(
case IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE:
status = QueryActiveApcContextsForCompletion();
if ( !NT_SUCCESS( status ) )
DEBUG_ERROR( "QueryActiveApcContextsForCompletion filed with status %x", status );
status = HandlePeriodicGlobalReportQueueQuery(Irp);
if ( !NT_SUCCESS( status ) )
@ -283,7 +289,8 @@ end:
return status;
}
NTSTATUS DeviceClose(
NTSTATUS
DeviceClose(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp
)
@ -302,7 +309,8 @@ NTSTATUS DeviceClose(
return Irp->IoStatus.Status;
}
NTSTATUS DeviceCreate(
NTSTATUS
DeviceCreate(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp
)

View file

@ -28,17 +28,20 @@ typedef struct _DRIVER_INITIATION_INFORMATION
} DRIVER_INITIATION_INFORMATION, * PDRIVER_INITIATION_INFORMATION;
NTSTATUS DeviceControl(
NTSTATUS
DeviceControl(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PIRP Irp
);
NTSTATUS DeviceClose(
NTSTATUS
DeviceClose(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp
);
NTSTATUS DeviceCreate(
NTSTATUS
DeviceCreate(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp
);

View file

@ -1000,6 +1000,8 @@ ValidateThreadViaKernelApcCallback(
PETHREAD current_thread;
PKAPC apc = NULL;
BOOLEAN apc_status;
HANDLE process_id;
PAPC_STACKWALK_CONTEXT context = ( PAPC_STACKWALK_CONTEXT )Context;
HANDLE id = PsGetProcessId( Process );
@ -1010,12 +1012,18 @@ ValidateThreadViaKernelApcCallback(
thread_list_head = ( PLIST_ENTRY )( ( UINT64 )Process + KPROCESS_THREADLIST_OFFSET );
thread_list_entry = thread_list_head->Flink;
context->header.allocation_in_progress = TRUE;
while ( thread_list_entry != thread_list_head )
{
current_thread = ( PETHREAD )( ( UINT64 )thread_list_entry - KTHREAD_THREADLIST_OFFSET );
/* ensure thread has a valid cid entry */
if ( PsGetThreadId( current_thread ) == NULL )
process_id = PsGetThreadId(current_thread );
/* ensure thread has a valid cid entry and is not svchost or the kernel */
if ( process_id == SYSTEM_IDLE_PROCESS_ID ||
process_id == SYSTEM_PROCESS_ID ||
process_id == SVCHOST_PROCESS_ID )
goto increment;
if (current_thread == KeGetCurrentThread())
@ -1055,6 +1063,8 @@ ValidateThreadViaKernelApcCallback(
increment:
thread_list_entry = thread_list_entry->Flink;
}
context->header.allocation_in_progress = FALSE;
}
/*

View file

@ -102,6 +102,7 @@ typedef struct _APC_CONTEXT_HEADER
{
LONG context_id;
volatile INT count;
volatile INT allocation_in_progress;
}APC_CONTEXT_HEADER, * PAPC_CONTEXT_HEADER;
@ -112,20 +113,28 @@ typedef struct _APC_STACKWALK_CONTEXT
}APC_STACKWALK_CONTEXT, * PAPC_STACKWALK_CONTEXT;
NTSTATUS GetSystemModuleInformation(
#define SYSTEM_IDLE_PROCESS_ID 0
#define SYSTEM_PROCESS_ID 4
#define SVCHOST_PROCESS_ID 8
NTSTATUS
GetSystemModuleInformation(
_Inout_ PSYSTEM_MODULES ModuleInformation
);
NTSTATUS HandleValidateDriversIOCTL(
NTSTATUS
HandleValidateDriversIOCTL(
_In_ PIRP Irp
);
PRTL_MODULE_EXTENDED_INFO FindSystemModuleByName(
PRTL_MODULE_EXTENDED_INFO
FindSystemModuleByName(
_In_ LPCSTR ModuleName,
_In_ PSYSTEM_MODULES SystemModules
);
NTSTATUS HandleNmiIOCTL(
NTSTATUS
HandleNmiIOCTL(
_In_ PIRP Irp
);
@ -134,7 +143,8 @@ FreeApcContextStructure(
_Inout_ PAPC_CONTEXT_HEADER Context
);
NTSTATUS ValidateThreadsViaKernelApc();
NTSTATUS
ValidateThreadsViaKernelApc();
VOID
FreeApcStackwalkApcContextInformation(

View file

@ -34,7 +34,8 @@ CHAR EXECUTIVE_OBJECT_POOL_TAGS[ EXECUTIVE_OBJECT_COUNT ][ POOL_TAG_LENGTH ] =
PVOID process_buffer = NULL;
ULONG process_count = NULL;
PKDDEBUGGER_DATA64 GetGlobalDebuggerData()
PKDDEBUGGER_DATA64
GetGlobalDebuggerData()
{
CONTEXT context = { 0 };
PDUMP_HEADER dump_header = { 0 };
@ -76,7 +77,8 @@ end:
return debugger_data;
}
VOID GetPsActiveProcessHead(
VOID
GetPsActiveProcessHead(
_In_ PUINT64 Address
)
{
@ -122,7 +124,9 @@ VOID GetPsActiveProcessHead(
* This signature will allow us to consistently and accurately determine if a given pool allocation is
* indeed an executive process allocation across major versions of Windows.
*/
BOOLEAN ValidateIfAddressIsProcessStructure(
STATIC
BOOLEAN
ValidateIfAddressIsProcessStructure(
_In_ PVOID Address,
_In_ PPOOL_HEADER PoolHeader
)
@ -188,8 +192,9 @@ BOOLEAN ValidateIfAddressIsProcessStructure(
*
* Also use the full name so we get the file extension and path not the 15 char long one
*/
VOID ScanPageForKernelObjectAllocation(
STATIC
VOID
ScanPageForKernelObjectAllocation(
_In_ UINT64 PageBase,
_In_ ULONG PageSize,
_In_ ULONG ObjectIndex,
@ -278,7 +283,9 @@ VOID ScanPageForKernelObjectAllocation(
* to enumerate, we want to make sure it lies within an appropriate region of
* physical memory, so this function is to check for exactly that.
*/
BOOLEAN IsPhysicalAddressInPhysicalMemoryRange(
STATIC
BOOLEAN
IsPhysicalAddressInPhysicalMemoryRange(
_In_ UINT64 PhysicalAddress,
_In_ PPHYSICAL_MEMORY_RANGE PhysicalMemoryRanges
)
@ -301,7 +308,9 @@ BOOLEAN IsPhysicalAddressInPhysicalMemoryRange(
return FALSE;
}
VOID EnumerateKernelLargePages(
STATIC
VOID
EnumerateKernelLargePages(
_In_ UINT64 PageBase,
_In_ ULONG PageSize,
_In_ PVOID AddressBuffer,
@ -345,8 +354,9 @@ VOID EnumerateKernelLargePages(
* except instead of simply reading the physical we translate it to a virtual address
* and extract the physical address from the value at each virtual address page entry.
*/
VOID WalkKernelPageTables( PVOID AddressBuffer )
STATIC
VOID
WalkKernelPageTables( PVOID AddressBuffer )
{
CR3 cr3;
PML4E pml4_base;
@ -524,12 +534,16 @@ VOID WalkKernelPageTables( PVOID AddressBuffer )
DEBUG_LOG( "Finished scanning memory" );
}
VOID IncrementProcessCounter()
STATIC
VOID
IncrementProcessCounter()
{
process_count++;
}
VOID CheckIfProcessAllocationIsInProcessList(
STATIC
VOID
CheckIfProcessAllocationIsInProcessList(
_In_ PEPROCESS Process
)
{
@ -547,7 +561,8 @@ VOID CheckIfProcessAllocationIsInProcessList(
}
}
NTSTATUS FindUnlinkedProcesses(
NTSTATUS
FindUnlinkedProcesses(
_In_ PIRP Irp
)
{

View file

@ -32,14 +32,17 @@ typedef struct _INVALID_PROCESS_ALLOCATION_REPORT
}INVALID_PROCESS_ALLOCATION_REPORT, *PINVALID_PROCESS_ALLOCATION_REPORT;
NTSTATUS FindUnlinkedProcesses(
NTSTATUS
FindUnlinkedProcesses(
_In_ PIRP Irp
);
VOID GetPsActiveProcessHead(
VOID
GetPsActiveProcessHead(
_In_ PUINT64 Address
);
PKDDEBUGGER_DATA64 GetGlobalDebuggerData();
PKDDEBUGGER_DATA64
GetGlobalDebuggerData();
#endif

View file

@ -26,7 +26,8 @@ typedef struct _REPORT_QUEUE_CONFIGURATION
REPORT_QUEUE_CONFIGURATION report_queue_config = { 0 };
VOID InitialiseGlobalReportQueue(
VOID
InitialiseGlobalReportQueue(
_In_ PBOOLEAN Status
)
{
@ -56,7 +57,8 @@ VOID InitialiseGlobalReportQueue(
// return head;
//}
VOID QueuePush(
VOID
QueuePush(
_In_ PQUEUE_HEAD Head,
_In_ PVOID Data
)
@ -85,7 +87,8 @@ end:
KeReleaseSpinLock( &Head->lock, irql );
}
PVOID QueuePop(
PVOID
QueuePop(
_In_ PQUEUE_HEAD Head
)
{
@ -113,7 +116,8 @@ end:
return data;
}
VOID InsertReportToQueue(
VOID
InsertReportToQueue(
_In_ PVOID Report
)
{
@ -122,7 +126,8 @@ VOID InsertReportToQueue(
KeReleaseGuardedMutex( &report_queue_config.lock );
}
VOID FreeGlobalReportQueueObjects()
VOID
FreeGlobalReportQueueObjects()
{
KeAcquireGuardedMutex( &report_queue_config.lock );
@ -146,7 +151,8 @@ end:
* reports as a result of a single usermode request and hence it makes dealing with
* reports generated from ObRegisterCallbacks for example much easier.
*/
NTSTATUS HandlePeriodicGlobalReportQueueQuery(
NTSTATUS
HandlePeriodicGlobalReportQueueQuery(
_In_ PIRP Irp
)
{
@ -254,7 +260,8 @@ end:
return STATUS_SUCCESS;
}
VOID ListInit(
VOID
ListInit(
_In_ PLIST_HEAD ListHead
)
{
@ -262,7 +269,8 @@ VOID ListInit(
ListHead->start = NULL;
}
PLIST_ITEM ListInsert(
PLIST_ITEM
ListInsert(
_In_ PLIST_HEAD ListHead,
_In_ PLIST_ITEM NewEntry
)
@ -278,7 +286,8 @@ PLIST_ITEM ListInsert(
KeReleaseSpinLock( &ListHead->lock, irql );
}
PVOID ListRemoveFirst(
PVOID
ListRemoveFirst(
_In_ PLIST_HEAD ListHead
)
{
@ -295,7 +304,8 @@ PVOID ListRemoveFirst(
KeReleaseSpinLock( &ListHead->lock, irql );
}
PVOID ListRemoveItem(
PVOID
ListRemoveItem(
_In_ PLIST_HEAD ListHead,
_Inout_ PLIST_ITEM ListItem
)

View file

@ -49,43 +49,53 @@ typedef struct _LIST_HEAD
#define LIST_POOL_TAG 'list'
VOID QueuePush(
VOID
QueuePush(
_In_ PQUEUE_HEAD Head,
_In_ PVOID Data
);
PVOID QueuePop(
PVOID
QueuePop(
_In_ PQUEUE_HEAD Head
);
VOID InitialiseGlobalReportQueue(
VOID
InitialiseGlobalReportQueue(
_In_ PBOOLEAN Status
);
VOID InsertReportToQueue(
VOID
InsertReportToQueue(
_In_ PVOID Report
);
NTSTATUS HandlePeriodicGlobalReportQueueQuery(
NTSTATUS
HandlePeriodicGlobalReportQueueQuery(
_In_ PIRP Irp
);
VOID FreeGlobalReportQueueObjects();
VOID
FreeGlobalReportQueueObjects();
VOID ListInit(
VOID
ListInit(
_In_ PLIST_HEAD ListHead
);
PLIST_ITEM ListInsert(
PLIST_ITEM
ListInsert(
_In_ PLIST_HEAD ListHead,
_In_ PLIST_ITEM Data
);
PVOID ListRemoveFirst(
PVOID
ListRemoveFirst(
_In_ PLIST_HEAD ListHead
);
PVOID ListRemoveItem(
PVOID
ListRemoveItem(
_In_ PLIST_HEAD ListHead,
_Inout_ PLIST_ITEM ListItem
);

View file

@ -16,7 +16,9 @@ typedef struct _KPRCB_THREAD_VALIDATION_CTX
}KPRCB_THREAD_VALIDATION_CTX, *PKPRCB_THREAD_VALIDATION_CTX;
VOID KPRCBThreadValidationProcessCallback(
STATIC
VOID
KPRCBThreadValidationProcessCallback(
_In_ PEPROCESS Process,
_Inout_ PVOID Context
)
@ -77,7 +79,8 @@ VOID KPRCBThreadValidationProcessCallback(
*
*/
VOID ValidateKPCRBThreads(
VOID
ValidateKPCRBThreads(
_In_ PIRP Irp
)
{
@ -129,7 +132,9 @@ VOID ValidateKPCRBThreads(
}
}
VOID DetectAttachedThreadsProcessCallback(
STATIC
VOID
DetectAttachedThreadsProcessCallback(
_In_ PEPROCESS Process,
_In_ PVOID Context
)

View file

@ -24,10 +24,12 @@ typedef struct _ATTACH_PROCESS_REPORT
}ATTACH_PROCESS_REPORT, *PATTACH_PROCESS_REPORT;
VOID ValidateKPCRBThreads(
VOID
ValidateKPCRBThreads(
_In_ PIRP Irp
);
VOID DetectThreadsAttachedToProtectedProcess();
VOID
DetectThreadsAttachedToProtectedProcess();
#endif