mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
prevents threads from disabling apcs
This commit is contained in:
parent
ce3c041fbc
commit
651b310f1c
2 changed files with 61 additions and 5 deletions
|
@ -45,6 +45,9 @@
|
|||
#define KTHREAD_THREADLIST_OFFSET 0x2f8
|
||||
#define KTHREAD_APC_STATE_OFFSET 0x258
|
||||
#define KTHREAD_START_ADDRESS_OFFSET 0x450
|
||||
#define KTHREAD_MISC_FLAGS_OFFSET 0x074
|
||||
|
||||
#define KTHREAD_MISC_FLAGS_APC_QUEUEABLE 14
|
||||
|
||||
#define EPROCESS_PEAK_VIRTUAL_SIZE_OFFSET 0x490
|
||||
#define EPROCESS_VAD_ROOT_OFFSET 0x7d8
|
||||
|
@ -1118,6 +1121,8 @@ typedef struct _STORAGE_DEVICE_DESCRIPTOR {
|
|||
UCHAR RawDeviceProperties[ 1 ];
|
||||
} STORAGE_DEVICE_DESCRIPTOR, * PSTORAGE_DEVICE_DESCRIPTOR;
|
||||
|
||||
|
||||
|
||||
NTKERNELAPI
|
||||
BOOLEAN
|
||||
ExEnumHandleTable(
|
||||
|
|
|
@ -929,7 +929,10 @@ HandleNmiIOCTL(
|
|||
if ( !NT_SUCCESS( status ) )
|
||||
{
|
||||
DEBUG_ERROR( "Error running NMI callbacks" );
|
||||
ExFreePoolWithTag( system_modules.address, SYSTEM_MODULES_POOL );
|
||||
|
||||
if (system_modules.address )
|
||||
ExFreePoolWithTag( system_modules.address, SYSTEM_MODULES_POOL );
|
||||
|
||||
return status;
|
||||
}
|
||||
status = AnalyseNmiData( &nmi_context, &system_modules, Irp );
|
||||
|
@ -937,8 +940,11 @@ HandleNmiIOCTL(
|
|||
if ( !NT_SUCCESS( status ) )
|
||||
DEBUG_ERROR( "Error analysing nmi data" );
|
||||
|
||||
ExFreePoolWithTag( system_modules.address, SYSTEM_MODULES_POOL );
|
||||
ExFreePoolWithTag( nmi_context.nmi_core_context, NMI_CONTEXT_POOL );
|
||||
if (system_modules.address )
|
||||
ExFreePoolWithTag( system_modules.address, SYSTEM_MODULES_POOL );
|
||||
|
||||
if (nmi_context.nmi_core_context )
|
||||
ExFreePoolWithTag( nmi_context.nmi_core_context, NMI_CONTEXT_POOL );
|
||||
|
||||
if ( nmi_context.stack_frames )
|
||||
ExFreePoolWithTag( nmi_context.stack_frames, STACK_FRAMES_POOL );
|
||||
|
@ -1065,6 +1071,27 @@ ApcNormalRoutine(
|
|||
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
FlipKThreadMiscFlagsFlag(
|
||||
_In_ PKTHREAD Thread,
|
||||
_In_ LONG FlagIndex,
|
||||
_In_ BOOLEAN NewValue
|
||||
)
|
||||
{
|
||||
PLONG misc_flags = ( PLONG )( ( UINT64 )Thread + KTHREAD_MISC_FLAGS_OFFSET );
|
||||
LONG mask = 1U << FlagIndex;
|
||||
|
||||
if ( !MmIsAddressValid( misc_flags ) )
|
||||
return FALSE;
|
||||
|
||||
if ( NewValue )
|
||||
*misc_flags |= mask;
|
||||
else
|
||||
*misc_flags &= ~mask;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
ValidateThreadViaKernelApcCallback(
|
||||
|
@ -1078,6 +1105,8 @@ ValidateThreadViaKernelApcCallback(
|
|||
PETHREAD current_thread;
|
||||
PKAPC apc = NULL;
|
||||
BOOLEAN apc_status;
|
||||
PLONG misc_flags = NULL;
|
||||
BOOLEAN apc_queueable = FALSE;
|
||||
PAPC_STACKWALK_CONTEXT context = ( PAPC_STACKWALK_CONTEXT )Context;
|
||||
LPCSTR process_name = PsGetProcessImageFileName( Process );
|
||||
|
||||
|
@ -1101,7 +1130,7 @@ ValidateThreadViaKernelApcCallback(
|
|||
{
|
||||
current_thread = ( PETHREAD )( ( UINT64 )thread_list_entry - KTHREAD_THREADLIST_OFFSET );
|
||||
|
||||
if (current_thread == KeGetCurrentThread())
|
||||
if (current_thread == KeGetCurrentThread() || !current_thread )
|
||||
goto increment;
|
||||
|
||||
apc = ( PKAPC )ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( KAPC ), POOL_TAG_APC );
|
||||
|
@ -1109,6 +1138,25 @@ ValidateThreadViaKernelApcCallback(
|
|||
if ( !apc )
|
||||
goto increment;
|
||||
|
||||
/*
|
||||
* Its possible to set the KThread->ApcQueueable flag to false ensuring that no APCs can be
|
||||
* queued to the thread, as KeInsertQueueApc will check this flag before queueing an APC so
|
||||
* lets make sure we flip this before before queueing ours. Since we filter out any system
|
||||
* threads this should be fine... c:
|
||||
*/
|
||||
misc_flags = ( PLONG )( ( UINT64 )current_thread + KTHREAD_MISC_FLAGS_OFFSET );
|
||||
|
||||
/* sanity check */
|
||||
if ( !MmIsAddressValid( misc_flags ) )
|
||||
goto increment;
|
||||
|
||||
/* todo: We should also flag all threads that have the flag set to false */
|
||||
if ( *misc_flags >> KTHREAD_MISC_FLAGS_APC_QUEUEABLE == FALSE )
|
||||
{
|
||||
if ( !FlipKThreadMiscFlagsFlag( current_thread, KTHREAD_MISC_FLAGS_APC_QUEUEABLE, TRUE ) )
|
||||
goto increment;
|
||||
}
|
||||
|
||||
KeInitializeApc(
|
||||
apc,
|
||||
current_thread,
|
||||
|
@ -1130,6 +1178,8 @@ ValidateThreadViaKernelApcCallback(
|
|||
if ( !apc_status )
|
||||
{
|
||||
DEBUG_ERROR( "KeInsertQueueApc failed" );
|
||||
ExFreePoolWithTag( apc, POOL_TAG_APC );
|
||||
apc = NULL;
|
||||
goto increment;
|
||||
}
|
||||
|
||||
|
@ -1204,4 +1254,5 @@ FreeApcStackwalkApcContextInformation(
|
|||
|
||||
if ( Context->modules )
|
||||
ExFreePoolWithTag( Context->modules, POOL_TAG_APC );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue