change da apc ref count stuff

This commit is contained in:
lhodges1 2023-09-26 20:00:45 +10:00
parent aeddd69022
commit 861c6d84f8
10 changed files with 271 additions and 244 deletions

View file

@ -48,10 +48,16 @@ OB_PREOP_CALLBACK_STATUS ObPreOpCallbackRoutine(
GetProtectedProcessId( &protected_process_id );
GetProtectedProcessEProcess( &protected_process );
if ( !protected_process_id || !protected_process )
goto end;
process_creator_name = PsGetProcessImageFileName( process_creator );
target_process_name = PsGetProcessImageFileName( target_process );
protected_process_name = PsGetProcessImageFileName( protected_process );
if ( !protected_process_name || !target_process_name )
goto end;
if ( !strcmp( protected_process_name, target_process_name) )
{
if ( !strcmp( process_creator_name, "lsass.exe" ) || !strcmp( process_creator_name, "csrss.exe" ) )

View file

@ -7,6 +7,8 @@
#define DEBUG_LOG(fmt, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[+] " fmt "\n", ##__VA_ARGS__)
#define DEBUG_ERROR(fmt, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[-] " fmt "\n", ##__VA_ARGS__)
#define STATIC static
#define NMI_CONTEXT_POOL '7331'
#define STACK_FRAMES_POOL 'loop'
#define INVALID_DRIVER_LIST_HEAD_POOL 'rwar'
@ -32,6 +34,7 @@
#define REPORT_QUEUE_TEMP_BUFFER_TAG 'temp'
#define REPORT_POOL_TAG 'repo'
#define MODULES_REPORT_POOL_TAG 'modu'
#define POOL_TAG_LIST_ITEM 'tsil'
#define ERROR -1
#define STACK_FRAME_POOL_SIZE 0x200

View file

@ -13,138 +13,118 @@
DRIVER_CONFIG driver_config = { 0 };
PROCESS_CONFIG process_config = { 0 };
VOID InitApcContextsList()
{
KeAcquireGuardedMutex( &driver_config.lock );
driver_config.apc_contexts = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( LIST_HEAD ), POOL_TAG_APC );
if ( !driver_config.apc_contexts )
return;
ListInit( driver_config.apc_contexts );
KeReleaseGuardedMutex( &driver_config.lock );
}
VOID FreeApcContextStructures()
STATIC
VOID
FreeAllApcContextStructures()
{
KeAcquireGuardedMutex( &driver_config.lock );
PLIST_ITEM entry = driver_config.apc_contexts->start;
if ( !entry )
goto unlock;
while ( entry )
for ( INT index = 0; index < 10; index++ )
{
FreeApcContextStructure( entry->data );
entry = entry->next;
ListRemoveItem( driver_config.apc_contexts, entry );
PUINT64 entry = driver_config.apc_contexts;
if ( entry[ index ] != NULL )
{
ExFreePoolWithTag( entry, POOL_TAG_APC );
}
}
unlock:
KeReleaseGuardedMutex( &driver_config.lock );
}
VOID InsertApcIntoApcContextList(
_In_ PLIST_HEAD ListHead,
_In_ PAPC_STATUS ApcStatus
)
{
KeAcquireGuardedMutex( &driver_config.lock );
ListInsert( ListHead, ApcStatus );
KeReleaseGuardedMutex( &driver_config.lock );
}
VOID RemoveApcContext(
_In_ LONG ContextIdentifier,
_In_ PKAPC Apc
BOOLEAN
FreeApcContextStructure(
_Inout_ PAPC_CONTEXT_HEADER Context
)
{
BOOLEAN result = FALSE;
KeAcquireGuardedMutex( &driver_config.lock );
PLIST_ITEM entry = driver_config.apc_contexts->start;
while ( entry )
for ( INT index = 0; index < 10; index++ )
{
PAPC_CONTEXT_HEADER header = ( PAPC_CONTEXT_HEADER )entry->data;
PUINT64 entry = driver_config.apc_contexts;
if ( header->context_id == ContextIdentifier )
if ( entry[ index ] == Context )
{
ListRemoveItem( driver_config.apc_contexts, entry );
ExFreePoolWithTag( entry->data, POOL_TAG_APC );
ExFreePoolWithTag( entry, LIST_POOL_TAG );
break;
if ( Context->count != 0 )
goto unlock;
ExFreePoolWithTag( Context, POOL_TAG_APC );
entry[ index ] = NULL;
result = TRUE;
goto unlock;
}
}
unlock:
KeReleaseGuardedMutex( &driver_config.lock );
return result;
}
VOID InsertApcContext(
VOID
InsertApcContext(
_In_ PVOID Context
)
{
KeAcquireGuardedMutex( &driver_config.lock );
if ( Context )
PAPC_CONTEXT_HEADER header = Context;
for ( INT index = 0; index < 10; index++ )
{
PLIST_ITEM entry = ListInsert( driver_config.apc_contexts, Context );
PUINT64 entry = driver_config.apc_contexts;
if ( !entry )
goto end;
PAPC_CONTEXT_HEADER header = ( PAPC_CONTEXT_HEADER )entry->data;
header->head = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( LIST_HEAD ), POOL_TAG_APC );
if ( !header->head )
if ( entry[ index ] == NULL )
{
entry[ index ] = Context;
goto end;
}
}
end:
KeReleaseGuardedMutex( &driver_config.lock );
}
VOID RemoveApcFromApcContextList(
_In_ PLIST_HEAD ListHead,
_Inout_ PLIST_ITEM ListEntry
)
{
KeAcquireGuardedMutex( &driver_config.lock );
ListRemoveItem( ListHead, ListEntry );
KeReleaseGuardedMutex( &driver_config.lock );
}
VOID GetApcContext(
VOID
GetApcContext(
_Inout_ PVOID* Context,
_In_ LONG ContextIdentifier
)
{
if ( !Context )
return;
KeAcquireGuardedMutex( &driver_config.lock );
PLIST_ITEM entry = driver_config.apc_contexts->start;
while ( entry )
for ( INT index = 0; index < 10; index++ )
{
PAPC_CONTEXT_HEADER header = ( PAPC_CONTEXT_HEADER )entry->data;
PAPC_CONTEXT_HEADER header = driver_config.apc_contexts[ index ];
if ( header == NULL )
continue;
if ( header->context_id == ContextIdentifier )
{
*Context = header;
KeReleaseGuardedMutex( &driver_config.lock );
return;
goto unlock;
}
entry = entry->next;
}
unlock:
KeReleaseGuardedMutex( &driver_config.lock );
}
VOID ReadProcessInitialisedConfigFlag(
VOID
GetApcContextByIndex(
_Inout_ PVOID* Context,
_In_ INT Index
)
{
KeAcquireGuardedMutex( &driver_config.lock );
*Context = driver_config.apc_contexts[ Index ];
KeReleaseGuardedMutex( &driver_config.lock );
}
VOID
ReadProcessInitialisedConfigFlag(
_Out_ PBOOLEAN Flag
)
{
@ -156,7 +136,8 @@ VOID ReadProcessInitialisedConfigFlag(
KeReleaseGuardedMutex( &process_config.lock );
}
VOID GetProtectedProcessEProcess(
VOID
GetProtectedProcessEProcess(
_Out_ PEPROCESS* Process
)
{
@ -168,7 +149,8 @@ VOID GetProtectedProcessEProcess(
KeReleaseGuardedMutex( &process_config.lock );
}
VOID GetProtectedProcessId(
VOID
GetProtectedProcessId(
_Out_ PLONG ProcessId
)
{
@ -178,7 +160,8 @@ VOID GetProtectedProcessId(
KeReleaseGuardedMutex( &process_config.lock );
}
VOID ClearProcessConfigOnProcessTermination()
VOID
ClearProcessConfigOnProcessTermination()
{
DEBUG_LOG( "Process closed, clearing driver process_configuration" );
KeAcquireGuardedMutex( &process_config.lock );
@ -189,7 +172,8 @@ VOID ClearProcessConfigOnProcessTermination()
KeReleaseGuardedMutex( &process_config.lock );
}
VOID GetDriverName(
VOID
GetDriverName(
_Out_ LPCSTR* DriverName
)
{
@ -201,7 +185,8 @@ VOID GetDriverName(
KeReleaseGuardedMutex( &driver_config.lock );
}
VOID GetDriverPath(
VOID
GetDriverPath(
_Out_ PUNICODE_STRING DriverPath
)
{
@ -211,7 +196,8 @@ VOID GetDriverPath(
KeReleaseGuardedMutex( &driver_config.lock );
}
VOID GetDriverRegistryPath(
VOID
GetDriverRegistryPath(
_Out_ PUNICODE_STRING RegistryPath
)
{
@ -221,7 +207,8 @@ VOID GetDriverRegistryPath(
KeReleaseGuardedMutex( &driver_config.lock );
}
VOID GetDriverDeviceName(
VOID
GetDriverDeviceName(
_Out_ PUNICODE_STRING DeviceName
)
{
@ -231,7 +218,8 @@ VOID GetDriverDeviceName(
KeReleaseGuardedMutex( &driver_config.lock );
}
VOID GetDriverSymbolicLink(
VOID
GetDriverSymbolicLink(
_Out_ PUNICODE_STRING DeviceSymbolicLink
)
{
@ -241,7 +229,8 @@ VOID GetDriverSymbolicLink(
KeReleaseGuardedMutex( &driver_config.lock );
}
VOID GetDriverConfigSystemInformation(
VOID
GetDriverConfigSystemInformation(
_Out_ PSYSTEM_INFORMATION* SystemInformation
)
{
@ -253,7 +242,9 @@ VOID GetDriverConfigSystemInformation(
KeReleaseGuardedMutex( &driver_config.lock );
}
NTSTATUS RegistryPathQueryCallbackRoutine(
STATIC
NTSTATUS
RegistryPathQueryCallbackRoutine(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
@ -309,7 +300,9 @@ NTSTATUS RegistryPathQueryCallbackRoutine(
return STATUS_SUCCESS;
}
VOID FreeDriverConfigurationStringBuffers()
STATIC
VOID
FreeDriverConfigurationStringBuffers()
{
if ( driver_config.unicode_driver_name.Buffer )
ExFreePoolWithTag( driver_config.unicode_driver_name.Buffer, POOL_TAG_STRINGS );
@ -321,7 +314,9 @@ VOID FreeDriverConfigurationStringBuffers()
RtlFreeAnsiString( &driver_config.ansi_driver_name );
}
NTSTATUS InitialiseDriverConfigOnDriverEntry(
STATIC
NTSTATUS
InitialiseDriverConfigOnDriverEntry(
_In_ PUNICODE_STRING RegistryPath
)
{
@ -404,15 +399,14 @@ NTSTATUS InitialiseDriverConfigOnDriverEntry(
return status;
}
InitApcContextsList();
DEBUG_LOG( "Motherboard serial: %s", driver_config.system_information.motherboard_serial );
DEBUG_LOG( "Drive 0 serial: %s", driver_config.system_information.drive_0_serial );
return status;
}
NTSTATUS InitialiseProcessConfigOnProcessLaunch(
NTSTATUS
InitialiseProcessConfigOnProcessLaunch(
_In_ PIRP Irp
)
{
@ -443,29 +437,36 @@ NTSTATUS InitialiseProcessConfigOnProcessLaunch(
return status;
}
VOID InitialiseProcessConfigOnDriverEntry()
STATIC
VOID
InitialiseProcessConfigOnDriverEntry()
{
KeInitializeGuardedMutex( &process_config.lock );
}
VOID CleanupDriverConfigOnUnload()
STATIC
VOID
CleanupDriverConfigOnUnload()
{
FreeDriverConfigurationStringBuffers();
FreeGlobalReportQueueObjects();
IoDeleteSymbolicLink( &driver_config.device_symbolic_link );
}
VOID DriverUnload(
STATIC
VOID
DriverUnload(
_In_ PDRIVER_OBJECT DriverObject
)
{
//PsSetCreateProcessNotifyRoutine( ProcessCreateNotifyRoutine, TRUE );
FreeAllApcContextStructures();
CleanupDriverConfigOnUnload();
FreeApcContextStructures();
IoDeleteDevice( DriverObject->DeviceObject );
}
VOID TerminateProtectedProcessOnViolation()
VOID
TerminateProtectedProcessOnViolation()
{
NTSTATUS status;
ULONG process_id;
@ -496,7 +497,8 @@ VOID TerminateProtectedProcessOnViolation()
ClearProcessConfigOnProcessTermination();
}
NTSTATUS DriverEntry(
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)

View file

@ -43,7 +43,7 @@ typedef struct _DRIVER_CONFIG
UNICODE_STRING driver_path;
UNICODE_STRING registry_path;
SYSTEM_INFORMATION system_information;
PLIST_HEAD apc_contexts;
PVOID apc_contexts[ 10 ];
KGUARDED_MUTEX lock;
}DRIVER_CONFIG, *PDRIVER_CONFIG;
@ -103,7 +103,13 @@ VOID RemoveApcFromApcContextList(
VOID InsertApcIntoApcContextList(
_In_ PLIST_HEAD ListHead,
_In_ PAPC_STATUS ApcStatus
_In_ PAPC_ENTRY ApcStatus
);
VOID
GetApcContextByIndex(
_Inout_ PVOID* Context,
_In_ INT Index
);
VOID TerminateProtectedProcessOnViolation();

View file

@ -124,6 +124,11 @@ NTSTATUS DeviceControl(
case IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE:
status = QueryActiveApcContextsForCompletion();
if ( !NT_SUCCESS( status ) )
DEBUG_ERROR( "QueryActiveApcContextsForCompletion failed with status %x", status );
status = HandlePeriodicGlobalReportQueueQuery(Irp);
if ( !NT_SUCCESS( status ) )

View file

@ -39,7 +39,8 @@ typedef struct _NMI_CONTEXT
/*
* TODO: this needs to be refactored to just return the entry not the whole fukin thing
*/
PRTL_MODULE_EXTENDED_INFO FindSystemModuleByName(
PRTL_MODULE_EXTENDED_INFO
FindSystemModuleByName(
_In_ LPCSTR ModuleName,
_In_ PSYSTEM_MODULES SystemModules
)
@ -59,7 +60,9 @@ PRTL_MODULE_EXTENDED_INFO FindSystemModuleByName(
}
}
NTSTATUS PopulateWhitelistedModuleBuffer(
STATIC
NTSTATUS
PopulateWhitelistedModuleBuffer(
_In_ PVOID Buffer,
_In_ PSYSTEM_MODULES SystemModules
)
@ -87,7 +90,9 @@ NTSTATUS PopulateWhitelistedModuleBuffer(
return STATUS_SUCCESS;
}
NTSTATUS ValidateDriverIOCTLDispatchRegion(
STATIC
NTSTATUS
ValidateDriverIOCTLDispatchRegion(
_In_ PDRIVER_OBJECT Driver,
_In_ PSYSTEM_MODULES Modules,
_In_ PWHITELISTED_REGIONS WhitelistedRegions,
@ -160,7 +165,9 @@ NTSTATUS ValidateDriverIOCTLDispatchRegion(
return STATUS_SUCCESS;
}
VOID InitDriverList(
STATIC
VOID
InitDriverList(
_In_ PINVALID_DRIVERS_HEAD ListHead
)
{
@ -168,7 +175,9 @@ VOID InitDriverList(
ListHead->first_entry = NULL;
}
VOID AddDriverToList(
STATIC
VOID
AddDriverToList(
_In_ PINVALID_DRIVERS_HEAD InvalidDriversHead,
_In_ PDRIVER_OBJECT Driver,
_In_ INT Reason
@ -189,7 +198,9 @@ VOID AddDriverToList(
InvalidDriversHead->first_entry = new_entry;
}
VOID RemoveInvalidDriverFromList(
STATIC
VOID
RemoveInvalidDriverFromList(
_In_ PINVALID_DRIVERS_HEAD InvalidDriversHead
)
{
@ -201,7 +212,9 @@ VOID RemoveInvalidDriverFromList(
}
}
VOID EnumerateInvalidDrivers(
STATIC
VOID
EnumerateInvalidDrivers(
_In_ PINVALID_DRIVERS_HEAD InvalidDriversHead
)
{
@ -214,7 +227,9 @@ VOID EnumerateInvalidDrivers(
}
}
NTSTATUS ValidateDriverObjectHasBackingModule(
STATIC
NTSTATUS
ValidateDriverObjectHasBackingModule(
_In_ PSYSTEM_MODULES ModuleInformation,
_In_ PDRIVER_OBJECT DriverObject,
_Out_ PBOOLEAN Result
@ -242,7 +257,8 @@ NTSTATUS ValidateDriverObjectHasBackingModule(
}
//https://imphash.medium.com/windows-process-internals-a-few-concepts-to-know-before-jumping-on-memory-forensics-part-3-4a0e195d947b
NTSTATUS GetSystemModuleInformation(
NTSTATUS
GetSystemModuleInformation(
_Out_ PSYSTEM_MODULES ModuleInformation
)
{
@ -296,7 +312,9 @@ NTSTATUS GetSystemModuleInformation(
return STATUS_SUCCESS;
}
NTSTATUS ValidateDriverObjects(
STATIC
NTSTATUS
ValidateDriverObjects(
_In_ PSYSTEM_MODULES SystemModules,
_In_ PINVALID_DRIVERS_HEAD InvalidDriverListHead
)
@ -453,7 +471,8 @@ end:
return STATUS_SUCCESS;
}
NTSTATUS HandleValidateDriversIOCTL(
NTSTATUS
HandleValidateDriversIOCTL(
_In_ PIRP Irp
)
{
@ -581,7 +600,8 @@ NTSTATUS HandleValidateDriversIOCTL(
return status;
}
NTSTATUS IsInstructionPointerInInvalidRegion(
NTSTATUS
IsInstructionPointerInInvalidRegion(
_In_ UINT64 RIP,
_In_ PSYSTEM_MODULES SystemModules,
_Out_ PBOOLEAN Result
@ -610,7 +630,9 @@ NTSTATUS IsInstructionPointerInInvalidRegion(
return STATUS_SUCCESS;
}
NTSTATUS AnalyseNmiData(
STATIC
NTSTATUS
AnalyseNmiData(
_In_ PNMI_CONTEXT NmiContext,
_In_ PSYSTEM_MODULES SystemModules,
_In_ PIRP Irp
@ -695,7 +717,9 @@ NTSTATUS AnalyseNmiData(
return STATUS_SUCCESS;
}
BOOLEAN NmiCallback(
STATIC
BOOLEAN
NmiCallback(
_In_ PVOID Context,
_In_ BOOLEAN Handled
)
@ -745,7 +769,9 @@ BOOLEAN NmiCallback(
return TRUE;
}
NTSTATUS LaunchNonMaskableInterrupt(
STATIC
NTSTATUS
LaunchNonMaskableInterrupt(
_In_ PNMI_CONTEXT NmiContext
)
{
@ -870,113 +896,32 @@ NTSTATUS HandleNmiIOCTL(
* The RundownRoutine is executed if the thread terminates before the APC was delivered to
* user mode.
*/
VOID ApcRundownRoutine(
STATIC
VOID
ApcRundownRoutine(
_In_ PRKAPC Apc
)
{
//FreeApcAndStatusStructure( Apc, APC_CONTEXT_ID_STACKWALK );
}
VOID InsertApcToContextList(
_In_ PKAPC Apc,
STATIC
VOID
FreeApcAndDecrementApcCount(
_In_ PRKAPC Apc,
_In_ LONG ContextId
)
{
PAPC_CONTEXT_HEADER header = NULL;
ExFreePoolWithTag( Apc, POOL_TAG_APC );
GetApcContext( &header, ContextId );
if ( !header )
return;
KeAcquireGuardedMutex( &header->lock );
switch ( header->context_id )
{
case APC_CONTEXT_ID_STACKWALK:;
PAPC_STACKWALK_CONTEXT context = ( PAPC_STACKWALK_CONTEXT )header;
PAPC_STATUS apc_status = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( APC_STATUS ), POOL_TAG_APC );
if ( !apc_status )
goto unlock;
apc_status->apc = Apc;
apc_status->apc_complete = FALSE;
InsertApcIntoApcContextList( context->head, apc_status );
break;
}
unlock:
KeReleaseGuardedMutex( &header->lock );
}
VOID FreeApcContextStructure(
_Inout_ PVOID Context
)
{
PAPC_CONTEXT_HEADER header = ( PAPC_CONTEXT_HEADER )Context;
KeAcquireGuardedMutex( &header->lock );
switch ( header->context_id )
{
case APC_CONTEXT_ID_STACKWALK:;
PAPC_STACKWALK_CONTEXT context = ( PAPC_STACKWALK_CONTEXT )header;
ExFreePoolWithTag( context->head, POOL_TAG_APC );
ExFreePoolWithTag( context->modules, POOL_TAG_APC );
break;
}
KeReleaseGuardedMutex( &header->lock );
}
VOID FreeApcAndStatusStructure(
_Inout_ PKAPC Apc,
_In_ LONG ContextId
)
{
PAPC_CONTEXT_HEADER header = NULL;
GetApcContext( &header, ContextId );
if ( !header )
return;
KeAcquireGuardedMutex( &header->lock );
switch ( header->context_id )
{
case APC_CONTEXT_ID_STACKWALK:;
PAPC_STACKWALK_CONTEXT context = ( PAPC_STACKWALK_CONTEXT )header;
PLIST_ITEM entry = ( PLIST_ITEM )context->head->start;
while ( entry != NULL )
{
PAPC_STATUS apc_entry = ( PAPC_STATUS )entry->data;
if ( apc_entry->apc == Apc )
{
ExFreePoolWithTag( apc_entry->apc, POOL_TAG_APC );
ExFreePoolWithTag( entry->data, POOL_TAG_APC );
RemoveApcFromApcContextList( context->head, entry );
KeReleaseGuardedMutex( &header->lock );
return;
}
entry = entry->next;
}
break;
}
header->count -= 1;
KeReleaseGuardedMutex( &header->lock );
}
@ -984,7 +929,9 @@ VOID FreeApcAndStatusStructure(
* The KernelRoutine is executed in kernel mode at APC_LEVEL before the APC is delivered. This
* is also where we want to free our APC object.
*/
VOID ApcKernelRoutine(
STATIC
VOID
ApcKernelRoutine(
_In_ PRKAPC Apc,
_Inout_ _Deref_pre_maybenull_ PKNORMAL_ROUTINE* NormalRoutine,
_Inout_ _Deref_pre_maybenull_ PVOID* NormalContext,
@ -1040,13 +987,15 @@ VOID ApcKernelRoutine(
free:
ExFreePoolWithTag( buffer, POOL_TAG_APC );
FreeApcAndStatusStructure( Apc, APC_CONTEXT_ID_STACKWALK );
FreeApcAndDecrementApcCount( Apc, APC_CONTEXT_ID_STACKWALK );
}
/*
* The NormalRoutine is executed in user mode when the APC is delivered.
*/
VOID ApcNormalRoutine(
STATIC
VOID
ApcNormalRoutine(
_In_opt_ PVOID NormalContext,
_In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2
@ -1055,7 +1004,26 @@ VOID ApcNormalRoutine(
}
VOID ValidateThreadViaKernelApcCallback(
STATIC
VOID
IncrementApcCount(
_In_ LONG ContextId
)
{
PAPC_CONTEXT_HEADER header = NULL;
GetApcContext( &header, ContextId );
if ( !header )
return;
KeAcquireGuardedMutex( &header->lock );
header->count += 1;
KeReleaseGuardedMutex( &header->lock );
}
STATIC
VOID
ValidateThreadViaKernelApcCallback(
_In_ PEPROCESS Process,
_In_ PVOID Context
)
@ -1067,6 +1035,10 @@ VOID ValidateThreadViaKernelApcCallback(
PKAPC apc = NULL;
BOOLEAN apc_status;
/* we dont want to schedule an apc to threads owned by the kernel */
if ( Process == PsInitialSystemProcess )
return;
thread_list_head = ( PLIST_ENTRY )( ( UINT64 )Process + KPROCESS_THREADLIST_OFFSET );
thread_list_entry = thread_list_head->Flink;
@ -1110,7 +1082,7 @@ VOID ValidateThreadViaKernelApcCallback(
goto increment;
}
InsertApcToContextList( apc, APC_CONTEXT_ID_STACKWALK );
IncrementApcCount( APC_CONTEXT_ID_STACKWALK );
increment:
thread_list_entry = thread_list_entry->Flink;
@ -1123,7 +1095,8 @@ VOID ValidateThreadViaKernelApcCallback(
* routine to threads we want a stack trace of. Hence by utilising both APCs and NMIs we get
* excellent coverage of the entire system.
*/
NTSTATUS ValidateThreadsViaKernelApc()
NTSTATUS
ValidateThreadsViaKernelApc()
{
NTSTATUS status;
PAPC_STACKWALK_CONTEXT context = NULL;
@ -1133,10 +1106,10 @@ NTSTATUS ValidateThreadsViaKernelApc()
if ( !context )
return STATUS_MEMORY_NOT_ALLOCATED;
context->context_id = APC_CONTEXT_ID_STACKWALK;
context->header.context_id = APC_CONTEXT_ID_STACKWALK;
context->modules = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( SYSTEM_MODULES ), POOL_TAG_APC );
KeInitializeGuardedMutex( &context->lock );
KeInitializeGuardedMutex( &context->header.lock );
if ( !context->modules )
{
@ -1161,7 +1134,45 @@ NTSTATUS ValidateThreadsViaKernelApc()
);
}
NTSTATUS QueryApcListToCheckForCompletion()
VOID
FreeApcStackwalkApcContextInformation(
_In_ PAPC_STACKWALK_CONTEXT Context
)
{
if ( Context->modules )
ExFreePoolWithTag( Context->modules, SYSTEM_MODULES_POOL );
}
NTSTATUS
QueryActiveApcContextsForCompletion()
{
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;
KeAcquireGuardedMutex( &entry->lock );
DEBUG_LOG( "APC Context id: %lx", entry->context_id );
DEBUG_LOG( "Actice Apc Count: %i", entry->count );
if ( entry->count > 0 )
goto unlock;
switch ( entry->context_id )
{
case APC_CONTEXT_ID_STACKWALK:
FreeApcStackwalkApcContextInformation( entry);
break;
}
unlock:
KeReleaseGuardedMutex( &entry->lock );
}
return STATUS_SUCCESS;
}

View file

@ -89,31 +89,29 @@ typedef struct _SYSTEM_MODULES
}SYSTEM_MODULES, * PSYSTEM_MODULES;
typedef struct _APC_STATUS
typedef struct _APC_ENTRY
{
struct _LIST_ITEM* next;
PKAPC apc;
BOOLEAN apc_complete;
}APC_STATUS, * PAPC_STATUS;
typedef struct _APC_STACKWALK_CONTEXT
{
LONG context_id;
PLIST_HEAD head;
KGUARDED_MUTEX lock;
PSYSTEM_MODULES modules;
}APC_STACKWALK_CONTEXT, * PAPC_STACKWALK_CONTEXT;
}APC_ENTRY, * PAPC_ENTRY;
#define APC_CONTEXT_ID_STACKWALK 0x1
typedef struct _APC_CONTEXT_HEADER
{
LONG context_id;
PLIST_HEAD head;
volatile INT count;
KGUARDED_MUTEX lock;
}APC_CONTEXT_HEADER, *PAPC_CONTEXT_HEADER;
}APC_CONTEXT_HEADER, * PAPC_CONTEXT_HEADER;
typedef struct _APC_STACKWALK_CONTEXT
{
APC_CONTEXT_HEADER header;
PSYSTEM_MODULES modules;
}APC_STACKWALK_CONTEXT, * PAPC_STACKWALK_CONTEXT;
NTSTATUS GetSystemModuleInformation(
_Out_ PSYSTEM_MODULES ModuleInformation
@ -138,4 +136,7 @@ VOID FreeApcContextStructure(
NTSTATUS ValidateThreadsViaKernelApc();
NTSTATUS
QueryActiveApcContextsForCompletion();
#endif

View file

@ -264,24 +264,18 @@ VOID ListInit(
PLIST_ITEM ListInsert(
_In_ PLIST_HEAD ListHead,
_In_ PVOID Data
_In_ PLIST_ITEM NewEntry
)
{
KIRQL irql = KeGetCurrentIrql();
KeAcquireSpinLock( &ListHead->lock, &irql );
PLIST_ITEM entry = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( LIST_ITEM ), POOL_TAG_APC );
PLIST_ITEM old_entry = ListHead->start;
if ( !entry )
return;
entry->data = Data;
entry->next = ListHead->start;
ListHead->start = entry;
ListHead->start = NewEntry;
NewEntry->next = old_entry;
KeReleaseSpinLock( &ListHead->lock, irql );
return entry;
}
PVOID ListRemoveFirst(
@ -325,7 +319,7 @@ PVOID ListRemoveItem(
{
if ( entry->next == ListItem )
{
entry->next = entry->next->next;
entry->next = ListItem->next;
ExFreePoolWithTag( ListItem, POOL_TAG_APC );
goto unlock;
}

View file

@ -37,7 +37,6 @@ typedef struct _REPORT_HEADER
typedef struct _LIST_ITEM
{
struct _LIST_ITEM* next;
PVOID data;
}LIST_ITEM, * PLIST_ITEM;
@ -79,7 +78,7 @@ VOID ListInit(
PLIST_ITEM ListInsert(
_In_ PLIST_HEAD ListHead,
_In_ PVOID Data
_In_ PLIST_ITEM Data
);
PVOID ListRemoveFirst(

View file

@ -71,7 +71,7 @@ DWORD WINAPI Init(HINSTANCE hinstDLL)
// kmanager.CheckForAttachedThreads();
// break;
//}
kmanager.VerifySystemModules();
//kmanager.VerifySystemModules();
kmanager.MonitorCallbackReports();
std::this_thread::sleep_for( std::chrono::seconds( 10 ) );
}