mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
start doing some ept detection stuff
This commit is contained in:
parent
651b310f1c
commit
f6d3966ecb
7 changed files with 195 additions and 19 deletions
|
@ -91,7 +91,8 @@ ObPreOpCallbackRoutine(
|
|||
|
||||
DEBUG_LOG( "handle stripped from: %s", process_creator_name );
|
||||
|
||||
POPEN_HANDLE_FAILURE_REPORT report = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( OPEN_HANDLE_FAILURE_REPORT ), REPORT_POOL_TAG );
|
||||
POPEN_HANDLE_FAILURE_REPORT report =
|
||||
ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( OPEN_HANDLE_FAILURE_REPORT ), REPORT_POOL_TAG );
|
||||
|
||||
if ( !report )
|
||||
goto end;
|
||||
|
@ -299,10 +300,10 @@ EnumHandleCallback(
|
|||
DEBUG_LOG( "Stripped PROCESS_VM_WRITE" );
|
||||
}
|
||||
|
||||
//POPEN_HANDLE_FAILURE_REPORT report = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( OPEN_HANDLE_FAILURE_REPORT ), REPORT_POOL_TAG );
|
||||
POPEN_HANDLE_FAILURE_REPORT report = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( OPEN_HANDLE_FAILURE_REPORT ), REPORT_POOL_TAG );
|
||||
|
||||
//if ( !report )
|
||||
// goto end;
|
||||
if ( !report )
|
||||
goto end;
|
||||
|
||||
/*
|
||||
* Using the same report structure as the ObRegisterCallbacks report
|
||||
|
@ -312,14 +313,14 @@ EnumHandleCallback(
|
|||
* another queue specifically for open handle reports since they will be
|
||||
* rare.
|
||||
*/
|
||||
//report->report_code = REPORT_ILLEGAL_HANDLE_OPERATION;
|
||||
//report->is_kernel_handle = NULL;
|
||||
//report->process_id = PsGetProcessId( process );
|
||||
//report->thread_id = NULL;
|
||||
//report->access = handle_access_mask;
|
||||
//RtlCopyMemory( &report->process_name, process_name, HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH );
|
||||
report->report_code = REPORT_ILLEGAL_HANDLE_OPERATION;
|
||||
report->is_kernel_handle = NULL;
|
||||
report->process_id = PsGetProcessId( process );
|
||||
report->thread_id = NULL;
|
||||
report->access = handle_access_mask;
|
||||
RtlCopyMemory( &report->process_name, process_name, HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH );
|
||||
|
||||
//InsertReportToQueue( report );
|
||||
InsertReportToQueue( report );
|
||||
}
|
||||
|
||||
end:
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#define MODULES_REPORT_POOL_TAG 'modu'
|
||||
#define POOL_TAG_LIST_ITEM 'tsil'
|
||||
|
||||
#define IA32_APERF_MSR 0x000000E8
|
||||
|
||||
#define ERROR -1
|
||||
#define STACK_FRAME_POOL_SIZE 0x200
|
||||
#define NUMBER_HASH_BUCKETS 37
|
||||
|
|
|
@ -640,14 +640,14 @@ DriverUnload(
|
|||
//QueryActiveApcContextsForCompletion();
|
||||
|
||||
/* dont unload while we have active APC operations */
|
||||
while ( !FreeAllApcContextStructures() )
|
||||
YieldProcessor();
|
||||
//while ( !FreeAllApcContextStructures() )
|
||||
// YieldProcessor();
|
||||
|
||||
/* This is safe to call even if the callbacks have already been disabled */
|
||||
UnregisterCallbacksOnProcessTermination();
|
||||
//UnregisterCallbacksOnProcessTermination();
|
||||
|
||||
CleanupDriverConfigOnUnload();
|
||||
IoDeleteDevice( DriverObject->DeviceObject );
|
||||
//CleanupDriverConfigOnUnload();
|
||||
//IoDeleteDevice( DriverObject->DeviceObject );
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -747,6 +747,10 @@ DriverEntry(
|
|||
return STATUS_FAILED_DRIVER_ENTRY;
|
||||
}
|
||||
|
||||
UNICODE_STRING string = RTL_CONSTANT_STRING( L"ExAllocatePoolWithTag" );
|
||||
|
||||
DetectEptPresenceOnFunction( &string );
|
||||
|
||||
DEBUG_LOG( "DonnaAC Driver Entry Complete" );
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
#define TOTAL_ITERATION_COUNT 20
|
||||
|
||||
#define IA32_APERF_MSR 0x000000E8
|
||||
|
||||
/*
|
||||
* TODO: Perform the test in a loop and average the delta out, then compare it
|
||||
* to an instruction such as FYL2XP1 (source: secret.club) which has an average
|
||||
|
|
|
@ -1266,4 +1266,170 @@ EnumeratePciDevices()
|
|||
}
|
||||
|
||||
ExFreePoolWithTag( device_interfaces, NULL );
|
||||
}
|
||||
|
||||
STATIC
|
||||
PVOID
|
||||
ScanForSignature(
|
||||
_In_ PVOID BaseAddress,
|
||||
_In_ SIZE_T MaxLength,
|
||||
_In_ LPCSTR Signature,
|
||||
_In_ SIZE_T SignatureLength
|
||||
)
|
||||
{
|
||||
CHAR current_char = 0;
|
||||
CHAR current_sig_char = 0;
|
||||
|
||||
for ( INT index = 0; index < MaxLength; index++ )
|
||||
{
|
||||
for ( INT sig_index = 0; sig_index < SignatureLength + 1; sig_index++ )
|
||||
{
|
||||
current_char = *( PCHAR )( ( UINT64 )BaseAddress + index + sig_index );
|
||||
current_sig_char = Signature[ sig_index ];
|
||||
|
||||
if ( sig_index == SignatureLength )
|
||||
return ( UINT64 )BaseAddress + index;
|
||||
|
||||
if ( current_char != current_sig_char )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma optimize("", off)
|
||||
|
||||
STATIC
|
||||
UINT64
|
||||
MeasureInstructionRead(
|
||||
_In_ PVOID InstructionAddress
|
||||
)
|
||||
{
|
||||
UINT64 start = __readmsr( IA32_APERF_MSR ) << 32;
|
||||
CHAR character = *(PCHAR)InstructionAddress;
|
||||
return ( __readmsr( IA32_APERF_MSR ) << 32 ) - start;
|
||||
}
|
||||
|
||||
STATIC
|
||||
UINT64
|
||||
MeasureInstructionExecute(
|
||||
_In_ PVOID InstructionAddress
|
||||
)
|
||||
{
|
||||
UINT64 start = __readmsr( IA32_APERF_MSR ) << 32;
|
||||
( ( VOID( * )( ) )InstructionAddress )( );
|
||||
return ( __readmsr( IA32_APERF_MSR ) << 32 ) - start;
|
||||
}
|
||||
|
||||
#pragma optimize("", on)
|
||||
|
||||
UINT64 MeasureReads(
|
||||
_In_ PVOID Address,
|
||||
_In_ ULONG Count
|
||||
)
|
||||
{
|
||||
UINT64 read_average = 0;
|
||||
KIRQL old_irql;
|
||||
|
||||
MeasureInstructionRead( Address );
|
||||
|
||||
old_irql = __readcr8();
|
||||
__writecr8( HIGH_LEVEL );
|
||||
|
||||
_disable();
|
||||
|
||||
for ( INT iteration = 0; iteration < Count; iteration++ )
|
||||
{
|
||||
read_average += MeasureInstructionRead( Address );
|
||||
}
|
||||
|
||||
_enable();
|
||||
__writecr8( old_irql );
|
||||
|
||||
return read_average / Count;
|
||||
}
|
||||
|
||||
UINT64 MeasureExecutionWithAlternatingReads(
|
||||
_In_ PVOID Address,
|
||||
_In_ ULONG Count
|
||||
)
|
||||
{
|
||||
UINT64 read_average = 0;
|
||||
UINT64 execute_average = 0;
|
||||
KIRQL old_irql;
|
||||
|
||||
MeasureInstructionRead( Address );
|
||||
MeasureInstructionExecute( Address );
|
||||
|
||||
old_irql = __readcr8();
|
||||
__writecr8( HIGH_LEVEL );
|
||||
|
||||
_disable();
|
||||
|
||||
for ( INT iteration = 0; iteration < Count; iteration++ )
|
||||
{
|
||||
read_average += MeasureInstructionRead( Address );
|
||||
execute_average += MeasureInstructionExecute( Address );
|
||||
}
|
||||
|
||||
_enable();
|
||||
__writecr8( old_irql );
|
||||
|
||||
return execute_average / Count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Even though we test for the presence of a hypervisor, we should still test for the presence
|
||||
* of EPT hooks on key functions.
|
||||
*
|
||||
* Credits to momo5502 for the idea: https://momo5502.com/blog/?p=255
|
||||
*/
|
||||
NTSTATUS
|
||||
DetectEptPresenceOnFunction(
|
||||
_In_ PUNICODE_STRING RoutineName
|
||||
)
|
||||
{
|
||||
PVOID function_address = NULL;
|
||||
PVOID ret_instruction_address = NULL;
|
||||
UINT64 page_base = NULL;
|
||||
LPCSTR ret_instruction = "\xC3";
|
||||
ULONG num_iterations = 200;
|
||||
UINT64 read_average = 0;
|
||||
UINT64 read_exec_average = 0;
|
||||
|
||||
DEBUG_LOG( "Sizxe of ret instruction: %llx", strlen( ret_instruction ) );
|
||||
|
||||
if ( !RoutineName )
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* some hard coded stuff for ExAllocatePoolWithTag for now */
|
||||
function_address = ( UINT64 )MmGetSystemRoutineAddress( RoutineName );
|
||||
|
||||
if ( !function_address )
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
DEBUG_LOG( "NtCreateFile Virtual Address: %llx", ( UINT64 )function_address );
|
||||
|
||||
page_base = ( UINT64 )function_address & 0xfffffffffffff000;
|
||||
|
||||
DEBUG_LOG( "Page base: %llx", page_base );
|
||||
|
||||
ret_instruction_address = ScanForSignature(
|
||||
page_base,
|
||||
PAGE_SIZE,
|
||||
ret_instruction,
|
||||
strlen( ret_instruction )
|
||||
);
|
||||
|
||||
if ( !ret_instruction_address )
|
||||
return STATUS_NOT_FOUND;
|
||||
|
||||
DEBUG_LOG( "Ret instruction: %llx", ( UINT64 )ret_instruction_address );
|
||||
|
||||
for ( int i = 0; i < 50; i++ )
|
||||
{
|
||||
read_average = MeasureReads( ret_instruction_address, num_iterations );
|
||||
read_exec_average = MeasureInstructionRead( ret_instruction_address, num_iterations );
|
||||
|
||||
DEBUG_LOG( "Read average: %llx, read exec average: %llx", read_average, read_exec_average );
|
||||
}
|
||||
}
|
|
@ -39,4 +39,9 @@ ParseSMBIOSTable(
|
|||
VOID
|
||||
EnumeratePciDevices();
|
||||
|
||||
NTSTATUS
|
||||
DetectEptPresenceOnFunction(
|
||||
_In_ PUNICODE_STRING RoutineName
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace kernelmode
|
|||
//VOID GetKernelStructureOffsets();
|
||||
|
||||
template <typename T>
|
||||
VOID ReportTypeFromReportQueue( CONST PVOID Buffer, PSIZE_T Offset, CONST PVOID Report )
|
||||
VOID ReportTypeFromReportQueue( CONST PVOID Buffer, PSIZE_T Offset, PVOID Report )
|
||||
{
|
||||
Report = ( T* )(
|
||||
( UINT64 )Buffer + sizeof( global::report_structures::REPORT_QUEUE_HEADER ) + *Offset );
|
||||
|
|
Loading…
Reference in a new issue