mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
few changes
This commit is contained in:
parent
c8cc15a4ec
commit
956b25ccd2
10 changed files with 199 additions and 153 deletions
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" );
|
||||
|
||||
|
|
188
driver/modules.c
188
driver/modules.c
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 ];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ) );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue