mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
fix apc free deadlock ting
This commit is contained in:
parent
a49f1a6f9c
commit
41f6036640
18 changed files with 273 additions and 152 deletions
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
100
driver/driver.c
100
driver/driver.c
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -125,6 +125,9 @@ FreeApcAndDecrementApcCount(
|
|||
_In_ LONG ContextId
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
QueryActiveApcContextsForCompletion();
|
||||
|
||||
VOID TerminateProtectedProcessOnViolation();
|
||||
|
||||
VOID ClearProcessConfigOnProcessTermination();
|
||||
|
|
|
@ -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
|
||||
)
|
||||
{
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
)
|
||||
{
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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
|
Loading…
Reference in a new issue