few changes

This commit is contained in:
lhodges1 2023-09-28 23:56:07 +10:00
parent c8cc15a4ec
commit 956b25ccd2
10 changed files with 199 additions and 153 deletions

View file

@ -384,7 +384,7 @@ EnumerateProcessListWithCallbackFunction(
PLIST_ENTRY process_list_entry = NULL;
PEPROCESS base_process = PsInitialSystemProcess;
if ( !base_process || !Function)
if ( !base_process )
return;
process_list_head = ( UINT64 )( ( UINT64 )base_process + EPROCESS_PLIST_ENTRY_OFFSET );

View file

@ -78,6 +78,7 @@
#define REPORT_INVALID_PROCESS_ALLOCATION 80
#define REPORT_HIDDEN_SYSTEM_THREAD 90
#define REPORT_ILLEGAL_ATTACH_PROCESS 100
#define REPORT_APC_STACKWALK 110
/*
* Generic macros that allow you to quickly determine whether

View file

@ -731,9 +731,7 @@ DriverEntry(
IoDeleteSymbolicLink( &driver_config.device_symbolic_link );
IoDeleteDevice( DriverObject->DeviceObject );
return STATUS_FAILED_DRIVER_ENTRY;
}
EnumeratePciDevices();
}
DEBUG_LOG( "DonnaAC Driver Entry Complete" );

View file

@ -976,101 +976,121 @@ ApcKernelRoutine(
_Inout_ _Deref_pre_maybenull_ PVOID* NormalContext,
_Inout_ _Deref_pre_maybenull_ PVOID* SystemArgument1,
_Inout_ _Deref_pre_maybenull_ PVOID* SystemArgument2
)
)
{
PVOID buffer = NULL;
INT frames_captured = 0;
UINT64 stack_frame = 0;
NTSTATUS status;
BOOLEAN flag = FALSE;
PAPC_STACKWALK_CONTEXT context;
context = ( PAPC_STACKWALK_CONTEXT )Apc->NormalContext;
buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, 0x200, POOL_TAG_APC );
if ( !buffer )
goto free;
frames_captured = RtlCaptureStackBackTrace(
NULL,
STACK_FRAME_POOL_SIZE / sizeof( UINT64 ),
buffer,
NULL
);
if ( frames_captured == NULL )
goto free;
for ( INT index = 0; index < frames_captured; index++ )
{
stack_frame = *( UINT64* )( ( UINT64 )buffer + index * sizeof( UINT64 ) );
/*
* Apc->NormalContext holds the address of our context data structure that we passed into
* KeInitializeApc as the last argument.
*/
status = IsInstructionPointerInInvalidRegion(
stack_frame,
context->modules,
&flag
);
if ( !NT_SUCCESS( status ) )
{
PVOID buffer = NULL;
INT frames_captured = 0;
UINT64 stack_frame = 0;
NTSTATUS status;
BOOLEAN flag = FALSE;
PAPC_STACKWALK_CONTEXT context;
DEBUG_ERROR( "IsInstructionPointerInInvalidRegion failed with status %x", status );
goto free;
}
context = ( PAPC_STACKWALK_CONTEXT )Apc->NormalContext;
if ( flag == FALSE )
{
PAPC_STACKWALK_REPORT report = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( APC_STACKWALK_REPORT ), POOL_TAG_APC );
buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, 0x200, POOL_TAG_APC );
if ( !buffer )
if ( !report )
goto free;
frames_captured = RtlCaptureStackBackTrace(
NULL,
STACK_FRAME_POOL_SIZE / sizeof( UINT64 ),
buffer,
NULL
report->report_code = REPORT_APC_STACKWALK;
report->kthread_address = ( UINT64 )KeGetCurrentThread();
report->invalid_rip = stack_frame;
RtlCopyMemory(
&report->driver,
( UINT64 )stack_frame - 0x500,
APC_STACKWALK_BUFFER_SIZE
);
if ( frames_captured == NULL )
goto free;
for ( INT index = 0; index < frames_captured; index++ )
{
stack_frame = *( UINT64* )( ( UINT64 )buffer + index * sizeof( UINT64 ) );
/*
* Apc->NormalContext holds the address of our context data structure that we passed into
* KeInitializeApc as the last argument.
*/
status = IsInstructionPointerInInvalidRegion(
stack_frame,
context->modules,
&flag
);
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "IsInstructionPointerInInvalidRegion failed with status %x", status );
goto free;
}
}
free:
if ( buffer )
ExFreePoolWithTag( buffer, POOL_TAG_APC );
FreeApcAndDecrementApcCount( Apc, APC_CONTEXT_ID_STACKWALK );
}
/*
* The NormalRoutine is executed in user mode when the APC is delivered.
*/
STATIC
VOID
ApcNormalRoutine(
_In_opt_ PVOID NormalContext,
_In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2
)
{
InsertReportToQueue( report );
}
}
STATIC
VOID
ValidateThreadViaKernelApcCallback(
_In_ PEPROCESS Process,
_In_ PVOID Context
)
{
NTSTATUS status;
PLIST_ENTRY thread_list_head;
PLIST_ENTRY thread_list_entry;
PETHREAD current_thread;
PKAPC apc = NULL;
BOOLEAN apc_status;
PAPC_STACKWALK_CONTEXT context = ( PAPC_STACKWALK_CONTEXT )Context;
LPCSTR process_name = PsGetProcessImageFileName( Process );
free:
/* we dont want to schedule an apc to threads owned by the kernel */
if ( Process == PsInitialSystemProcess )
return;
if ( buffer )
ExFreePoolWithTag( buffer, POOL_TAG_APC );
/* We are not interested in these processess.. for now lol */
if ( !strcmp( process_name, "svchost.exe" ) ||
!strcmp( process_name, "Registry" ) ||
!strcmp( process_name, "smss.exe" ) ||
!strcmp( process_name, "csrss.exe" ) )
return;
FreeApcAndDecrementApcCount( Apc, APC_CONTEXT_ID_STACKWALK );
}
/*
* The NormalRoutine is executed in user mode when the APC is delivered.
*/
STATIC
VOID
ApcNormalRoutine(
_In_opt_ PVOID NormalContext,
_In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2
)
{
}
STATIC
VOID
ValidateThreadViaKernelApcCallback(
_In_ PEPROCESS Process,
_In_ PVOID Context
)
{
NTSTATUS status;
PLIST_ENTRY thread_list_head;
PLIST_ENTRY thread_list_entry;
PETHREAD current_thread;
PKAPC apc = NULL;
BOOLEAN apc_status;
PAPC_STACKWALK_CONTEXT context = ( PAPC_STACKWALK_CONTEXT )Context;
LPCSTR process_name = PsGetProcessImageFileName( Process );
/* we dont want to schedule an apc to threads owned by the kernel */
if ( Process == PsInitialSystemProcess )
return;
/* We are not interested in these processess.. for now lol */
if ( !strcmp( process_name, "svchost.exe" ) ||
!strcmp( process_name, "Registry" ) ||
!strcmp( process_name, "smss.exe" ) ||
!strcmp( process_name, "csrss.exe" ) )
return;
thread_list_head = ( PLIST_ENTRY )( ( UINT64 )Process + KPROCESS_THREADLIST_OFFSET );
thread_list_entry = thread_list_head->Flink;

View file

@ -26,6 +26,17 @@ typedef struct _MODULE_VALIDATION_FAILURE
}MODULE_VALIDATION_FAILURE, *PMODULE_VALIDATION_FAILURE;
#define APC_STACKWALK_BUFFER_SIZE 4096
typedef struct _APC_STACKWALK_REPORT
{
INT report_code;
UINT64 kthread_address;
UINT64 invalid_rip;
CHAR driver[ APC_STACKWALK_BUFFER_SIZE ];
}APC_STACKWALK_REPORT, *PAPC_STACKWALK_REPORT;
/* system modules information */
typedef struct _SYSTEM_MODULES

View file

@ -225,6 +225,18 @@ HandlePeriodicGlobalReportQueueQuery(
total_size += sizeof( INVALID_PROCESS_ALLOCATION_REPORT );
break;
case REPORT_APC_STACKWALK:
RtlCopyMemory(
( UINT64 )report_buffer + sizeof( GLOBAL_REPORT_QUEUE_HEADER ) + total_size,
report,
sizeof( APC_STACKWALK_REPORT )
);
total_size += sizeof( APC_STACKWALK_REPORT );
break;
}
/* QueuePop frees the node, but we still need to free the returned data */

View file

@ -25,6 +25,7 @@
#define REPORT_INVALID_PROCESS_ALLOCATION 80
#define REPORT_HIDDEN_SYSTEM_THREAD 90
#define REPORT_ILLEGAL_ATTACH_PROCESS 100
#define REPORT_APC_STACKWALK 110
#define TEST_STEAM_64_ID 123456789;
@ -191,6 +192,14 @@ namespace global
INT CanUserProceed;
INT reason;
};
struct APC_STACKWALK_REPORT
{
INT report_code;
UINT64 kthread_address;
UINT64 invalid_rip;
CHAR driver[ 4096 ];
};
}
}

View file

@ -174,12 +174,14 @@ VOID kernelmode::Driver::QueryReportQueue()
LONG buffer_size;
REPORT_ID* report_header;
SIZE_T total_size = NULL;
global::report_structures::OPEN_HANDLE_FAILURE_REPORT* handle_report;
global::report_structures::ATTACH_PROCESS_REPORT* attach_report;
global::report_structures::INVALID_PROCESS_ALLOCATION_REPORT* allocation_report;
global::report_structures::OPEN_HANDLE_FAILURE_REPORT handle_report;
global::report_structures::ATTACH_PROCESS_REPORT attach_report;
global::report_structures::INVALID_PROCESS_ALLOCATION_REPORT allocation_report;
global::report_structures::APC_STACKWALK_REPORT apc_report;
/* allocate enough for the largest report buffer * max reports */
buffer_size =
sizeof( global::report_structures::INVALID_PROCESS_ALLOCATION_REPORT ) * MAX_REPORTS_PER_IRP +
sizeof( global::report_structures::APC_STACKWALK_REPORT ) * MAX_REPORTS_PER_IRP +
sizeof( global::report_structures::REPORT_QUEUE_HEADER );
buffer = malloc( buffer_size );
@ -208,50 +210,32 @@ VOID kernelmode::Driver::QueryReportQueue()
if ( !header )
goto end;
LOG_INFO( "Report count: %d", header->count );
if ( header->count == 0 )
goto end;
for ( INT i = 0; i < header->count; i++ )
for ( INT index = 0; index < header->count; index++ )
{
report_header = ( REPORT_ID* )( ( UINT64 )buffer +
sizeof( global::report_structures::REPORT_QUEUE_HEADER ) + total_size );
LOG_INFO( "Report id: %d", report_header->report_id );
if ( report_header->report_id == REPORT_ILLEGAL_ATTACH_PROCESS )
switch ( report_header->report_id )
{
attach_report = ( global::report_structures::ATTACH_PROCESS_REPORT* )(
( UINT64 )buffer + sizeof( global::report_structures::REPORT_QUEUE_HEADER ) + total_size );
this->report_interface->ReportViolation( attach_report );
total_size += sizeof( global::report_structures::ATTACH_PROCESS_REPORT );
continue;
}
else if ( report_header->report_id == REPORT_ILLEGAL_HANDLE_OPERATION )
{
handle_report = ( global::report_structures::OPEN_HANDLE_FAILURE_REPORT* )(
( UINT64 )buffer + sizeof( global::report_structures::REPORT_QUEUE_HEADER ) + total_size );
this->report_interface->ReportViolation( handle_report );
total_size += sizeof( global::report_structures::OPEN_HANDLE_FAILURE_REPORT );
continue;
}
else if ( report_header->report_id == REPORT_INVALID_PROCESS_ALLOCATION )
{
allocation_report = ( global::report_structures::INVALID_PROCESS_ALLOCATION_REPORT* )(
( UINT64 )buffer + sizeof( global::report_structures::REPORT_QUEUE_HEADER ) + total_size );
this->report_interface->ReportViolation( allocation_report );
total_size += sizeof( global::report_structures::INVALID_PROCESS_ALLOCATION_REPORT );
continue;
case REPORT_ILLEGAL_ATTACH_PROCESS:
ReportTypeFromReportQueue<global::report_structures::ATTACH_PROCESS_REPORT>( buffer, &total_size, &attach_report );
break;
case REPORT_ILLEGAL_HANDLE_OPERATION:
ReportTypeFromReportQueue<global::report_structures::OPEN_HANDLE_FAILURE_REPORT>( buffer, &total_size, &handle_report );
break;
case REPORT_INVALID_PROCESS_ALLOCATION:
ReportTypeFromReportQueue<global::report_structures::INVALID_PROCESS_ALLOCATION_REPORT>( buffer, &total_size, &allocation_report );
break;
case REPORT_APC_STACKWALK:
ReportTypeFromReportQueue<global::report_structures::APC_STACKWALK_REPORT>( buffer, &total_size, &apc_report );
break;
default:
break;
}
}

View file

@ -58,6 +58,17 @@ namespace kernelmode
VOID CheckForAttachedThreads();
VOID VerifyProcessLoadedModuleExecutableRegions();
VOID SendClientHardwareInformation();
template <typename T>
VOID ReportTypeFromReportQueue(CONST PVOID Buffer, PSIZE_T Offset, PVOID Report)
{
Report = ( T* )(
( UINT64 )Buffer + sizeof( global::report_structures::REPORT_QUEUE_HEADER ) + *Offset );
this->report_interface->ReportViolation( (T*)Report );
*Offset += sizeof( T );
}
};
struct DRIVER_INITIATION_INFORMATION

View file

@ -43,35 +43,35 @@ DWORD WINAPI Init(HINSTANCE hinstDLL)
while ( !GetAsyncKeyState( VK_DELETE ) )
{
//int seed = ( rand() % 7 );
int seed = ( rand() % 7 );
//std::cout << "Seed: " << seed << std::endl;
std::cout << "Seed: " << seed << std::endl;
//switch ( seed )
//{
//case 0:
// kmanager.EnumerateHandleTables();
// break;
//case 1:
// kmanager.PerformIntegrityCheck();
// break;
//case 2:
// kmanager.ScanPoolsForUnlinkedProcesses();
// break;
//case 3:
// kmanager.VerifySystemModules();
// break;
//case 4:
// kmanager.ValidateProcessModules();
// break;
//case 5:
// kmanager.RunNmiCallbacks();
// break;
//case 6:
// kmanager.CheckForAttachedThreads();
// break;
//}
//kmanager.VerifySystemModules();
switch ( seed )
{
case 0:
kmanager.EnumerateHandleTables();
break;
case 1:
kmanager.PerformIntegrityCheck();
break;
case 2:
kmanager.ScanPoolsForUnlinkedProcesses();
break;
case 3:
kmanager.VerifySystemModules();
break;
case 4:
kmanager.ValidateProcessModules();
break;
case 5:
kmanager.RunNmiCallbacks();
break;
case 6:
kmanager.CheckForAttachedThreads();
break;
}
kmanager.VerifySystemModules();
kmanager.MonitorCallbackReports();
std::this_thread::sleep_for( std::chrono::seconds( 10 ) );
}