HyperDbg Debugger
Loading...
Searching...
No Matches
ExecTrap.c File Reference

The reversing machine's routines. More...

#include "pch.h"

Functions

BOOLEAN ExecTrapTraverseThroughOsPageTables (PVMM_EPT_PAGE_TABLE EptTable, CR3_TYPE TargetCr3, CR3_TYPE KernelCr3)
 This function gets virtual address and returns its PTE of the virtual address based on the specific cr3 but without switching to the target address.
 
BOOLEAN ExecTrapAllocateUserDisabledMbecEptPageTable ()
 Initialize the needed structure for hooking user-mode execution.
 
BOOLEAN ExecTrapAllocateKernelDisabledMbecEptPageTable ()
 Initialize the needed structure for hooking kernel-mode execution.
 
BOOLEAN ExecTrapEnableExecuteOnlyPages (PVMM_EPT_PAGE_TABLE EptTable)
 Adjust execute-only bits bit of target page-table.
 
VOID ExecTrapReadRamPhysicalRegions ()
 Read the RAM regions (physical address)
 
BOOLEAN ExecTrapInitialize ()
 Initialize the reversing machine based on service request.
 
VOID ExecTrapUninitialize ()
 Uinitialize the needed structure for the reversing machine.
 
VOID ExecTrapRestoreToNormalEptp (VIRTUAL_MACHINE_STATE *VCpu)
 restore to normal EPTP
 
VOID ExecTrapChangeToExecuteOnlyEptp (VIRTUAL_MACHINE_STATE *VCpu)
 change to execute-only EPTP
 
VOID ExecTrapChangeToUserDisabledMbecEptp (VIRTUAL_MACHINE_STATE *VCpu)
 change to user-disabled MBEC EPTP
 
VOID ExecTrapChangeToKernelDisabledMbecEptp (VIRTUAL_MACHINE_STATE *VCpu)
 change to kernel-disabled MBEC EPTP
 
VOID ExecTrapHandleMoveToAdjustedTrapState (VIRTUAL_MACHINE_STATE *VCpu, DEBUGGER_EVENT_MODE_TYPE TargetMode)
 Restore the execution of the trap to adjusted trap state.
 
BOOLEAN ExecTrapHandleEptViolationVmexit (VIRTUAL_MACHINE_STATE *VCpu, VMX_EXIT_QUALIFICATION_EPT_VIOLATION *ViolationQualification)
 Handle EPT Violations related to the MBEC hooks.
 
VOID ExecTrapHandleCr3Vmexit (VIRTUAL_MACHINE_STATE *VCpu)
 Handle MOV to CR3 vm-exits for hooking mode execution.
 
BOOLEAN ExecTrapAddProcessToWatchingList (UINT32 ProcessId)
 Add the target process to the watching list.
 
BOOLEAN ExecTrapRemoveProcessFromWatchingList (UINT32 ProcessId)
 Remove the target process from the watching list.
 

Detailed Description

The reversing machine's routines.

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.4
Date
2023-07-05

Function Documentation

◆ ExecTrapAddProcessToWatchingList()

BOOLEAN ExecTrapAddProcessToWatchingList ( UINT32 ProcessId)

Add the target process to the watching list.

Parameters
ProcessId
Returns
BOOLEAN
895{
899 (UINT64)ProcessId);
900}
unsigned __int64 UINT64
Definition BasicTypes.h:21
#define MAXIMUM_NUMBER_OF_PROCESSES_FOR_USER_KERNEL_EXEC_THREAD
maximum number of processes for a simultaneous user-mode, kernel-mode execution trap
Definition ExecTrap.h:23
USER_KERNEL_EXECUTION_TRAP_STATE g_ExecTrapState
State of the trap-flag.
Definition GlobalVariables.h:162
BOOLEAN InsertionSortInsertItem(UINT64 ArrayPtr[], UINT32 *NumberOfItems, UINT32 MaxNumOfItems, UINT64 Key)
Function to implement insertion sort.
Definition InsertionSort.c:24
UINT32 NumberOfItems
Definition ExecTrap.h:35
UINT64 InterceptionProcessIds[MAXIMUM_NUMBER_OF_PROCESSES_FOR_USER_KERNEL_EXEC_THREAD]
Definition ExecTrap.h:36

◆ ExecTrapAllocateKernelDisabledMbecEptPageTable()

BOOLEAN ExecTrapAllocateKernelDisabledMbecEptPageTable ( )

Initialize the needed structure for hooking kernel-mode execution.

should be called from vmx non-root mode

Returns
BOOLEAN
320{
321 PVMM_EPT_PAGE_TABLE ModeBasedEptTable;
322 EPT_POINTER EPTP = {0};
323
324 //
325 // Allocate another EPT page table
326 //
327 ModeBasedEptTable = EptAllocateAndCreateIdentityPageTable();
328
329 if (ModeBasedEptTable == NULL)
330 {
331 //
332 // There was an error allocating MBEC page tables
333 //
334 return FALSE;
335 }
336
337 //
338 // Disable EPT user-mode execution bit for the target EPTP
339 //
341
342 //
343 // Set the global address for MBEC EPT page table
344 //
346
347 //
348 // For performance, we let the processor know it can cache the EPT
349 //
350 EPTP.MemoryType = MEMORY_TYPE_WRITE_BACK;
351
352 //
353 // We might utilize the 'access' and 'dirty' flag features in the dirty logging mechanism
354 //
355 EPTP.EnableAccessAndDirtyFlags = TRUE;
356
357 //
358 // Bits 5:3 (1 less than the EPT page-walk length) must be 3, indicating an EPT page-walk length of 4;
359 // see Section 28.2.2
360 //
361 EPTP.PageWalkLength = 3;
362
363 //
364 // The physical page number of the page table we will be using
365 //
366 EPTP.PageFrameNumber = (SIZE_T)VirtualAddressToPhysicalAddress(&ModeBasedEptTable->PML4) / PAGE_SIZE;
367
368 //
369 // We will write the EPTP to the VMCS later
370 //
371 g_EptState->ModeBasedKernelDisabledEptPointer.AsUInt = EPTP.AsUInt;
372
373 return TRUE;
374}
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
_Use_decl_annotations_ UINT64 VirtualAddressToPhysicalAddress(_In_ PVOID VirtualAddress)
Converts Virtual Address to Physical Address.
Definition Conversion.c:154
PVMM_EPT_PAGE_TABLE EptAllocateAndCreateIdentityPageTable(VOID)
Allocates page maps and create identity page table.
Definition Ept.c:642
EPT_STATE * g_EptState
Save the state and variables related to EPT.
Definition GlobalVariables.h:50
BOOLEAN ModeBasedExecHookDisableKernelModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
Adjust (unset) kernel-mode execution bit of target page-table but allow user-mode execution.
Definition ModeBasedExecHook.c:67
#define PAGE_SIZE
Size of each page (4096 bytes)
Definition common.h:69
PVMM_EPT_PAGE_TABLE ModeBasedKernelDisabledEptPageTable
Definition Ept.h:123
EPT_POINTER ModeBasedKernelDisabledEptPointer
Definition Ept.h:125
Structure for saving EPT Table.
Definition State.h:105
EPT_PML4_POINTER PML4[VMM_EPT_PML4E_COUNT]
28.2.2 Describes 512 contiguous 512GB memory regions each with 512 1GB regions.
Definition State.h:110

◆ ExecTrapAllocateUserDisabledMbecEptPageTable()

BOOLEAN ExecTrapAllocateUserDisabledMbecEptPageTable ( )

Initialize the needed structure for hooking user-mode execution.

should be called from vmx non-root mode

Returns
BOOLEAN
256{
257 PVMM_EPT_PAGE_TABLE ModeBasedEptTable;
258 EPT_POINTER EPTP = {0};
259
260 //
261 // Allocate another EPT page table
262 //
263 ModeBasedEptTable = EptAllocateAndCreateIdentityPageTable();
264
265 if (ModeBasedEptTable == NULL)
266 {
267 //
268 // There was an error allocating MBEC page tables
269 //
270 return FALSE;
271 }
272
273 //
274 // Disable EPT user-mode execution bit for the target EPTP
275 //
277
278 //
279 // Set the global address for MBEC EPT page table
280 //
282
283 //
284 // For performance, we let the processor know it can cache the EPT
285 //
286 EPTP.MemoryType = MEMORY_TYPE_WRITE_BACK;
287
288 //
289 // We might utilize the 'access' and 'dirty' flag features in the dirty logging mechanism
290 //
291 EPTP.EnableAccessAndDirtyFlags = TRUE;
292
293 //
294 // Bits 5:3 (1 less than the EPT page-walk length) must be 3, indicating an EPT page-walk length of 4;
295 // see Section 28.2.2
296 //
297 EPTP.PageWalkLength = 3;
298
299 //
300 // The physical page number of the page table we will be using
301 //
302 EPTP.PageFrameNumber = (SIZE_T)VirtualAddressToPhysicalAddress(&ModeBasedEptTable->PML4) / PAGE_SIZE;
303
304 //
305 // We will write the EPTP to the VMCS later
306 //
307 g_EptState->ModeBasedUserDisabledEptPointer.AsUInt = EPTP.AsUInt;
308
309 return TRUE;
310}
BOOLEAN ModeBasedExecHookDisableUserModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
Adjust (unset) user-mode execution bit of target page-table.
Definition ModeBasedExecHook.c:23
EPT_POINTER ModeBasedUserDisabledEptPointer
Definition Ept.h:124
PVMM_EPT_PAGE_TABLE ModeBasedUserDisabledEptPageTable
Definition Ept.h:122

◆ ExecTrapChangeToExecuteOnlyEptp()

VOID ExecTrapChangeToExecuteOnlyEptp ( VIRTUAL_MACHINE_STATE * VCpu)

change to execute-only EPTP

Parameters
VCpuThe virtual processor's state
Returns
VOID
692{
693 //
694 // Change EPTP
695 //
696 __vmx_vmwrite(VMCS_CTRL_EPT_POINTER, g_EptState->ExecuteOnlyEptPointer.AsUInt);
697
698 //
699 // It's not on normal EPTP
700 //
701 VCpu->NotNormalEptp = TRUE;
702}
EPT_POINTER ExecuteOnlyEptPointer
Definition Ept.h:126
BOOLEAN NotNormalEptp
Definition State.h:300

◆ ExecTrapChangeToKernelDisabledMbecEptp()

VOID ExecTrapChangeToKernelDisabledMbecEptp ( VIRTUAL_MACHINE_STATE * VCpu)

change to kernel-disabled MBEC EPTP

Parameters
VCpuThe virtual processor's state
Returns
VOID
732{
733 //
734 // Change EPTP
735 //
736 __vmx_vmwrite(VMCS_CTRL_EPT_POINTER, g_EptState->ModeBasedKernelDisabledEptPointer.AsUInt);
737
738 //
739 // It's not on normal EPTP
740 //
741 VCpu->NotNormalEptp = TRUE;
742}

◆ ExecTrapChangeToUserDisabledMbecEptp()

VOID ExecTrapChangeToUserDisabledMbecEptp ( VIRTUAL_MACHINE_STATE * VCpu)

change to user-disabled MBEC EPTP

Parameters
VCpuThe virtual processor's state
Returns
VOID
712{
713 //
714 // Change EPTP
715 //
716 __vmx_vmwrite(VMCS_CTRL_EPT_POINTER, g_EptState->ModeBasedUserDisabledEptPointer.AsUInt);
717
718 //
719 // It's not on normal EPTP
720 //
721 VCpu->NotNormalEptp = TRUE;
722}

◆ ExecTrapEnableExecuteOnlyPages()

BOOLEAN ExecTrapEnableExecuteOnlyPages ( PVMM_EPT_PAGE_TABLE EptTable)

Adjust execute-only bits bit of target page-table.

should be called from vmx non-root mode

Parameters
EptTable
Returns
BOOLEAN
385{
386 INT64 RemainingSize = 0;
387 UINT64 CurrentAddress = 0;
388
389 //
390 // *** allow execution of user-mode pages in execute only EPTP ***
391 //
392
393 //
394 // Set execute access for PML4s
395 //
396 for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
397 {
398 //
399 // We only set the top-level PML4 for intercepting user-mode execution
400 //
401 EptTable->PML4[i].UserModeExecute = TRUE;
402 }
403
404 //
405 // Set execute access for PML3s
406 //
407 for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
408 {
409 EptTable->PML3[i].UserModeExecute = TRUE;
410 }
411
412 //
413 // Set execute access for PML2s
414 //
415 for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
416 {
417 for (size_t j = 0; j < VMM_EPT_PML2E_COUNT; j++)
418 {
419 EptTable->PML2[i][j].UserModeExecute = TRUE;
420 }
421 }
422
423 //
424 // *** disallow read or write for certain memory only (not MMIO) EPTP pages ***
425 //
426 for (size_t i = 0; i < MAX_PHYSICAL_RAM_RANGE_COUNT; i++)
427 {
428 if (PhysicalRamRegions[i].RamPhysicalAddress != NULL64_ZERO)
429 {
430 RemainingSize = (INT64)PhysicalRamRegions[i].RamSize;
431 CurrentAddress = PhysicalRamRegions[i].RamPhysicalAddress;
432
433 while (RemainingSize > 0)
434 {
435 //
436 // Get the target entry in EPT table (every entry is 2-MB granularity)
437 //
438 PEPT_PML2_ENTRY EptEntry = EptGetPml2Entry(EptTable, CurrentAddress);
439 EptEntry->WriteAccess = FALSE;
440
441 //
442 // Move to the new address
443 //
444 CurrentAddress += SIZE_2_MB;
445 RemainingSize -= SIZE_2_MB;
446 }
447 }
448 }
449
450 return TRUE;
451}
signed __int64 INT64
Definition BasicTypes.h:45
#define NULL64_ZERO
Definition BasicTypes.h:52
PEPT_PML2_ENTRY EptGetPml2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress)
Get the PML2 entry for this physical address.
Definition Ept.c:431
#define SIZE_2_MB
Integer 2MB.
Definition Ept.h:31
#define MAX_PHYSICAL_RAM_RANGE_COUNT
Definition ModeBasedExecHook.h:18
MODE_BASED_RAM_REGIONS PhysicalRamRegions[MAX_PHYSICAL_RAM_RANGE_COUNT]
Definition ModeBasedExecHook.h:39
EPT_PDE_2MB * PEPT_PML2_ENTRY
Definition State.h:20
#define VMM_EPT_PML4E_COUNT
The number of 512GB PML4 entries in the page table.
Definition State.h:78
#define VMM_EPT_PML3E_COUNT
The number of 1GB PDPT entries in the page table per 512GB PML4 entry.
Definition State.h:84
#define VMM_EPT_PML2E_COUNT
Then number of 2MB Page Directory entries in the page table per 1GB PML3 entry.
Definition State.h:91
EPT_PML3_POINTER PML3[VMM_EPT_PML3E_COUNT]
Describes exactly 512 contiguous 1GB memory regions within a our singular 512GB PML4 region.
Definition State.h:116
EPT_PML2_ENTRY PML2[VMM_EPT_PML3E_COUNT][VMM_EPT_PML2E_COUNT]
For each 1GB PML3 entry, create 512 2MB entries to map identity. NOTE: We are using 2MB pages as the ...
Definition State.h:124
UINT64 RamPhysicalAddress
Definition ModeBasedExecHook.h:30

◆ ExecTrapHandleCr3Vmexit()

VOID ExecTrapHandleCr3Vmexit ( VIRTUAL_MACHINE_STATE * VCpu)

Handle MOV to CR3 vm-exits for hooking mode execution.

Parameters
VCpuThe virtual processor's state
Returns
VOID
848{
849 BOOLEAN Result;
850 UINT32 Index;
851
852 //
853 // Search the list of processes for the current process's user-execution
854 // trap state
855 //
858 &Index,
859 (UINT64)PsGetCurrentProcessId());
860
861 //
862 // Check whether the procerss is in the list of interceptions or not
863 //
864 if (Result)
865 {
866 //
867 // Enable MBEC to detect execution in user-mode
868 //
870 VCpu->MbecEnabled = TRUE;
871
872 //
873 // Trigger the event
874 //
876 }
877 else if (VCpu->MbecEnabled)
878 {
879 //
880 // In case, the process is changed, we've disable the MBEC
881 //
883 VCpu->MbecEnabled = FALSE;
884 }
885}
UCHAR BOOLEAN
Definition BasicTypes.h:39
unsigned int UINT32
Definition BasicTypes.h:48
BOOLEAN BinarySearchPerformSearchItem(UINT64 ArrayPtr[], UINT32 NumberOfItems, UINT32 *ResultIndex, UINT64 Key)
A utility function to perform the binary search.
Definition BinarySearch.c:46
VOID DispatchEventMode(VIRTUAL_MACHINE_STATE *VCpu, DEBUGGER_EVENT_MODE_TYPE TargetMode, BOOLEAN HandleState)
Handling debugger functions related to user-mode/kernel-mode execution trap events.
Definition Dispatch.c:312
VOID HvSetModeBasedExecutionEnableFlag(BOOLEAN Set)
Set Mode-based Execution Control (MBEC) Enable bit.
Definition Hv.c:677
@ DEBUGGER_EVENT_MODE_TYPE_KERNEL_MODE
Definition Events.h:207
BOOLEAN MbecEnabled
Definition State.h:301

◆ ExecTrapHandleEptViolationVmexit()

BOOLEAN ExecTrapHandleEptViolationVmexit ( VIRTUAL_MACHINE_STATE * VCpu,
VMX_EXIT_QUALIFICATION_EPT_VIOLATION * ViolationQualification )

Handle EPT Violations related to the MBEC hooks.

Parameters
VCpuThe virtual processor's state
ViolationQualification
Returns
BOOLEAN
781{
782 //
783 // Check if this mechanism is use or not
784 //
786 {
787 return FALSE;
788 }
789
790 if (!ViolationQualification->EptExecutableForUserMode && ViolationQualification->ExecuteAccess)
791 {
792 //
793 // For test purposes
794 //
795 // LogInfo("Reached to the user-mode of the process (0x%x) is executed address: %llx", PsGetCurrentProcessId(), VCpu->LastVmexitRip);
796
797 //
798 // Suppress the RIP increment
799 //
801
802 //
803 // Trigger the event
804 //
806
807 return TRUE;
808 }
809 else if (!ViolationQualification->EptExecutable && ViolationQualification->ExecuteAccess)
810 {
811 //
812 // For test purposes
813 //
814 // LogInfo("Reached to the kernel-mode of the process (0x%x) is executed address: %llx", PsGetCurrentProcessId(), VCpu->LastVmexitRip);
815
816 //
817 // Suppress the RIP increment
818 //
820
821 //
822 // Trigger the event
823 //
825 }
826 else
827 {
828 //
829 // Unexpected violation
830 //
831 return FALSE;
832 }
833
834 //
835 // It successfully handled by MBEC hooks
836 //
837 return TRUE;
838}
BOOLEAN g_ExecTrapInitialized
Showes whether the execution trap handler is allowed to trigger an event or not.
Definition GlobalVariables.h:149
VOID HvSuppressRipIncrement(VIRTUAL_MACHINE_STATE *VCpu)
Suppress the incrementation of RIP.
Definition Hv.c:324
@ DEBUGGER_EVENT_MODE_TYPE_USER_MODE
Definition Events.h:206

◆ ExecTrapHandleMoveToAdjustedTrapState()

VOID ExecTrapHandleMoveToAdjustedTrapState ( VIRTUAL_MACHINE_STATE * VCpu,
DEBUGGER_EVENT_MODE_TYPE TargetMode )

Restore the execution of the trap to adjusted trap state.

Parameters
VCpuThe virtual processor's state
IsUserModeWhether the execution event caused by a switch from kernel-to-user or otherwise user-to-kernel
Returns
VOID
754{
755 if (TargetMode == DEBUGGER_EVENT_MODE_TYPE_USER_MODE)
756 {
757 //
758 // Change EPT to kernel disabled
759 //
761 }
762 else if (TargetMode == DEBUGGER_EVENT_MODE_TYPE_KERNEL_MODE)
763 {
764 //
765 // Change EPT to user disabled
766 //
768 }
769}
VOID ExecTrapChangeToKernelDisabledMbecEptp(VIRTUAL_MACHINE_STATE *VCpu)
change to kernel-disabled MBEC EPTP
Definition ExecTrap.c:731
VOID ExecTrapChangeToUserDisabledMbecEptp(VIRTUAL_MACHINE_STATE *VCpu)
change to user-disabled MBEC EPTP
Definition ExecTrap.c:711

◆ ExecTrapInitialize()

BOOLEAN ExecTrapInitialize ( )

Initialize the reversing machine based on service request.

Returns
BOOLEAN
498{
499 //
500 // Check if the reversing machine is already initialized
501 //
503 {
504 //
505 // Already initialized
506 //
507 return FALSE;
508 }
509
510 //
511 // Check if MBEC supported by this processors
512 //
514 {
515 LogInfo("Your processor doesn't support Mode-Based Execution Controls (MBEC), which is a needed feature for this functionality :(\n"
516 "MBEC is available on processors starting from the 7th generation (Kaby Lake) and onwards");
517 return FALSE;
518 }
519
520 //
521 // Read the RAM regions
522 //
524
525 //
526 // Allocate MBEC EPT page-table (user-disabled)
527 //
529 {
530 //
531 // There was an error allocating MBEC page table for EPT tables
532 //
533 return FALSE;
534 }
535
536 //
537 // Allocate MBEC EPT page-table (kernel-disabled)
538 //
540 {
541 //
542 // Free the user-disabled page-table buffer
543 //
544 MmFreeContiguousMemory(g_EptState->ModeBasedUserDisabledEptPageTable);
546
547 //
548 // There was an error allocating MBEC page table for EPT tables
549 //
550 return FALSE;
551 }
552
553 //
554 // Call the function responsible for initializing Mode-based hooks
555 //
557 {
558 //
559 // Free the user-disabled page-table buffer
560 //
561 MmFreeContiguousMemory(g_EptState->ModeBasedUserDisabledEptPageTable);
563
564 //
565 // Free the kernel-disabled page-table buffer
566 //
567 MmFreeContiguousMemory(g_EptState->ModeBasedKernelDisabledEptPageTable);
569
570 //
571 // The initialization was not successful
572 //
573 return FALSE;
574 }
575
576 //
577 // Change EPT on all core's to a MBEC supported EPTP
578 // (No longer needed as the starting phase of the process uses EPT hooks)
579 //
581
582 //
583 // Indicate that the reversing machine is initialized
584 // It should be initialized here BEFORE broadcasting mov 2 cr3 exiting
585 // because an EPT violation might be thrown before we enabled it from
586 // here
587 //
589
590 //
591 // Enable Mode-based execution control by broadcasting MOV to CR3 exiting
592 //
594
595 return TRUE;
596}
VOID BroadcastChangeToMbecSupportedEptpOnAllProcessors()
routines for changing EPTP to an MBEC supported EPTP
Definition Broadcast.c:447
VOID BroadcastEnableMovToCr3ExitingOnAllProcessors()
routines for debugging threads (enable mov-to-cr3 exiting)
Definition Broadcast.c:436
VOID ExecTrapReadRamPhysicalRegions()
Read the RAM regions (physical address)
Definition ExecTrap.c:459
BOOLEAN ExecTrapAllocateUserDisabledMbecEptPageTable()
Initialize the needed structure for hooking user-mode execution.
Definition ExecTrap.c:255
BOOLEAN ExecTrapAllocateKernelDisabledMbecEptPageTable()
Initialize the needed structure for hooking kernel-mode execution.
Definition ExecTrap.c:319
COMPATIBILITY_CHECKS_STATUS g_CompatibilityCheck
Different attributes and compatibility checks of the current processor.
Definition GlobalVariables.h:26
#define LogInfo(format,...)
Define log variables.
Definition HyperDbgHyperLogIntrinsics.h:71
BOOLEAN ModeBasedExecHookInitialize()
Initialize the needed structure for hooking mode execution.
Definition ModeBasedExecHook.c:185
NULL()
Definition test-case-generator.py:530
BOOLEAN ModeBasedExecutionSupport
Definition CompatibilityChecks.h:28

◆ ExecTrapReadRamPhysicalRegions()

VOID ExecTrapReadRamPhysicalRegions ( )

Read the RAM regions (physical address)

Returns
VOID
460{
461 PHYSICAL_ADDRESS Address;
462 LONGLONG Size;
463 UINT32 Count = 0;
464 PPHYSICAL_MEMORY_RANGE PhysicalMemoryRanges = NULL;
465
466 //
467 // Read the RAM regions (BIOS) gives these details to Windows
468 //
469 PhysicalMemoryRanges = MmGetPhysicalMemoryRanges();
470
471 do
472 {
473 Address.QuadPart = PhysicalMemoryRanges[Count].BaseAddress.QuadPart;
474 Size = PhysicalMemoryRanges[Count].NumberOfBytes.QuadPart;
475
476 if (!Address.QuadPart && !Size)
477 {
478 break;
479 }
480
481 // LogInfo("RAM Range, from: %llx to %llx", Address.QuadPart, Address.QuadPart + Size);
482
484 PhysicalRamRegions[Count].RamSize = Size;
485
486 } while (++Count < MAX_PHYSICAL_RAM_RANGE_COUNT);
487
488 ExFreePool(PhysicalMemoryRanges);
489}
UINT64 Address
Definition HyperDbgScriptImports.h:67
UINT64 RamSize
Definition ModeBasedExecHook.h:31

◆ ExecTrapRemoveProcessFromWatchingList()

BOOLEAN ExecTrapRemoveProcessFromWatchingList ( UINT32 ProcessId)

Remove the target process from the watching list.

Parameters
ProcessId
Returns
BOOLEAN
910{
913 (UINT64)ProcessId);
914}
BOOLEAN InsertionSortDeleteItem(UINT64 ArrayPtr[], UINT32 *NumberOfItems, UINT32 Index)
Function to implement insertion sort.
Definition InsertionSort.c:66

◆ ExecTrapRestoreToNormalEptp()

VOID ExecTrapRestoreToNormalEptp ( VIRTUAL_MACHINE_STATE * VCpu)

restore to normal EPTP

Parameters
VCpuThe virtual processor's state
Returns
VOID
672{
673 //
674 // Change EPTP
675 //
676 __vmx_vmwrite(VMCS_CTRL_EPT_POINTER, VCpu->EptPointer.AsUInt);
677
678 //
679 // It's on normal EPTP
680 //
681 VCpu->NotNormalEptp = FALSE;
682}
EPT_POINTER EptPointer
Definition State.h:341

◆ ExecTrapTraverseThroughOsPageTables()

BOOLEAN ExecTrapTraverseThroughOsPageTables ( PVMM_EPT_PAGE_TABLE EptTable,
CR3_TYPE TargetCr3,
CR3_TYPE KernelCr3 )

This function gets virtual address and returns its PTE of the virtual address based on the specific cr3 but without switching to the target address.

the TargetCr3 should be kernel cr3 as we will use it to translate kernel addresses so the kernel functions to translate addresses should be mapped; thus, don't pass a KPTI meltdown user cr3 to this function

Parameters
VaVirtual Address
LevelPMLx
TargetCr3user/kernel cr3 of target process
KernelCr3kernel cr3 of target process
Returns
PVOID virtual address of PTE based on cr3
30{
31 CR3_TYPE Cr3;
32 UINT64 TempCr3;
33 PUINT64 Cr3Va;
34 PUINT64 PdptVa;
35 PUINT64 PdVa;
36 PUINT64 PtVa;
37 BOOLEAN IsLargePage = FALSE;
38 CR3_TYPE CurrentProcessCr3 = {0};
39
40 //
41 // Move to guest process as we're currently in system cr3
42 //
43 CurrentProcessCr3 = SwitchToProcessMemoryLayoutByCr3(KernelCr3);
44
45 Cr3.Flags = TargetCr3.Flags;
46
47 //
48 // Cr3 should be shifted 12 to the left because it's PFN
49 //
50 TempCr3 = Cr3.Fields.PageFrameNumber << 12;
51
52 PVOID EptPmlEntry4 = EptGetPml1OrPml2Entry(EptTable, Cr3.Fields.PageFrameNumber << 12, &IsLargePage);
53
54 if (EptPmlEntry4 != NULL)
55 {
56 if (IsLargePage)
57 {
58 ((PEPT_PML2_ENTRY)EptPmlEntry4)->ReadAccess = TRUE;
59 ((PEPT_PML2_ENTRY)EptPmlEntry4)->WriteAccess = TRUE;
60 }
61 else
62 {
63 ((PEPT_PML1_ENTRY)EptPmlEntry4)->ReadAccess = TRUE;
64 ((PEPT_PML1_ENTRY)EptPmlEntry4)->WriteAccess = TRUE;
65 }
66 }
67 else
68 {
69 LogInfo("null address");
70 }
71
72 //
73 // we need VA of Cr3, not PA
74 //
75 Cr3Va = (UINT64 *)PhysicalAddressToVirtualAddress(TempCr3);
76
77 //
78 // Check for invalid address
79 //
80 if (Cr3Va == NULL)
81 {
82 //
83 // Restore the original process
84 //
85 SwitchToPreviousProcess(CurrentProcessCr3);
86
87 return FALSE;
88 }
89
90 for (size_t i = 0; i < 512; i++)
91 {
92 // LogInfo("Address of Cr3Va: %llx", Cr3Va);
93
94 PPAGE_ENTRY Pml4e = (PAGE_ENTRY *)&Cr3Va[i];
95
96 if (Pml4e->Fields.Present)
97 {
98 // LogInfo("PML4[%d] = %llx", i, Pml4e->Fields.PageFrameNumber);
99
100 IsLargePage = FALSE;
101 EptPmlEntry4 = EptGetPml1OrPml2Entry(EptTable, Pml4e->Fields.PageFrameNumber << 12, &IsLargePage);
102
103 if (EptPmlEntry4 != NULL)
104 {
105 if (IsLargePage)
106 {
107 ((PEPT_PML2_ENTRY)EptPmlEntry4)->ReadAccess = TRUE;
108 ((PEPT_PML2_ENTRY)EptPmlEntry4)->WriteAccess = TRUE;
109 }
110 else
111 {
112 ((PEPT_PML1_ENTRY)EptPmlEntry4)->ReadAccess = TRUE;
113 ((PEPT_PML1_ENTRY)EptPmlEntry4)->WriteAccess = TRUE;
114 }
115 }
116 else
117 {
118 LogInfo("null address");
119 }
120
122
123 //
124 // Check for invalid address
125 //
126 if (PdptVa != NULL)
127 {
128 for (size_t j = 0; j < 512; j++)
129 {
130 // LogInfo("Address of PdptVa: %llx", PdptVa);
131
132 PPAGE_ENTRY Pdpte = (PAGE_ENTRY *)&PdptVa[j];
133
134 if (Pdpte->Fields.Present)
135 {
136 // LogInfo("PML3[%d] = %llx", j, Pdpte->Fields.PageFrameNumber);
137
138 IsLargePage = FALSE;
139 PVOID EptPmlEntry3 = EptGetPml1OrPml2Entry(EptTable, Pdpte->Fields.PageFrameNumber << 12, &IsLargePage);
140
141 if (EptPmlEntry3 != NULL)
142 {
143 if (IsLargePage)
144 {
145 ((PEPT_PML2_ENTRY)EptPmlEntry3)->ReadAccess = TRUE;
146 ((PEPT_PML2_ENTRY)EptPmlEntry3)->WriteAccess = TRUE;
147 }
148 else
149 {
150 ((PEPT_PML1_ENTRY)EptPmlEntry3)->ReadAccess = TRUE;
151 ((PEPT_PML1_ENTRY)EptPmlEntry3)->WriteAccess = TRUE;
152 }
153 }
154 else
155 {
156 LogInfo("null address");
157 }
158
159 if (Pdpte->Fields.LargePage)
160 {
161 continue;
162 }
163
165
166 //
167 // Check for invalid address
168 //
169 if (PdVa != NULL)
170 {
171 for (size_t k = 0; k < 512; k++)
172 {
173 // LogInfo("Address of PdVa: %llx", PdVa);
174
175 if (PdVa == (PUINT64)0xfffffffffffffe00)
176 {
177 continue;
178 }
179
180 PPAGE_ENTRY Pde = (PAGE_ENTRY *)&PdVa[k];
181
182 if (Pde->Fields.Present)
183 {
184 // LogInfo("PML2[%d] = %llx", k, Pde->Fields.PageFrameNumber);
185
186 IsLargePage = FALSE;
187 PVOID EptPmlEntry2 = EptGetPml1OrPml2Entry(EptTable, Pde->Fields.PageFrameNumber << 12, &IsLargePage);
188
189 if (EptPmlEntry2 != NULL)
190 {
191 if (IsLargePage)
192 {
193 ((PEPT_PML2_ENTRY)EptPmlEntry2)->ReadAccess = TRUE;
194 ((PEPT_PML2_ENTRY)EptPmlEntry2)->WriteAccess = TRUE;
195 }
196 else
197 {
198 ((PEPT_PML1_ENTRY)EptPmlEntry2)->ReadAccess = TRUE;
199 ((PEPT_PML1_ENTRY)EptPmlEntry2)->WriteAccess = TRUE;
200 }
201 }
202 else
203 {
204 LogInfo("null address");
205 }
206
207 if (Pde->Fields.LargePage)
208 {
209 continue;
210 }
211
213
214 //
215 // Check for invalid address
216 //
217 if (PtVa != NULL)
218 {
219 for (size_t l = 0; l < 512; l++)
220 {
221 // LogInfo("Address of PtVa: %llx", PtVa);
222
223 // PPAGE_ENTRY Pt = &PtVa[l];
224
225 /* if (Pt->Fields.Present)
226 {
227 // LogInfo("PML1[%d] = %llx", l, Pt->Fields.PageFrameNumber);
228 }*/
229 }
230 }
231 }
232 }
233 }
234 }
235 }
236 }
237 }
238 }
239
240 //
241 // Restore the original process
242 //
243 SwitchToPreviousProcess(CurrentProcessCr3);
244
245 return TRUE;
246}
unsigned __int64 * PUINT64
Definition BasicTypes.h:21
_Use_decl_annotations_ UINT64 PhysicalAddressToVirtualAddress(UINT64 PhysicalAddress)
Converts Physical Address to Virtual Address.
Definition Conversion.c:22
PVOID EptGetPml1OrPml2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress, BOOLEAN *IsLargePage)
Get the PML1 entry for this physical address if the large page is available then large page of Pml2 i...
Definition Ept.c:368
_Use_decl_annotations_ VOID SwitchToPreviousProcess(CR3_TYPE PreviousProcess)
Switch to previous process's cr3.
Definition SwitchLayout.c:125
_Use_decl_annotations_ CR3_TYPE SwitchToProcessMemoryLayoutByCr3(CR3_TYPE TargetCr3)
Switch to another process's cr3.
Definition SwitchLayout.c:99
EPT_PTE * PEPT_PML1_ENTRY
Definition State.h:22
CR3 Structure.
Definition BasicTypes.h:130
UINT64 Flags
Definition BasicTypes.h:133
struct _CR3_TYPE::@56::@58 Fields
UINT64 PageFrameNumber
Definition BasicTypes.h:138
Page Entries.
Definition MemoryMapper.h:61
UINT64 LargePage
Definition MemoryMapper.h:86
struct _PAGE_ENTRY::@2::@4 Fields
UINT64 Present
Definition MemoryMapper.h:79
UINT64 PageFrameNumber
Definition MemoryMapper.h:89

◆ ExecTrapUninitialize()

VOID ExecTrapUninitialize ( )

Uinitialize the needed structure for the reversing machine.

should be called from vmx non-root mode

Returns
VOID
606{
607 //
608 // Check if it's already initialized
609 //
611 {
612 return;
613 }
614
615 //
616 // Indicate that the uninitialization phase started
617 //
619
620 //
621 // Disable MOV to CR3 exiting
622 //
624
625 //
626 // Restore to normal EPTP
627 //
629
630 //
631 // Uninitialize the mode-based execution controls
632 //
634
635 //
636 // Indicate that the execution traps are disabled
637 //
639
640 //
641 // Indicate that the uninitialization phase finished
642 //
644
645 //
646 // Free Identity Page Table for MBEC hooks (user-disabled)
647 //
649 {
650 MmFreeContiguousMemory(g_EptState->ModeBasedUserDisabledEptPageTable);
652 }
653
654 //
655 // Free Identity Page Table for MBEC hooks (kernel-disabled)
656 //
658 {
659 MmFreeContiguousMemory(g_EptState->ModeBasedKernelDisabledEptPageTable);
661 }
662}
VOID BroadcastRestoreToNormalEptpOnAllProcessors()
routines for restoring EPTP to normal EPTP
Definition Broadcast.c:458
VOID BroadcastDisableMovToCr3ExitingOnAllProcessors()
routines for debugging threads (disable mov-to-cr3 exiting)
Definition Broadcast.c:491
BOOLEAN g_ExecTrapUnInitializationStarted
Showes whether the uninitialization of the exec trap is started or not.
Definition GlobalVariables.h:156
VOID ModeBasedExecHookUninitialize()
Uinitialize the needed structure for hooking mode execution.
Definition ModeBasedExecHook.c:247