HyperDbg Debugger
Loading...
Searching...
No Matches
Hooks.h File Reference

Hook headers. More...

Go to the source code of this file.

Classes

struct  _SSDTStruct
 SSDT structure. More...
 
struct  _HIDDEN_HOOKS_DETOUR_DETAILS
 Details of detours style EPT hooks. More...
 
struct  _SYSTEM_MODULE_ENTRY
 Module entry. More...
 
struct  _SYSTEM_MODULE_INFORMATION
 System Information for modules. More...
 

Macros

#define IS_SYSRET_INSTRUCTION(Code)
 As we have just on sysret in all the Windows, we use the following variable to hold its address this way, we're not force to check for the instruction so we remove the memory access to check for sysret in this case.
 
#define IS_SYSCALL_INSTRUCTION(Code)
 
#define IMAGE_DOS_SIGNATURE   0x5A4D
 Special signatures.
 
#define IMAGE_OS2_SIGNATURE   0x454E
 
#define IMAGE_OS2_SIGNATURE_LE   0x454C
 
#define IMAGE_VXD_SIGNATURE   0x454C
 
#define IMAGE_NT_SIGNATURE   0x00004550
 
#define MAX_EXEC_TRAMPOLINE_SIZE   100
 Maximum number of supported execution trampoline.
 

Typedefs

typedef struct _SSDTStruct SSDTStruct
 SSDT structure.
 
typedef struct _SSDTStructPSSDTStruct
 
typedef struct _HIDDEN_HOOKS_DETOUR_DETAILS HIDDEN_HOOKS_DETOUR_DETAILS
 Details of detours style EPT hooks.
 
typedef struct _HIDDEN_HOOKS_DETOUR_DETAILSPHIDDEN_HOOKS_DETOUR_DETAILS
 
typedef struct _SYSTEM_MODULE_ENTRY SYSTEM_MODULE_ENTRY
 Module entry.
 
typedef struct _SYSTEM_MODULE_ENTRYPSYSTEM_MODULE_ENTRY
 
typedef struct _SYSTEM_MODULE_INFORMATION SYSTEM_MODULE_INFORMATION
 System Information for modules.
 
typedef struct _SYSTEM_MODULE_INFORMATIONPSYSTEM_MODULE_INFORMATION
 
typedef enum _SYSTEM_INFORMATION_CLASS SYSTEM_INFORMATION_CLASS
 System information class.
 
typedef enum _SYSTEM_INFORMATION_CLASSPSYSTEM_INFORMATION_CLASS
 
typedef NTSTATUS(NTAPI * ZWQUERYSYSTEMINFORMATION) (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL)
 

Enumerations

enum  _SYSTEM_INFORMATION_CLASS { SystemModuleInformation = 11 , SystemKernelDebuggerInformation = 35 }
 System information class. More...
 

Functions

VOID SyscallHookTest ()
 Make examples for testing hidden hooks.
 
VOID SyscallHookConfigureEFER (VIRTUAL_MACHINE_STATE *VCpu, BOOLEAN EnableEFERSyscallHook)
 This function enables or disables EFER syscall hoo.
 
BOOLEAN SyscallHookHandleUD (_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
 
BOOLEAN SyscallHookEmulateSYSRET (_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
 
BOOLEAN SyscallHookEmulateSYSCALL (_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
 
BOOLEAN EptHookPerformPageHook (VIRTUAL_MACHINE_STATE *VCpu, PVOID TargetAddress, CR3_TYPE ProcessCr3)
 Hook in VMX Root Mode with hidden breakpoints (A pre-allocated buffer should be available)
 
BOOLEAN EptHookPerformPageHookMonitorAndInlineHook (VIRTUAL_MACHINE_STATE *VCpu, PVOID HookingDetails, CR3_TYPE ProcessCr3, UINT32 PageHookMask)
 Hook in VMX Root Mode with hidden detours and monitor (A pre-allocated buffer should be available)
 
BOOLEAN EptHook (PVOID TargetAddress, UINT32 ProcessId)
 Hook in VMX non-root Mode (hidden breakpoint)
 
BOOLEAN EptHookFromVmxRoot (PVOID TargetAddress)
 This function invokes a direct VMCALL to setup the hook.
 
BOOLEAN EptHookInlineHook (VIRTUAL_MACHINE_STATE *VCpu, PVOID TargetAddress, PVOID HookFunction, UINT32 ProcessId)
 Hook in VMX non-root mode (hidden detours)
 
BOOLEAN EptHookMonitorHook (VIRTUAL_MACHINE_STATE *VCpu, EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *HookingDetails, UINT32 ProcessId)
 This function applies monitor hooks to the target EPT table.
 
BOOLEAN EptHookInlineHookFromVmxRoot (VIRTUAL_MACHINE_STATE *VCpu, PVOID TargetAddress, PVOID HookFunction)
 Hook in VMX root-mode (hidden detours)
 
BOOLEAN EptHookMonitorFromVmxRoot (VIRTUAL_MACHINE_STATE *VCpu, EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *MemoryAddressDetails)
 This function applies EPT monitor hooks to the target EPT table.
 
BOOLEAN EptHookHandleHookedPage (VIRTUAL_MACHINE_STATE *VCpu, EPT_HOOKED_PAGE_DETAIL *HookedEntryDetails, VMX_EXIT_QUALIFICATION_EPT_VIOLATION ViolationQualification, SIZE_T PhysicalAddress, EPT_HOOKS_CONTEXT *LastContext, BOOLEAN *IgnoreReadOrWriteOrExec, BOOLEAN *IsExecViolation)
 Handle hooked pages in Vmx-root mode.
 
BOOLEAN EptHookRestoreSingleHookToOriginalEntry (VIRTUAL_MACHINE_STATE *VCpu, SIZE_T PhysicalAddress, UINT64 OriginalEntry)
 Remove a special hook from the hooked pages lists.
 
VOID EptHookRestoreAllHooksToOriginalEntry (VIRTUAL_MACHINE_STATE *VCpu)
 Remove all hooks from the hooked pages lists (Should be called in vmx-root)
 
VOID EptHookUnHookAll ()
 Remove all hooks from the hooked pages lists.
 
BOOLEAN EptHookUnHookAllByHookingTag (UINT64 HookingTag)
 Remove all hooks from the hooked pages by the given hooking tag.
 
BOOLEAN EptHookUnHookSingleAddress (UINT64 VirtualAddress, UINT64 PhysAddress, UINT32 ProcessId)
 Remove single hook from the hooked pages list and invalidate TLB From VMX non-root mode.
 
BOOLEAN EptHookUnHookSingleHookByHookingTagFromVmxRoot (UINT64 HookingTag, EPT_SINGLE_HOOK_UNHOOKING_DETAILS *TargetUnhookingDetails)
 Remove single hook from the hooked pages by the given hooking tag.
 
BOOLEAN EptHookUnHookSingleAddressFromVmxRoot (UINT64 VirtualAddress, UINT64 PhysAddress, EPT_SINGLE_HOOK_UNHOOKING_DETAILS *TargetUnhookingDetails)
 Remove single hook from the hooked pages list and invalidate TLB From VMX root-mode.
 
UINT32 EptHookGetCountOfEpthooks (BOOLEAN IsEptHook2)
 get the length of active EPT hooks (!epthook and !epthook2)
 
BOOLEAN EptHookRemoveEntryAndFreePoolFromEptHook2sDetourList (UINT64 Address)
 Remove an entry from g_EptHook2sDetourListHead.
 
PVOID EptHook2GeneralDetourEventHandler (PGUEST_REGS Regs, PVOID CalledFrom)
 routines to generally handle breakpoint hit for detour
 
VOID EptHookAllocateExtraHookingPagesForMemoryMonitorsAndExecEptHooks (UINT32 Count)
 Allocate (reserve) extra pages for storing details of page hooks for memory monitor and regular hidden breakpoit exec EPT hooks.
 
VOID EptHookReservePreallocatedPoolsForEptHooks (UINT32 Count)
 Allocate pre-allocated pools for EPT hooks.
 
BOOLEAN EptHookModifyInstructionFetchState (VIRTUAL_MACHINE_STATE *VCpu, PVOID PhysicalAddress, BOOLEAN IsUnset)
 Change PML EPT state for execution (execute) @detail should be called from VMX-root.
 
BOOLEAN EptHookModifyPageReadState (VIRTUAL_MACHINE_STATE *VCpu, PVOID PhysicalAddress, BOOLEAN IsUnset)
 Change PML EPT state for read @detail should be called from VMX-root.
 
BOOLEAN EptHookModifyPageWriteState (VIRTUAL_MACHINE_STATE *VCpu, PVOID PhysicalAddress, BOOLEAN IsUnset)
 Change PML EPT state for write @detail should be called from VMX-root.
 
VOID EptHookHandleMonitorTrapFlag (VIRTUAL_MACHINE_STATE *VCpu)
 Handle vm-exits for Monitor Trap Flag to restore previous state.
 

Variables

PHANDLE FileHandle
 
PHANDLE ACCESS_MASK DesiredAccess
 
PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES ObjectAttributes
 
PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK IoStatusBlock
 
PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK PLARGE_INTEGER AllocationSize
 
PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK PLARGE_INTEGER ULONG FileAttributes
 
PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK PLARGE_INTEGER ULONG ULONG ShareAccess
 
PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK PLARGE_INTEGER ULONG ULONG ULONG CreateDisposition
 
PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK PLARGE_INTEGER ULONG ULONG ULONG ULONG CreateOptions
 
PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK PLARGE_INTEGER ULONG ULONG ULONG ULONG PVOID EaBuffer
 
PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK PLARGE_INTEGER ULONG ULONG ULONG ULONG PVOID ULONG EaLength
 
POOL_TYPE PoolType
 
POOL_TYPE SIZE_T NumberOfBytes
 
POOL_TYPE SIZE_T ULONG Tag
 

Detailed Description

Hook headers.

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.1
Date
2020-04-11

Macro Definition Documentation

◆ IMAGE_DOS_SIGNATURE

#define IMAGE_DOS_SIGNATURE   0x5A4D

Special signatures.

◆ IMAGE_NT_SIGNATURE

#define IMAGE_NT_SIGNATURE   0x00004550

◆ IMAGE_OS2_SIGNATURE

#define IMAGE_OS2_SIGNATURE   0x454E

◆ IMAGE_OS2_SIGNATURE_LE

#define IMAGE_OS2_SIGNATURE_LE   0x454C

◆ IMAGE_VXD_SIGNATURE

#define IMAGE_VXD_SIGNATURE   0x454C

◆ IS_SYSCALL_INSTRUCTION

#define IS_SYSCALL_INSTRUCTION ( Code)
Value:
(*((PUINT8)(Code) + 0) == 0x0F && \
*((PUINT8)(Code) + 1) == 0x05)
unsigned char * PUINT8
Definition BasicTypes.h:46
35#define IS_SYSCALL_INSTRUCTION(Code) \
36 (*((PUINT8)(Code) + 0) == 0x0F && \
37 *((PUINT8)(Code) + 1) == 0x05)

◆ IS_SYSRET_INSTRUCTION

#define IS_SYSRET_INSTRUCTION ( Code)
Value:
(*((PUINT8)(Code) + 0) == 0x48 && \
*((PUINT8)(Code) + 1) == 0x0F && \
*((PUINT8)(Code) + 2) == 0x07)

As we have just on sysret in all the Windows, we use the following variable to hold its address this way, we're not force to check for the instruction so we remove the memory access to check for sysret in this case.

Check for instruction sysret and syscall

31#define IS_SYSRET_INSTRUCTION(Code) \
32 (*((PUINT8)(Code) + 0) == 0x48 && \
33 *((PUINT8)(Code) + 1) == 0x0F && \
34 *((PUINT8)(Code) + 2) == 0x07)

◆ MAX_EXEC_TRAMPOLINE_SIZE

#define MAX_EXEC_TRAMPOLINE_SIZE   100

Maximum number of supported execution trampoline.

Typedef Documentation

◆ HIDDEN_HOOKS_DETOUR_DETAILS

Details of detours style EPT hooks.

◆ PHIDDEN_HOOKS_DETOUR_DETAILS

◆ PSSDTStruct

typedef struct _SSDTStruct * PSSDTStruct

◆ PSYSTEM_INFORMATION_CLASS

◆ PSYSTEM_MODULE_ENTRY

◆ PSYSTEM_MODULE_INFORMATION

◆ SSDTStruct

typedef struct _SSDTStruct SSDTStruct

SSDT structure.

◆ SYSTEM_INFORMATION_CLASS

System information class.

◆ SYSTEM_MODULE_ENTRY

Module entry.

◆ SYSTEM_MODULE_INFORMATION

System Information for modules.

◆ ZWQUERYSYSTEMINFORMATION

typedef NTSTATUS(NTAPI * ZWQUERYSYSTEMINFORMATION) (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL)

Enumeration Type Documentation

◆ _SYSTEM_INFORMATION_CLASS

System information class.

Enumerator
SystemModuleInformation 
SystemKernelDebuggerInformation 
115{
@ SystemKernelDebuggerInformation
Definition Hooks.h:117
@ SystemModuleInformation
Definition Hooks.h:116
enum _SYSTEM_INFORMATION_CLASS SYSTEM_INFORMATION_CLASS
System information class.

Function Documentation

◆ EptHook()

BOOLEAN EptHook ( PVOID TargetAddress,
UINT32 ProcessId )

Hook in VMX non-root Mode (hidden breakpoint)

Parameters
TargetAddress
ProcessId
Returns
BOOLEAN

Hook in VMX non-root Mode (hidden breakpoint)

this command uses hidden breakpoints (0xcc) to hook, THIS FUNCTION SHOULD BE CALLED WHEN THE VMLAUNCH ALREADY EXECUTED, it is because, broadcasting to enable exception bitmap for breakpoint is not clear here, if we want to broadcast to enable exception bitmaps on all cores when vmlaunch is not executed then that's ok but a user might call this function when we didn't configure the vmcs, it's a problem! we can solve it by giving a hint to vmcs configure function to make it ok for future configuration but that sounds stupid, I think it's better to not support this feature. Btw, debugger won't use this function in the above mentioned method, so we won't have any problem with this This function should be called from VMX non-root mode

Parameters
TargetAddressThe address of function or memory address to be hooked
ProcessIdThe process id to translate based on that process's cr3
Returns
BOOLEAN Returns true if the hook was successful or false if there was an error
606{
607 //
608 // Should be called from vmx non-root
609 //
611 {
612 return FALSE;
613 }
614
615 return EptHookPerformHook(TargetAddress, ProcessId, FALSE);
616}
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
BOOLEAN EptHookPerformHook(PVOID TargetAddress, UINT32 ProcessId, BOOLEAN ApplyDirectlyFromVmxRoot)
This function invokes a VMCALL to set the hook and broadcast the exiting for the breakpoints on excep...
Definition EptHook.c:533
BOOLEAN VmxGetCurrentExecutionMode()
Check current execution mode (vmx-root and non-root)
Definition Vmx.c:222

◆ EptHook2GeneralDetourEventHandler()

PVOID EptHook2GeneralDetourEventHandler ( PGUEST_REGS Regs,
PVOID CalledFrom )

routines to generally handle breakpoint hit for detour

Parameters
Regs
CalledFrom
Returns
PVOID
2484{
2485 PLIST_ENTRY TempList = 0;
2486 EPT_HOOKS_CONTEXT TempContext = {0};
2487
2488 //
2489 // The RSP register is the at the RCX and we just added (reverse by stack) to it's
2490 // values by the size of the GUEST_REGS
2491 //
2492 Regs->rsp = (UINT64)Regs - sizeof(GUEST_REGS);
2493
2494 //
2495 // test
2496 //
2497
2498 //
2499 // LogInfo("Hidden Hooked function Called with : rcx = 0x%llx , rdx = 0x%llx , r8 = 0x%llx , r9 = 0x%llx",
2500 // Regs->rcx,
2501 // Regs->rdx,
2502 // Regs->r8,
2503 // Regs->r9);
2504 //
2505
2506 //
2507 // Create temporary context
2508 //
2509 TempContext.VirtualAddress = (UINT64)CalledFrom;
2510 TempContext.PhysicalAddress = VirtualAddressToPhysicalAddress(CalledFrom);
2511
2512 //
2513 // Create a temporary VCpu
2514 //
2515 VIRTUAL_MACHINE_STATE * VCpu = &g_GuestState[KeGetCurrentProcessorNumberEx(NULL)];
2516
2517 //
2518 // Set the register for the temporary VCpu
2519 //
2520 VCpu->Regs = Regs;
2521
2522 //
2523 // As the context to event trigger, we send the address of function
2524 // which is current hidden hook is triggered for it
2525 //
2526 DispatchEventHiddenHookExecDetours(VCpu, &TempContext);
2527
2528 //
2529 // Iterate through the list of hooked pages details to find
2530 // and return where want to jump after this functions
2531 //
2532 TempList = &g_EptHook2sDetourListHead;
2533
2534 while (&g_EptHook2sDetourListHead != TempList->Flink)
2535 {
2536 TempList = TempList->Flink;
2537 PHIDDEN_HOOKS_DETOUR_DETAILS CurrentHookedDetails = CONTAINING_RECORD(TempList, HIDDEN_HOOKS_DETOUR_DETAILS, OtherHooksList);
2538
2539 if (CurrentHookedDetails->HookedFunctionAddress == CalledFrom)
2540 {
2541 return CurrentHookedDetails->ReturnAddress;
2542 }
2543 }
2544
2545 //
2546 // If we reach here, means that we didn't find the return address
2547 // that's an error, generally we can't do anything but as the user
2548 // might already cleaned the hook and the structures are removed
2549 // so we just return the original caller address and continue the
2550 // guest normally
2551 //
2552 return CalledFrom;
2553}
unsigned __int64 UINT64
Definition BasicTypes.h:21
_Use_decl_annotations_ UINT64 VirtualAddressToPhysicalAddress(_In_ PVOID VirtualAddress)
Converts Virtual Address to Physical Address.
Definition Conversion.c:154
VOID DispatchEventHiddenHookExecDetours(VIRTUAL_MACHINE_STATE *VCpu, PVOID Context)
Handling debugger functions related to hidden hook exec detours events.
Definition Dispatch.c:984
VIRTUAL_MACHINE_STATE * g_GuestState
Save the state and variables related to virtualization on each to logical core.
Definition GlobalVariables.h:38
LIST_ENTRY g_EptHook2sDetourListHead
List header of hidden hooks detour.
Definition GlobalVariables.h:62
Temporary $context used in some EPT hook commands.
Definition DataTypes.h:320
UINT64 VirtualAddress
Definition DataTypes.h:323
UINT64 PhysicalAddress
Definition DataTypes.h:322
Details of detours style EPT hooks.
Definition Hooks.h:74
PVOID HookedFunctionAddress
Definition Hooks.h:76
PVOID ReturnAddress
Definition Hooks.h:77
The status of each core after and before VMX.
Definition State.h:290
GUEST_REGS * Regs
Definition State.h:305
Definition BasicTypes.h:70
UINT64 rsp
Definition BasicTypes.h:79

◆ EptHookAllocateExtraHookingPagesForMemoryMonitorsAndExecEptHooks()

VOID EptHookAllocateExtraHookingPagesForMemoryMonitorsAndExecEptHooks ( UINT32 Count)

Allocate (reserve) extra pages for storing details of page hooks for memory monitor and regular hidden breakpoit exec EPT hooks.

Parameters
Count
Returns
VOID
111{
112 ULONG ProcessorsCount;
113
114 //
115 // Get number of processors
116 //
117 ProcessorsCount = KeQueryActiveProcessorCount(0);
118
119 //
120 // Request pages to be allocated for converting 2MB to 4KB pages
121 // Each core needs its own splitting page-tables
122 //
124 Count * ProcessorsCount,
126
127 //
128 // Request pages to be allocated for paged hook details
129 //
131 Count,
133}
unsigned long ULONG
Definition BasicTypes.h:37
@ SPLIT_2MB_PAGING_TO_4KB_PAGE
Definition DataTypes.h:43
@ TRACKING_HOOKED_PAGES
Definition DataTypes.h:41
BOOLEAN PoolManagerRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention)
Request to allocate new buffers.
Definition PoolManager.c:415
Structure to save the state of each hooked pages.
Definition State.h:163
Split 2MB granularity to 4 KB granularity.
Definition Ept.h:135

◆ EptHookFromVmxRoot()

BOOLEAN EptHookFromVmxRoot ( PVOID TargetAddress)

This function invokes a direct VMCALL to setup the hook.

Parameters
TargetAddress
Returns
BOOLEAN

the caller of this function should make sure to 1) broadcast to all cores to intercept breakpoints (#BPs) and after calling this function 2) the caller should broadcast to all cores to invalidate their EPTPs This function should be called from VMX root-mode

Parameters
TargetAddressThe address of function or memory address to be hooked
Returns
BOOLEAN Returns true if the hook was successful or false if there was an error
632{
633 //
634 // Should be called from VMX root-mode
635 //
637 {
638 return FALSE;
639 }
640
641 return EptHookPerformHook(TargetAddress, NULL_ZERO, TRUE);
642}
#define NULL_ZERO
Definition BasicTypes.h:51

◆ EptHookGetCountOfEpthooks()

UINT32 EptHookGetCountOfEpthooks ( BOOLEAN IsEptHook2)

get the length of active EPT hooks (!epthook and !epthook2)

Parameters

return UINT32

Parameters
IsEptHook2Whether the length should be for !epthook or !epthook2
Returns
UINT32 Count of remained breakpoints
1866{
1867 UINT32 Count = 0;
1868
1870 {
1871 if (IsEptHook2)
1872 {
1873 if (HookedEntry->IsHiddenBreakpoint == FALSE)
1874 {
1875 Count++;
1876 }
1877 }
1878 else
1879 {
1880 if (HookedEntry->IsHiddenBreakpoint == TRUE)
1881 {
1882 Count++;
1883 }
1884 }
1885 }
1886
1887 return Count;
1888}
unsigned int UINT32
Definition BasicTypes.h:48
EPT_STATE * g_EptState
Save the state and variables related to EPT.
Definition GlobalVariables.h:50
#define LIST_FOR_EACH_LINK(_head, _struct_type, _member, _var)
Definition MetaMacros.h:34
LIST_ENTRY HookedPagesList
Definition Ept.h:118

◆ EptHookHandleHookedPage()

BOOLEAN EptHookHandleHookedPage ( VIRTUAL_MACHINE_STATE * VCpu,
EPT_HOOKED_PAGE_DETAIL * HookedEntryDetails,
VMX_EXIT_QUALIFICATION_EPT_VIOLATION ViolationQualification,
SIZE_T PhysicalAddress,
EPT_HOOKS_CONTEXT * LastContext,
BOOLEAN * IgnoreReadOrWriteOrExec,
BOOLEAN * IsExecViolation )

Handle hooked pages in Vmx-root mode.

Parameters
VCpu
HookedEntryDetails
ViolationQualification
PhysicalAddress
LastContext
IgnoreReadOrWriteOrExec
IsExecViolation
Returns
BOOLEAN

Handle hooked pages in Vmx-root mode.

Parameters
VCpuThe virtual processor's state
HookedEntryDetailsThe entry that describes the hooked page
ViolationQualificationThe exit qualification of vm-exit
PhysicalAddressThe physical address that cause this vm-exit
LastContextThe last (current) context of the execution
IgnoreReadOrWriteOrExecWhether to ignore the event effects or not
IsExecViolationWhether it's execution violation or not executing the post triggering of the event or not
Returns
BOOLEAN Returns TRUE if the function was hook was handled or returns false if there was an unexpected ept violation
1693{
1694 UINT64 ExactAccessedVirtualAddress;
1695 UINT64 AlignedVirtualAddress;
1696 UINT64 AlignedPhysicalAddress;
1697 BOOLEAN IsTriggeringPostEventAllowed = FALSE;
1698
1699 //
1700 // Get alignment
1701 //
1702 AlignedVirtualAddress = (UINT64)PAGE_ALIGN(HookedEntryDetails->VirtualAddress);
1703 AlignedPhysicalAddress = (UINT64)PAGE_ALIGN(PhysicalAddress);
1704
1705 //
1706 // Let's read the exact address that was accessed
1707 //
1708 ExactAccessedVirtualAddress = AlignedVirtualAddress + PhysicalAddress - AlignedPhysicalAddress;
1709
1710 //
1711 // Set the last context
1712 //
1713 LastContext->HookingTag = HookedEntryDetails->HookingTag;
1714 LastContext->PhysicalAddress = PhysicalAddress;
1715 LastContext->VirtualAddress = ExactAccessedVirtualAddress;
1716
1717 if (!ViolationQualification.EptReadable && ViolationQualification.ReadAccess)
1718 {
1719 //
1720 // LogInfo("Guest RIP : 0x%llx tries to read the page at : 0x%llx", GuestRip, ExactAccessedAddress);
1721 //
1722
1723 //
1724 // Set last violation
1725 //
1726 HookedEntryDetails->LastViolation = EPT_HOOKED_LAST_VIOLATION_READ;
1727
1728 //
1729 // Trigger the event related to Monitor Read and Monitor Read & Write and
1730 // Monitor Read & Execute and Monitor Read & Write & Execute
1731 //
1732 *IgnoreReadOrWriteOrExec = DispatchEventHiddenHookPageReadWriteExecuteReadPreEvent(VCpu, LastContext, &IsTriggeringPostEventAllowed);
1733
1734 //
1735 // It's not an execution violation
1736 //
1737 *IsExecViolation = FALSE;
1738 }
1739 else if (!ViolationQualification.EptWriteable && ViolationQualification.WriteAccess)
1740 {
1741 //
1742 // LogInfo("Guest RIP : 0x%llx tries to write on the page at : 0x%llx", GuestRip, ExactAccessedAddress);
1743 //
1744
1745 //
1746 // Set last violation
1747 //
1748 HookedEntryDetails->LastViolation = EPT_HOOKED_LAST_VIOLATION_WRITE;
1749
1750 //
1751 // Trigger the event related to Monitor Write and Monitor Read & Write and
1752 // Monitor Write & Execute and Monitor Read & Write & Execute
1753 //
1754 *IgnoreReadOrWriteOrExec = DispatchEventHiddenHookPageReadWriteExecuteWritePreEvent(VCpu, LastContext, &IsTriggeringPostEventAllowed);
1755
1756 //
1757 // It's not an execution violation
1758 //
1759 *IsExecViolation = FALSE;
1760 }
1761 else if (!ViolationQualification.EptExecutable && ViolationQualification.ExecuteAccess)
1762 {
1763 //
1764 // LogInfo("Guest RIP : 0x%llx tries to execute the page at : 0x%llx", GuestRip, ExactAccessedAddress);
1765 //
1766
1767 //
1768 // Set last violation
1769 //
1770 HookedEntryDetails->LastViolation = EPT_HOOKED_LAST_VIOLATION_EXEC;
1771
1772 //
1773 // Trigger the event related to Monitor Execute and Monitor Read & Execute and
1774 // Monitor Write & Execute and Monitor Read & Write & Execute
1775 //
1776 *IgnoreReadOrWriteOrExec = DispatchEventHiddenHookPageReadWriteExecuteExecutePreEvent(VCpu, LastContext, &IsTriggeringPostEventAllowed);
1777
1778 //
1779 // It's an execution violation
1780 //
1781 *IsExecViolation = TRUE;
1782 }
1783 else
1784 {
1785 //
1786 // triggering post event is not allowed as it's not valid
1787 //
1788 HookedEntryDetails->IsPostEventTriggerAllowed = FALSE;
1789
1790 //
1791 // there was an unexpected ept violation
1792 //
1793 return FALSE;
1794 }
1795
1796 //
1797 // Set whether the post event trigger is allowed or not
1798 // If only one event short-circuit a special EPT hook the 'post' mode will be ignored for all of the same events
1799 //
1800 if (*IgnoreReadOrWriteOrExec == FALSE)
1801 {
1802 HookedEntryDetails->IsPostEventTriggerAllowed = IsTriggeringPostEventAllowed;
1803 }
1804 else
1805 {
1806 //
1807 // Ignoring read/write/exec will remove the 'post' event
1808 //
1809 HookedEntryDetails->IsPostEventTriggerAllowed = FALSE;
1810 }
1811
1812 //
1813 // Means that restore the Entry to the previous state after current
1814 // instruction executed in the guest
1815 //
1816 return TRUE;
1817}
UCHAR BOOLEAN
Definition BasicTypes.h:39
BOOLEAN DispatchEventHiddenHookPageReadWriteExecuteWritePreEvent(VIRTUAL_MACHINE_STATE *VCpu, PVOID Context, BOOLEAN *IsTriggeringPostEventAllowed)
Handling debugger functions related to read & write & execute, write events (pre)
Definition Dispatch.c:1102
BOOLEAN DispatchEventHiddenHookPageReadWriteExecuteExecutePreEvent(VIRTUAL_MACHINE_STATE *VCpu, PVOID Context, BOOLEAN *IsTriggeringPostEventAllowed)
Handling debugger functions related to read & write & execute, execute events (pre)
Definition Dispatch.c:1196
BOOLEAN DispatchEventHiddenHookPageReadWriteExecuteReadPreEvent(VIRTUAL_MACHINE_STATE *VCpu, PVOID Context, BOOLEAN *IsTriggeringPostEventAllowed)
Handling debugger functions related to read & write & execute, read events (pre)
Definition Dispatch.c:1008
@ EPT_HOOKED_LAST_VIOLATION_READ
Definition State.h:64
@ EPT_HOOKED_LAST_VIOLATION_EXEC
Definition State.h:66
@ EPT_HOOKED_LAST_VIOLATION_WRITE
Definition State.h:65
#define PAGE_ALIGN(Va)
Aligning a page.
Definition common.h:75
UINT64 VirtualAddress
The virtual address from the caller perspective view (cr3)
Definition State.h:175
UINT64 HookingTag
Tag used for notifying the caller.
Definition State.h:202
BOOLEAN IsPostEventTriggerAllowed
This field shows whether the hook should call the post event trigger after restoring the state or not...
Definition State.h:248
EPT_HOOKED_LAST_VIOLATION LastViolation
This field shows the last violation happened to this EPT hook.
Definition State.h:253
UINT64 HookingTag
Definition DataTypes.h:321

◆ EptHookHandleMonitorTrapFlag()

VOID EptHookHandleMonitorTrapFlag ( VIRTUAL_MACHINE_STATE * VCpu)

Handle vm-exits for Monitor Trap Flag to restore previous state.

Parameters
VCpuThe virtual processor's state
Returns
VOID
1964{
1965 PVOID TargetPage;
1966 //
1967 // Pointer to the page entry in the page table
1968 //
1970
1971 //
1972 // restore the hooked state
1973 //
1975 TargetPage,
1977 InveptSingleContext);
1978
1979 //
1980 // Check to trigger the post event (for events relating the !monitor command
1981 // and the emulation hardware debug registers)
1982 //
1984 {
1986 {
1987 //
1988 // This is a "read" hook
1989 //
1992 }
1994 {
1995 //
1996 // This is a "write" hook
1997 //
2000 }
2002 {
2003 //
2004 // This is a "execute" hook
2005 //
2008 }
2009 }
2010
2011 //
2012 // Check for user-mode attaching mechanisms and callback
2013 // (we call it here, because this callback might change the EPTP entries and invalidate EPTP)
2014 //
2016}
BOOLEAN VmmCallbackRestoreEptState(UINT32 CoreId)
routine callback to restore EPT state
Definition Callback.c:294
VOID DispatchEventHiddenHookPageReadWriteExecReadPostEvent(VIRTUAL_MACHINE_STATE *VCpu, PVOID Context)
Handling debugger functions related to read & write & execute, read events (post)
Definition Dispatch.c:1289
VOID DispatchEventHiddenHookPageReadWriteExecWritePostEvent(VIRTUAL_MACHINE_STATE *VCpu, PVOID Context)
Handling debugger functions related to read & write & execute, write events (post)
Definition Dispatch.c:1336
VOID DispatchEventHiddenHookPageReadWriteExecExecutePostEvent(VIRTUAL_MACHINE_STATE *VCpu, PVOID Context)
Handling debugger functions related to read & write & execute, execute events (post)
Definition Dispatch.c:1381
PEPT_PML1_ENTRY EptGetPml1Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress)
Get the PML1 entry for this physical address if the page is split.
Definition Ept.c:304
_Use_decl_annotations_ VOID EptSetPML1AndInvalidateTLB(VIRTUAL_MACHINE_STATE *VCpu, PEPT_PML1_ENTRY EntryAddress, EPT_PML1_ENTRY EntryValue, INVEPT_TYPE InvalidationType)
This function set the specific PML1 entry in a spinlock protected area then invalidate the TLB.
Definition Ept.c:1075
EPT_HOOKS_CONTEXT LastContextState
Temporary context for the post event monitors It shows the context of the last address that triggered...
Definition State.h:242
EPT_PML1_ENTRY ChangedEntry
The original page entry. Will be copied back when the hook is remove from the page.
Definition State.h:219
SIZE_T PhysicalBaseAddress
The base address of the page. Used to find this structure in the list of page hooks when a hook is hi...
Definition State.h:187
PVMM_EPT_PAGE_TABLE EptPageTable
Definition State.h:342
PEPT_HOOKED_PAGE_DETAIL MtfEptHookRestorePoint
Definition State.h:331
UINT32 CoreId
Definition State.h:306

◆ EptHookInlineHook()

BOOLEAN EptHookInlineHook ( VIRTUAL_MACHINE_STATE * VCpu,
PVOID TargetAddress,
PVOID HookFunction,
UINT32 ProcessId )

Hook in VMX non-root mode (hidden detours)

Parameters
VCpu
TargetAddress
HookFunction
ProcessId
Returns
BOOLEAN

Hook in VMX non-root mode (hidden detours)

this function should be called from VMX non-root mode

Parameters
VCpuThe virtual processor's state
TargetAddressThe address of function or memory address to be hooked
HookFunctionThe function that will be called when hook triggered
ProcessIdThe process id to translate based on that process's cr3
Returns
BOOLEAN Returns true if the hook was successful or false if there was an error
1546{
1547 EPT_HOOKS_ADDRESS_DETAILS_FOR_EPTHOOK2 HookingDetail = {0};
1548
1549 //
1550 // Should be called from vmx non-root
1551 //
1553 {
1554 return FALSE;
1555 }
1556
1557 //
1558 // Set the hooking details
1559 //
1560 HookingDetail.TargetAddress = TargetAddress;
1561 HookingDetail.HookFunction = HookFunction;
1562
1564 &HookingDetail,
1565 NULL,
1566 ProcessId,
1567 TRUE,
1568 FALSE);
1569}
BOOLEAN EptHookPerformMemoryOrInlineHook(VIRTUAL_MACHINE_STATE *VCpu, EPT_HOOKS_ADDRESS_DETAILS_FOR_EPTHOOK2 *EptHook2AddressDetails, EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *MemoryAddressDetails, UINT32 ProcessId, BOOLEAN EptHiddenHook2, BOOLEAN ApplyDirectlyFromVmxRoot)
This function allocates a buffer in VMX Non Root Mode and then invokes a VMCALL to set the hook.
Definition EptHook.c:1370
Setting details for EPT Hooks (!epthook2)
Definition DataTypes.h:347
PVOID HookFunction
Definition DataTypes.h:349
PVOID TargetAddress
Definition DataTypes.h:348

◆ EptHookInlineHookFromVmxRoot()

BOOLEAN EptHookInlineHookFromVmxRoot ( VIRTUAL_MACHINE_STATE * VCpu,
PVOID TargetAddress,
PVOID HookFunction )

Hook in VMX root-mode (hidden detours)

Parameters
VCpu
TargetAddress
HookFunction
Returns
BOOLEAN

Hook in VMX root-mode (hidden detours)

this function should be called from VMX root-mode

Parameters
VCpuThe virtual processor's state
TargetAddressThe address of function or memory address to be hooked
HookFunctionThe function that will be called when hook triggered
Returns
BOOLEAN Returns true if the hook was successful or false if there was an error
1616{
1617 EPT_HOOKS_ADDRESS_DETAILS_FOR_EPTHOOK2 HookingDetail = {0};
1618
1619 //
1620 // Should be called from vmx root-mode
1621 //
1623 {
1624 return FALSE;
1625 }
1626
1627 //
1628 // Configure the details
1629 //
1630 HookingDetail.TargetAddress = TargetAddress;
1631 HookingDetail.HookFunction = HookFunction;
1632
1634 &HookingDetail,
1635 NULL,
1636 NULL_ZERO,
1637 TRUE,
1638 TRUE);
1639}

◆ EptHookModifyInstructionFetchState()

BOOLEAN EptHookModifyInstructionFetchState ( VIRTUAL_MACHINE_STATE * VCpu,
PVOID PhysicalAddress,
BOOLEAN IsUnset )

Change PML EPT state for execution (execute) @detail should be called from VMX-root.

Parameters
VCpuThe virtual processor's state
PhysicalAddressTarget physical address
IsUnsetIs unsetting bit or setting bit
Returns
BOOLEAN
2569{
2570 PVOID PmlEntry = NULL;
2571 BOOLEAN IsLargePage = FALSE;
2572
2573 PmlEntry = EptGetPml1OrPml2Entry(g_EptState->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
2574
2575 if (PmlEntry)
2576 {
2577 if (IsLargePage)
2578 {
2579 if (IsUnset)
2580 {
2581 ((PEPT_PML2_ENTRY)PmlEntry)->ExecuteAccess = FALSE;
2582 }
2583 else
2584 {
2585 ((PEPT_PML2_ENTRY)PmlEntry)->ExecuteAccess = TRUE;
2586 }
2587 }
2588 else
2589 {
2590 if (IsUnset)
2591 {
2592 ((PEPT_PML1_ENTRY)PmlEntry)->ExecuteAccess = FALSE;
2593 }
2594 else
2595 {
2596 ((PEPT_PML1_ENTRY)PmlEntry)->ExecuteAccess = TRUE;
2597 }
2598 }
2599 }
2600 else
2601 {
2602 return FALSE;
2603 }
2604
2605 //
2606 // Invalidate the EPTP (single-context)
2607 //
2608 EptInveptSingleContext(VCpu->EptPointer.AsUInt);
2609
2610 return TRUE;
2611}
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
UCHAR EptInveptSingleContext(_In_ UINT64 EptPointer)
Invalidates a single context in ept cache table.
Definition Invept.c:40
EPT_PTE * PEPT_PML1_ENTRY
Definition State.h:22
EPT_PDE_2MB * PEPT_PML2_ENTRY
Definition State.h:20
NULL()
Definition test-case-generator.py:530
PVMM_EPT_PAGE_TABLE EptPageTable
Definition Ept.h:121
EPT_POINTER EptPointer
Definition State.h:341

◆ EptHookModifyPageReadState()

BOOLEAN EptHookModifyPageReadState ( VIRTUAL_MACHINE_STATE * VCpu,
PVOID PhysicalAddress,
BOOLEAN IsUnset )

Change PML EPT state for read @detail should be called from VMX-root.

Parameters
VCpuThe virtual processor's state
PhysicalAddressTarget physical address
IsUnsetIs unsetting bit or setting bit
Returns
BOOLEAN
2627{
2628 PVOID PmlEntry = NULL;
2629 BOOLEAN IsLargePage = FALSE;
2630
2631 PmlEntry = EptGetPml1OrPml2Entry(g_EptState->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
2632
2633 if (PmlEntry)
2634 {
2635 if (IsLargePage)
2636 {
2637 if (IsUnset)
2638 {
2639 ((PEPT_PML2_ENTRY)PmlEntry)->ReadAccess = FALSE;
2640 }
2641 else
2642 {
2643 ((PEPT_PML2_ENTRY)PmlEntry)->ReadAccess = TRUE;
2644 }
2645 }
2646 else
2647 {
2648 if (IsUnset)
2649 {
2650 ((PEPT_PML1_ENTRY)PmlEntry)->ReadAccess = FALSE;
2651 }
2652 else
2653 {
2654 ((PEPT_PML1_ENTRY)PmlEntry)->ReadAccess = TRUE;
2655 }
2656 }
2657 }
2658 else
2659 {
2660 return FALSE;
2661 }
2662
2663 //
2664 // Invalidate the EPTP (single-context)
2665 //
2666 EptInveptSingleContext(VCpu->EptPointer.AsUInt);
2667
2668 return TRUE;
2669}

◆ EptHookModifyPageWriteState()

BOOLEAN EptHookModifyPageWriteState ( VIRTUAL_MACHINE_STATE * VCpu,
PVOID PhysicalAddress,
BOOLEAN IsUnset )

Change PML EPT state for write @detail should be called from VMX-root.

Parameters
VCpuThe virtual processor's state
PhysicalAddressTarget physical address
IsUnsetIs unsetting bit or setting bit
Returns
BOOLEAN
2685{
2686 PVOID PmlEntry = NULL;
2687 BOOLEAN IsLargePage = FALSE;
2688
2689 PmlEntry = EptGetPml1OrPml2Entry(g_EptState->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
2690
2691 if (PmlEntry)
2692 {
2693 if (IsLargePage)
2694 {
2695 if (IsUnset)
2696 {
2697 ((PEPT_PML2_ENTRY)PmlEntry)->WriteAccess = FALSE;
2698 }
2699 else
2700 {
2701 ((PEPT_PML2_ENTRY)PmlEntry)->WriteAccess = TRUE;
2702 }
2703 }
2704 else
2705 {
2706 if (IsUnset)
2707 {
2708 ((PEPT_PML1_ENTRY)PmlEntry)->WriteAccess = FALSE;
2709 }
2710 else
2711 {
2712 ((PEPT_PML1_ENTRY)PmlEntry)->WriteAccess = TRUE;
2713 }
2714 }
2715 }
2716 else
2717 {
2718 return FALSE;
2719 }
2720
2721 //
2722 // Invalidate the EPTP (single-context)
2723 //
2724 EptInveptSingleContext(VCpu->EptPointer.AsUInt);
2725
2726 return TRUE;
2727}

◆ EptHookMonitorFromVmxRoot()

BOOLEAN EptHookMonitorFromVmxRoot ( VIRTUAL_MACHINE_STATE * VCpu,
EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR * MemoryAddressDetails )

This function applies EPT monitor hooks to the target EPT table.

this function should be called from VMX root-mode

Parameters
VCpu
MemoryAddressDetails
Returns
BOOLEAN

this function should be called from VMX root-mode

Parameters
VCpuThe virtual processor's state
MemoryAddressDetailsdetails of the target memory
Returns
BOOLEAN Returns true if the hook was successful or false if there was an error
1653{
1654 //
1655 // Should be called from vmx root-mode
1656 //
1658 {
1659 return FALSE;
1660 }
1661
1663 NULL,
1664 MemoryAddressDetails,
1665 NULL_ZERO,
1666 FALSE,
1667 TRUE);
1668}

◆ EptHookMonitorHook()

BOOLEAN EptHookMonitorHook ( VIRTUAL_MACHINE_STATE * VCpu,
EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR * HookingDetails,
UINT32 ProcessId )

This function applies monitor hooks to the target EPT table.

this function should be called from VMX non-root mode

Parameters
VCpu
HookingDetails
ProcessId
Returns
BOOLEAN

this function should be called from VMX non-root mode

Parameters
VCpuThe virtual processor's state
HookingDetailsMonitor hooking details
ProcessIdThe process id to translate based on that process's cr3
Returns
BOOLEAN Returns true if the hook was successful or false if there was an error
1585{
1586 //
1587 // Should be called from vmx non-root
1588 //
1590 {
1591 return FALSE;
1592 }
1593
1595 NULL,
1596 HookingDetails,
1597 ProcessId,
1598 FALSE,
1599 FALSE);
1600}

◆ EptHookPerformPageHook()

BOOLEAN EptHookPerformPageHook ( VIRTUAL_MACHINE_STATE * VCpu,
PVOID TargetAddress,
CR3_TYPE ProcessCr3 )

Hook in VMX Root Mode with hidden breakpoints (A pre-allocated buffer should be available)

Parameters
VCpu
TargetAddress
ProcessCr3
Returns
BOOLEAN

Hook in VMX Root Mode with hidden breakpoints (A pre-allocated buffer should be available)

This function returns false in VMX Non-Root Mode if the VM is already initialized This function have to be called through a VMCALL in VMX Root Mode

Parameters
VCpuThe virtual processor's state
TargetAddressThe address of function or memory address to be hooked
ProcessCr3The process cr3 to translate based on that process's cr3
Returns
BOOLEAN Returns true if the hook was successful or false if there was an error
477{
478 SIZE_T PhysicalBaseAddress;
479 PVOID VirtualTarget;
480 EPT_HOOKED_PAGE_DETAIL * HookedEntry = NULL;
481
482 //
483 // Translate the page from a physical address to virtual so we can read its memory.
484 // This function will return NULL if the physical address was not already mapped in
485 // virtual memory.
486 //
487 VirtualTarget = PAGE_ALIGN(TargetAddress);
488
489 //
490 // Here we have to change the CR3, it is because we are in SYSTEM process
491 // and if the target address is not mapped in SYSTEM address space (e.g
492 // user mode address of another process) then the translation is invalid
493 //
494
495 //
496 // Find cr3 of target core
497 //
498 PhysicalBaseAddress = (SIZE_T)VirtualAddressToPhysicalAddressByProcessCr3(VirtualTarget, ProcessCr3);
499
500 if (!PhysicalBaseAddress)
501 {
503 return FALSE;
504 }
505
506 //
507 // try to see if we can find the address
508 //
509
510 HookedEntry = EptHookFindByPhysAddress(PhysicalBaseAddress);
511
512 if (HookedEntry != NULL)
513 {
514 return EptHookUpdateHookPage(TargetAddress, HookedEntry);
515 }
516 else
517 {
518 return EptHookCreateHookPage(VCpu, TargetAddress, ProcessCr3);
519 }
520}
VOID VmmCallbackSetLastError(UINT32 LastError)
routine callback to set last error
Definition Callback.c:175
_Use_decl_annotations_ UINT64 VirtualAddressToPhysicalAddressByProcessCr3(PVOID VirtualAddress, CR3_TYPE TargetCr3)
Converts Virtual Address to Physical Address based on a specific process's kernel cr3.
Definition Conversion.c:215
#define DEBUGGER_ERROR_INVALID_ADDRESS
error, invalid address specified for debugger
Definition ErrorCodes.h:63

◆ EptHookPerformPageHookMonitorAndInlineHook()

BOOLEAN EptHookPerformPageHookMonitorAndInlineHook ( VIRTUAL_MACHINE_STATE * VCpu,
PVOID HookingDetails,
CR3_TYPE ProcessCr3,
UINT32 PageHookMask )

Hook in VMX Root Mode with hidden detours and monitor (A pre-allocated buffer should be available)

Parameters
VCpu
HookingDetails
ProcessCr3
PageHookMask
Returns
BOOLEAN

Hook in VMX Root Mode with hidden detours and monitor (A pre-allocated buffer should be available)

This function returns false in VMX Non-Root Mode if the VM is already initialized This function have to be called through a VMCALL in VMX Root Mode

Parameters
VCpuThe virtual processor's state
HookingDetailsThe address of function or memory address to be hooked
ProcessCr3The process cr3 to translate based on that process's cr3
PageHookMaskMask hook of the page
Returns
BOOLEAN Returns true if the hook was successful or false if there was an error
984{
985 ULONG ProcessorsCount;
986 EPT_PML1_ENTRY ChangedEntry;
987 SIZE_T PhysicalBaseAddress;
988 PVOID AlignedTargetVaOrPa;
989 PVOID TargetBuffer;
990 PVOID TargetAddress;
991 PVOID HookFunction;
992 UINT64 TargetAddressInSafeMemory;
993 PEPT_PML1_ENTRY TargetPage;
994 PEPT_HOOKED_PAGE_DETAIL HookedPage;
995 CR3_TYPE Cr3OfCurrentProcess;
996 PLIST_ENTRY TempList = 0;
997 PEPT_HOOKED_PAGE_DETAIL HookedEntry = NULL;
998 BOOLEAN UnsetExecute = FALSE;
999 BOOLEAN UnsetRead = FALSE;
1000 BOOLEAN UnsetWrite = FALSE;
1001 BOOLEAN EptHiddenHook = FALSE;
1002
1003 UnsetRead = (PageHookMask & PAGE_ATTRIB_READ) ? TRUE : FALSE;
1004 UnsetWrite = (PageHookMask & PAGE_ATTRIB_WRITE) ? TRUE : FALSE;
1005 UnsetExecute = (PageHookMask & PAGE_ATTRIB_EXEC) ? TRUE : FALSE;
1006 EptHiddenHook = (PageHookMask & PAGE_ATTRIB_EXEC_HIDDEN_HOOK) ? TRUE : FALSE;
1007
1008 //
1009 // Get number of processors
1010 //
1011 ProcessorsCount = KeQueryActiveProcessorCount(0);
1012
1013 //
1014 // Translate the page from a physical address to virtual so we can read its memory.
1015 // This function will return NULL if the physical address was not already mapped in
1016 // virtual memory.
1017 //
1018 if (EptHiddenHook)
1019 {
1020 TargetAddress = ((EPT_HOOKS_ADDRESS_DETAILS_FOR_EPTHOOK2 *)HookingDetails)->TargetAddress;
1021 }
1022 else
1023 {
1024 TargetAddress = (PVOID)((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->StartAddress;
1025 }
1026
1027 AlignedTargetVaOrPa = PAGE_ALIGN(TargetAddress);
1028
1029 //
1030 // Here we have to change the CR3, it is because we are in SYSTEM process
1031 // and if the target address is not mapped in SYSTEM address space (e.g
1032 // user mode address of another process) then the translation is invalid
1033 //
1034
1035 if (!EptHiddenHook &&
1037 {
1038 //
1039 // The address itself is a physical address, no need for conversion
1040 //
1041 PhysicalBaseAddress = (SIZE_T)AlignedTargetVaOrPa;
1042 }
1043 else
1044 {
1045 //
1046 // based on the CR3 of target core
1047 //
1048 PhysicalBaseAddress = (SIZE_T)VirtualAddressToPhysicalAddressByProcessCr3(AlignedTargetVaOrPa, ProcessCr3);
1049 }
1050
1051 if (!PhysicalBaseAddress)
1052 {
1054 return FALSE;
1055 }
1056
1057 //
1058 // try to see if we can find the address
1059 //
1060 TempList = &g_EptState->HookedPagesList;
1061
1062 while (&g_EptState->HookedPagesList != TempList->Flink)
1063 {
1064 TempList = TempList->Flink;
1065 HookedEntry = CONTAINING_RECORD(TempList, EPT_HOOKED_PAGE_DETAIL, PageHookList);
1066
1067 if (HookedEntry->PhysicalBaseAddress == PhysicalBaseAddress)
1068 {
1069 //
1070 // Means that we find the address and !epthook2 doesn't support
1071 // multiple breakpoints in on page
1072 //
1074 return FALSE;
1075 }
1076 }
1077
1078 //
1079 // Save the detail of hooked page to keep track of it
1080 //
1082
1083 if (!HookedPage)
1084 {
1086 return FALSE;
1087 }
1088
1089 //
1090 // Save the virtual address
1091 //
1092 HookedPage->VirtualAddress = (UINT64)TargetAddress;
1093
1094 //
1095 // Save the physical address
1096 //
1097 HookedPage->PhysicalBaseAddress = PhysicalBaseAddress;
1098
1099 //
1100 // If it's a monitor hook, then we need to hold the address of the start
1101 // physical address as well as the end physical address, plus tagging information
1102 //
1103 if (!EptHiddenHook)
1104 {
1105 //
1106 // Save the target tag
1107 //
1108 HookedPage->HookingTag = ((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->Tag;
1109
1110 //
1111 // Save the start of the target physical address
1112 //
1114 {
1115 //
1116 // Physical address
1117 //
1118 HookedPage->StartOfTargetPhysicalAddress = (SIZE_T)(((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->StartAddress);
1119 }
1120 else
1121 {
1122 //
1123 // Virtual address
1124 //
1126 (PVOID)(((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->StartAddress),
1127 ProcessCr3);
1128 }
1129
1130 if (!HookedPage->StartOfTargetPhysicalAddress)
1131 {
1132 PoolManagerFreePool((UINT64)HookedPage);
1133
1135 return FALSE;
1136 }
1137
1138 //
1139 // Save the end of the target physical address
1140 //
1142 {
1143 //
1144 // Physical address
1145 //
1146 HookedPage->EndOfTargetPhysicalAddress = (SIZE_T)(((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->EndAddress);
1147 }
1148 else
1149 {
1150 //
1151 // Virtual address
1152 //
1154 (PVOID)(((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->EndAddress),
1155 ProcessCr3);
1156 }
1157
1158 if (!HookedPage->EndOfTargetPhysicalAddress)
1159 {
1160 PoolManagerFreePool((UINT64)HookedPage);
1161
1163 return FALSE;
1164 }
1165 }
1166
1167 //
1168 // Fake page content physical address
1169 //
1171
1172 if (EptHiddenHook)
1173 {
1174 //
1175 // Show that entry has hidden hooks for execution
1176 //
1177 HookedPage->IsExecutionHook = TRUE;
1178
1179 //
1180 // Switch to target process
1181 //
1182 Cr3OfCurrentProcess = SwitchToProcessMemoryLayoutByCr3(ProcessCr3);
1183
1184 //
1185 // Copy the content to the fake page
1186 // The following line can't be used in user mode addresses
1187 // RtlCopyBytes(&HookedPage->FakePageContents, VirtualTarget, PAGE_SIZE);
1188 //
1189 MemoryMapperReadMemorySafe((UINT64)AlignedTargetVaOrPa, &HookedPage->FakePageContents, PAGE_SIZE);
1190
1191 //
1192 // Restore to original process
1193 //
1194 SwitchToPreviousProcess(Cr3OfCurrentProcess);
1195
1196 //
1197 // Compute new offset of target offset into a safe bufferr
1198 // It will be used to compute the length of the detours
1199 // address because we might have a user mode code
1200 //
1201 TargetAddressInSafeMemory = EptHookCalcBreakpointOffset(TargetAddress, HookedPage);
1202
1203 //
1204 // Make sure if handler function is valid or if it's default
1205 // then we set it to the default handler
1206 //
1207 if (((EPT_HOOKS_ADDRESS_DETAILS_FOR_EPTHOOK2 *)HookingDetails)->HookFunction == NULL)
1208 {
1209 HookFunction = (PVOID)AsmGeneralDetourHook;
1210 }
1211 else
1212 {
1213 HookFunction = ((EPT_HOOKS_ADDRESS_DETAILS_FOR_EPTHOOK2 *)HookingDetails)->HookFunction;
1214 }
1215
1216 //
1217 // Create Hook
1218 //
1219 if (!EptHookInstructionMemory(HookedPage, ProcessCr3, TargetAddress, (PVOID)TargetAddressInSafeMemory, HookFunction))
1220 {
1221 PoolManagerFreePool((UINT64)HookedPage);
1222
1224 return FALSE;
1225 }
1226 }
1227
1228 for (size_t i = 0; i < ProcessorsCount; i++)
1229 {
1230 //
1231 // Set target buffer, request buffer from pool manager,
1232 // we also need to allocate new page to replace the current page
1233 //
1235
1236 if (!TargetBuffer)
1237 {
1238 PoolManagerFreePool((UINT64)HookedPage);
1239
1241 return FALSE;
1242 }
1243
1244 if (!EptSplitLargePage(g_GuestState[i].EptPageTable, TargetBuffer, PhysicalBaseAddress))
1245 {
1246 PoolManagerFreePool((UINT64)HookedPage);
1247 PoolManagerFreePool((UINT64)TargetBuffer); // Here also other previous pools should be specified, but we forget it for now
1248
1249 LogDebugInfo("Err, could not split page for the address : 0x%llx", PhysicalBaseAddress);
1251 return FALSE;
1252 }
1253
1254 //
1255 // Pointer to the page entry in the page table
1256 //
1257 TargetPage = EptGetPml1Entry(g_GuestState[i].EptPageTable, PhysicalBaseAddress);
1258
1259 //
1260 // Ensure the target is valid
1261 //
1262 if (!TargetPage)
1263 {
1264 PoolManagerFreePool((UINT64)HookedPage);
1265 PoolManagerFreePool((UINT64)TargetBuffer); // Here also other previous pools should be specified, but we forget it for now
1266
1268 return FALSE;
1269 }
1270
1271 //
1272 // Save the original entry (only one of the page tables as the base original entry
1273 // is enough)
1274 //
1275 HookedPage->OriginalEntry = *TargetPage;
1276
1277 //
1278 // Save the original permissions of the page
1279 //
1280 ChangedEntry = *TargetPage;
1281
1282 //
1283 // Execution is treated differently
1284 //
1285 if (UnsetRead)
1286 ChangedEntry.ReadAccess = 0;
1287 else
1288 ChangedEntry.ReadAccess = 1;
1289
1290 if (UnsetWrite)
1291 ChangedEntry.WriteAccess = 0;
1292 else
1293 ChangedEntry.WriteAccess = 1;
1294
1295 if (UnsetExecute)
1296 ChangedEntry.ExecuteAccess = 0;
1297 else
1298 ChangedEntry.ExecuteAccess = 1;
1299
1300 //
1301 // If it's Execution hook then we have to set extra fields
1302 //
1303 if (EptHiddenHook)
1304 {
1305 //
1306 // In execution hook, we have to make sure to unset read, write because
1307 // an EPT violation should occur for these cases and we can swap the original page
1308 //
1309 ChangedEntry.ReadAccess = 0;
1310 ChangedEntry.WriteAccess = 0;
1311 ChangedEntry.ExecuteAccess = 1;
1312
1313 //
1314 // Also set the current pfn to fake page
1315 //
1316 ChangedEntry.PageFrameNumber = HookedPage->PhysicalBaseAddressOfFakePageContents;
1317 }
1318
1319 //
1320 // Only for the first time execution of the loop, we save these details,
1321 // it is because after this condition, the hook is applied and by applying
1322 // the hook, we have to make sure that the address is saved g_EptState->HookedPagesList
1323 // because the hook might be simultaneously triggered from other cores
1324 //
1325 if (i == 0)
1326 {
1327 //
1328 // Save the modified entry
1329 //
1330 HookedPage->ChangedEntry = ChangedEntry;
1331
1332 //
1333 // Add it to the list
1334 //
1336 }
1337
1338 //
1339 // Apply the hook to EPT
1340 //
1341 TargetPage->AsUInt = ChangedEntry.AsUInt;
1342
1343 //
1344 // If it's the current core then we invalidate the EPT
1345 //
1346 if (VCpu->CoreId == i && g_GuestState[i].HasLaunched)
1347 {
1348 EptInveptSingleContext(VCpu->EptPointer.AsUInt);
1349 }
1350 }
1351
1352 return TRUE;
1353}
@ DEBUGGER_MEMORY_HOOK_PHYSICAL_ADDRESS
Definition DataTypes.h:312
BOOLEAN EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable, PVOID PreAllocatedBuffer, SIZE_T PhysicalAddress)
Split 2MB (LargePage) into 4kb pages.
Definition Ept.c:462
#define PAGE_ATTRIB_EXEC
Definition Ept.h:24
#define PAGE_ATTRIB_READ
Page attributes for internal use.
Definition Ept.h:22
#define PAGE_ATTRIB_EXEC_HIDDEN_HOOK
Definition Ept.h:25
#define PAGE_ATTRIB_WRITE
Definition Ept.h:23
BOOLEAN EptHookInstructionMemory(PEPT_HOOKED_PAGE_DETAIL Hook, CR3_TYPE ProcessCr3, PVOID TargetFunction, PVOID TargetFunctionInSafeMemory, PVOID HookFunction)
Hook instructions.
Definition EptHook.c:834
#define DEBUGGER_ERROR_EPT_FAILED_TO_GET_PML1_ENTRY_OF_TARGET_ADDRESS
error, failed to get PML1 entry of the target address
Definition ErrorCodes.h:264
#define DEBUGGER_ERROR_PRE_ALLOCATED_BUFFER_IS_EMPTY
error, there is no pre-allocated buffer
Definition ErrorCodes.h:251
#define DEBUGGER_ERROR_EPT_MULTIPLE_HOOKS_IN_A_SINGLE_PAGE
error, multiple EPT Hooks or Monitors are applied on a single page
Definition ErrorCodes.h:270
#define DEBUGGER_ERROR_COULD_NOT_BUILD_THE_EPT_HOOK
error, could not build the EPT Hook
Definition ErrorCodes.h:276
#define DEBUGGER_ERROR_EPT_COULD_NOT_SPLIT_THE_LARGE_PAGE_TO_4KB_PAGES
error, in the EPT handler, it could not split the 2MB pages to 512 entries of 4 KB pages
Definition ErrorCodes.h:258
#define LogDebugInfo(format,...)
Log, initialize boot information and debug information.
Definition HyperDbgHyperLogIntrinsics.h:155
void AsmGeneralDetourHook(void)
Detour hook handler.
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafe(UINT64 VaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead)
Read memory safely by mapping the buffer (It's a wrapper)
Definition MemoryMapper.c:1101
UINT64 PoolManagerRequestPool(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size)
This function should be called from vmx-root in order to get a pool from the list.
Definition PoolManager.c:212
BOOLEAN PoolManagerFreePool(UINT64 AddressToFree)
This function set a pool flag to be freed, and it will be freed on the next IOCTL when it's safe to r...
Definition PoolManager.c:136
_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
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ PLIST_ENTRY Entry)
Definition Windows.h:115
EPT_PTE EPT_PML1_ENTRY
Definition State.h:22
#define PAGE_SIZE
Size of each page (4096 bytes)
Definition common.h:69
CR3 Structure.
Definition BasicTypes.h:130
SIZE_T PhysicalBaseAddressOfFakePageContents
The base address of the page with fake contents. Used to swap page with fake contents when a hook is ...
Definition State.h:208
BOOLEAN IsExecutionHook
This field shows whether the hook contains a hidden hook for execution or not.
Definition State.h:229
LIST_ENTRY PageHookList
Linked list entries for each page hook.
Definition State.h:170
CHAR FakePageContents[PAGE_SIZE]
Definition State.h:165
SIZE_T EndOfTargetPhysicalAddress
End address of the target physical address.
Definition State.h:197
SIZE_T StartOfTargetPhysicalAddress
Start address of the target physical address.
Definition State.h:192
EPT_PML1_ENTRY OriginalEntry
The original page entry. Will be copied back when the hook is removed from the page.
Definition State.h:214
Setting details for EPT Hooks (!monitor)
Definition DataTypes.h:331
BOOLEAN HasLaunched
Definition State.h:293

◆ EptHookRemoveEntryAndFreePoolFromEptHook2sDetourList()

BOOLEAN EptHookRemoveEntryAndFreePoolFromEptHook2sDetourList ( UINT64 Address)

Remove an entry from g_EptHook2sDetourListHead.

Parameters
Address
Returns
BOOLEAN

Remove an entry from g_EptHook2sDetourListHead.

Parameters
AddressAddress to remove
Returns
BOOLEAN TRUE if successfully removed and false if not found
1827{
1828 //
1829 // Iterate through the list of hooked pages details to find
1830 // the entry in the list
1831 //
1832 LIST_FOR_EACH_LINK(g_EptHook2sDetourListHead, HIDDEN_HOOKS_DETOUR_DETAILS, OtherHooksList, CurrentHookedDetails)
1833 {
1834 if (CurrentHookedDetails->HookedFunctionAddress == (PVOID)Address)
1835 {
1836 //
1837 // We found the address, we should remove it and add it for
1838 // future deallocation
1839 //
1840 RemoveEntryList(&CurrentHookedDetails->OtherHooksList);
1841
1842 //
1843 // Free the pool in next ioctl
1844 //
1845 if (!PoolManagerFreePool((UINT64)CurrentHookedDetails))
1846 {
1847 LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
1848 }
1849 return TRUE;
1850 }
1851 }
1852 //
1853 // No entry found !
1854 //
1855 return FALSE;
1856}
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113
UINT64 Address
Definition HyperDbgScriptImports.h:67
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition Windows.h:56

◆ EptHookReservePreallocatedPoolsForEptHooks()

VOID EptHookReservePreallocatedPoolsForEptHooks ( UINT32 Count)

Allocate pre-allocated pools for EPT hooks.

Parameters
Countnumber of hooks
Returns
VOID

Allocate pre-allocated pools for EPT hooks.

Parameters
Countnumber of hooks
Returns
VOID
71{
72 ULONG ProcessorsCount;
73
74 //
75 // Get number of processors
76 //
77 ProcessorsCount = KeQueryActiveProcessorCount(0);
78
79 //
80 // Request pages to be allocated for converting 2MB to 4KB pages
81 // Each core needs its own splitting page-tables
82 //
84
85 //
86 // Request pages to be allocated for paged hook details
87 //
89
90 //
91 // Request pages to be allocated for Trampoline of Executable hooked pages
92 //
94
95 //
96 // Request pages to be allocated for detour hooked pages details
97 //
99}
@ EXEC_TRAMPOLINE
Definition DataTypes.h:42
@ DETOUR_HOOK_DETAILS
Definition DataTypes.h:44
#define MAX_EXEC_TRAMPOLINE_SIZE
Maximum number of supported execution trampoline.
Definition Hooks.h:174

◆ EptHookRestoreAllHooksToOriginalEntry()

VOID EptHookRestoreAllHooksToOriginalEntry ( VIRTUAL_MACHINE_STATE * VCpu)

Remove all hooks from the hooked pages lists (Should be called in vmx-root)

Parameters
VCpu
Returns
VOID

Remove all hooks from the hooked pages lists (Should be called in vmx-root)

Warning
This function won't remove entries from LIST_ENTRY, just invalidate the paging, use EptHookUnHookAll instead
Parameters
VCpuThe virtual processor's state
Returns
VOID
705{
706 PEPT_PML1_ENTRY TargetPage;
707
708 //
709 // Should be called from vmx-root, for calling from vmx non-root use the corresponding VMCALL
710 //
712 {
713 return;
714 }
715
717 {
718 //
719 // Pointer to the page entry in the page table
720 //
721 TargetPage = EptGetPml1Entry(VCpu->EptPageTable, HookedEntry->PhysicalBaseAddress);
722
723 //
724 // Apply the hook to EPT
725 //
726 TargetPage->AsUInt = HookedEntry->OriginalEntry.AsUInt;
727 }
728
729 //
730 // Invalidate EPT Cache
731 //
733}

◆ EptHookRestoreSingleHookToOriginalEntry()

BOOLEAN EptHookRestoreSingleHookToOriginalEntry ( VIRTUAL_MACHINE_STATE * VCpu,
SIZE_T PhysicalAddress,
UINT64 OriginalEntry )

Remove a special hook from the hooked pages lists.

Parameters
VCpu
PhysicalAddress
OriginalEntry
Returns
BOOLEAN

Remove a special hook from the hooked pages lists.

Warning
This function won't remove entries from LIST_ENTRY, just invalidate the paging, use EptHookUnHookSingleAddress instead
Parameters
VCpuThe virtual processor's state
PhysicalAddress
OriginalEntry
Returns
BOOLEAN Return false if there was an error or returns true if it was successful
659{
660 PEPT_PML1_ENTRY TargetPage;
661
662 //
663 // Should be called from vmx-root, for calling from vmx non-root use the corresponding VMCALL
664 //
666 {
667 return FALSE;
668 }
669 //
670 // Pointer to the page entry in the page table
671 //
672 TargetPage = EptGetPml1Entry(VCpu->EptPageTable, PhysicalAddress);
673
674 if (TargetPage != NULL)
675 {
676 //
677 // Apply the hook to EPT
678 //
679 TargetPage->AsUInt = OriginalEntry;
680
681 //
682 // Invalidate EPT Cache
683 //
685
686 return TRUE;
687 }
688
689 //
690 // The PML1 entry not found
691 //
692 return FALSE;
693}

◆ EptHookUnHookAll()

VOID EptHookUnHookAll ( )

Remove all hooks from the hooked pages lists.

Returns
VOID

Remove all hooks from the hooked pages lists.

Returns
VOID
2432{
2433 //
2434 // Should be called from vmx non-root
2435 //
2437 {
2438 return;
2439 }
2440
2441 //
2442 // Remove it in all the cores
2443 //
2445
2446 //
2447 // In the case of unhooking all pages, we remove the hooked
2448 // from EPT table in vmx-root and at last, we need to deallocate
2449 // it from the buffers
2450 //
2451
2453 {
2454 //
2455 // Now that we removed this hidden detours hook, it is
2456 // time to remove it from g_EptHook2sDetourListHead
2457 // if the hook is detours
2458 //
2459 if (!CurrEntity->IsHiddenBreakpoint)
2460 {
2461 EptHookRemoveEntryAndFreePoolFromEptHook2sDetourList(CurrEntity->VirtualAddress);
2462 }
2463
2464 //
2465 // As we are in vmx-root here, we add the hooked entry to the list
2466 // of pools that will be deallocated on next IOCTL
2467 //
2468 if (!PoolManagerFreePool((UINT64)CurrEntity))
2469 {
2470 LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
2471 }
2472 }
2473}
BOOLEAN EptHookRemoveEntryAndFreePoolFromEptHook2sDetourList(UINT64 Address)
Remove the entry from g_EptHook2sDetourListHead in the case of !epthook2 details.
Definition EptHook.c:1826
VOID DpcRoutineRemoveHookAndInvalidateAllEntriesOnAllCores(KDPC *Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
The broadcast function which removes all the hooks and invalidate TLB.
Definition DpcRoutines.c:1607

◆ EptHookUnHookAllByHookingTag()

BOOLEAN EptHookUnHookAllByHookingTag ( UINT64 HookingTag)

Remove all hooks from the hooked pages by the given hooking tag.

Should be called from Vmx Non-root

Parameters
HookingTagThe hooking tag to unhook
Returns
BOOLEAN If unhook was successful it returns true or if it was not successful returns false
2297{
2298 EPT_SINGLE_HOOK_UNHOOKING_DETAILS TargetUnhookingDetails; // not used
2299 BOOLEAN AtLeastOneUnhooked = FALSE;
2300 BOOLEAN UnhookingResult = FALSE;
2301
2302 //
2303 // Should be called from vmx non-root
2304 //
2306 {
2307 return FALSE;
2308 }
2309
2310KeepUnhooking:
2312 NULL_ZERO,
2313 HookingTag,
2314 NULL_ZERO,
2315 FALSE,
2316 &TargetUnhookingDetails);
2317
2318 if (UnhookingResult)
2319 {
2320 AtLeastOneUnhooked = TRUE;
2321
2322 //
2323 // Keep unhooking until there is no more hooking details
2324 //
2325 goto KeepUnhooking;
2326 }
2327
2328 return AtLeastOneUnhooked;
2329}
BOOLEAN EptHookPerformUnHookSingleAddress(UINT64 VirtualAddress, UINT64 PhysAddress, UINT64 HookingTag, UINT32 ProcessId, BOOLEAN ApplyDirectlyFromVmxRoot, EPT_SINGLE_HOOK_UNHOOKING_DETAILS *TargetUnhookingDetails)
Remove single hook from the hooked pages list and invalidate TLB.
Definition EptHook.c:2209
Details of unhooking single EPT hooks.
Definition DataTypes.h:358

◆ EptHookUnHookSingleAddress()

BOOLEAN EptHookUnHookSingleAddress ( UINT64 VirtualAddress,
UINT64 PhysAddress,
UINT32 ProcessId )

Remove single hook from the hooked pages list and invalidate TLB From VMX non-root mode.

Parameters
VirtualAddress
PhysAddress
ProcessId
Returns
BOOLEAN

Remove single hook from the hooked pages list and invalidate TLB From VMX non-root mode.

Should be called from VMX non-root

Parameters
VirtualAddressVirtual address to unhook
PhysAddressPhysical address to unhook (optional)
ProcessIdThe process id of target process

in unhooking for some hooks only physical address is availables

Returns
BOOLEAN If unhook was successful it returns true or if it was not successful returns false
2373{
2374 EPT_SINGLE_HOOK_UNHOOKING_DETAILS TargetUnhookingDetails; // not used
2375
2376 //
2377 // Should be called from VMX non-root
2378 //
2380 {
2381 return FALSE;
2382 }
2383
2384 return EptHookPerformUnHookSingleAddress(VirtualAddress,
2385 PhysAddress,
2386 NULL_ZERO,
2387 ProcessId,
2388 FALSE,
2389 &TargetUnhookingDetails);
2390}

◆ EptHookUnHookSingleAddressFromVmxRoot()

BOOLEAN EptHookUnHookSingleAddressFromVmxRoot ( UINT64 VirtualAddress,
UINT64 PhysAddress,
EPT_SINGLE_HOOK_UNHOOKING_DETAILS * TargetUnhookingDetails )

Remove single hook from the hooked pages list and invalidate TLB From VMX root-mode.

Parameters
VirtualAddress
PhysAddress
TargetUnhookingDetails
Returns
BOOLEAN

Remove single hook from the hooked pages list and invalidate TLB From VMX root-mode.

Should be called from VMX root-mode

Parameters
VirtualAddressVirtual address to unhook
PhysAddressPhysical address to unhook (optional)
TargetUnhookingDetailsTarget data for the caller to restore EPT entry and invalidate EPT caches. Only when applied in VMX-root mode directly
Returns
BOOLEAN If unhook was successful it returns true or if it was not successful returns false
2407{
2408 //
2409 // Should be called from VMX root-mode
2410 //
2412 {
2413 return FALSE;
2414 }
2415
2416 return EptHookPerformUnHookSingleAddress(VirtualAddress,
2417 PhysAddress,
2419 NULL_ZERO,
2420 TRUE,
2421 TargetUnhookingDetails);
2422}
#define NULL64_ZERO
Definition BasicTypes.h:52

◆ EptHookUnHookSingleHookByHookingTagFromVmxRoot()

BOOLEAN EptHookUnHookSingleHookByHookingTagFromVmxRoot ( UINT64 HookingTag,
EPT_SINGLE_HOOK_UNHOOKING_DETAILS * TargetUnhookingDetails )

Remove single hook from the hooked pages by the given hooking tag.

Should be called from Vmx root-mode

Parameters
HookingTagThe hooking tag to unhook
Returns
BOOLEAN If unhook was successful it returns true or if it was not successful returns false
2341{
2342 //
2343 // Should be called from VMX root-mode
2344 //
2346 {
2347 return FALSE;
2348 }
2349
2352 HookingTag,
2353 NULL_ZERO,
2354 TRUE,
2355 TargetUnhookingDetails);
2356}

◆ SyscallHookConfigureEFER()

VOID SyscallHookConfigureEFER ( VIRTUAL_MACHINE_STATE * VCpu,
BOOLEAN EnableEFERSyscallHook )

This function enables or disables EFER syscall hoo.

This function should be called for the first time that we want to enable EFER hook because after calling this function EFER MSR is loaded from GUEST_EFER instead of loading from the regular EFER MSR.

Parameters
VCpuThe virtual processor's state
EnableEFERSyscallHookDetermines whether we want to enable syscall hook or disable syscall hook
Returns
VOID
32{
33 IA32_EFER_REGISTER MsrValue;
34 IA32_VMX_BASIC_REGISTER VmxBasicMsr = {0};
35 UINT32 VmEntryControls = 0;
36 UINT32 VmExitControls = 0;
37
38 //
39 // Reading IA32_VMX_BASIC_MSR
40 //
41 VmxBasicMsr.AsUInt = __readmsr(IA32_VMX_BASIC);
42
43 //
44 // Read previous VM-Entry and VM-Exit controls
45 //
46 VmxVmread32P(VMCS_CTRL_VMENTRY_CONTROLS, &VmEntryControls);
47 VmxVmread32P(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, &VmExitControls);
48
49 MsrValue.AsUInt = __readmsr(IA32_EFER);
50
51 if (EnableEFERSyscallHook)
52 {
53 MsrValue.SyscallEnable = FALSE;
54
55 //
56 // Set VM-Entry controls to load EFER
57 //
58 __vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls | VM_ENTRY_LOAD_IA32_EFER, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
59
60 //
61 // Set VM-Exit controls to save EFER
62 //
63 __vmx_vmwrite(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls | VM_EXIT_SAVE_IA32_EFER, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
64
65 //
66 // Set the GUEST EFER to use this value as the EFER
67 //
68 __vmx_vmwrite(VMCS_GUEST_EFER, MsrValue.AsUInt);
69
70 //
71 // also, we have to set exception bitmap to cause vm-exit on #UDs
72 //
74 }
75 else
76 {
77 MsrValue.SyscallEnable = TRUE;
78
79 //
80 // Set VM-Entry controls to load EFER
81 //
82 __vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls & ~VM_ENTRY_LOAD_IA32_EFER, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
83
84 //
85 // Set VM-Exit controls to save EFER
86 //
87 __vmx_vmwrite(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls & ~VM_EXIT_SAVE_IA32_EFER, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
88
89 //
90 // Set the GUEST EFER to use this value as the EFER
91 //
92 __vmx_vmwrite(VMCS_GUEST_EFER, MsrValue.AsUInt);
93
94 //
95 // Because we're not save or load EFER on vm-exits so
96 // we have to set it manually
97 //
98 __writemsr(IA32_EFER, MsrValue.AsUInt);
99
100 //
101 // unset the exception to not cause vm-exit on #UDs
102 //
104 }
105}
UINT32 HvAdjustControls(UINT32 Ctl, UINT32 Msr)
Adjust controls for VMCS based on processor capability.
Definition Hv.c:23
VOID HvSetExceptionBitmap(VIRTUAL_MACHINE_STATE *VCpu, UINT32 IdtIndex)
Set exception bitmap in VMCS.
Definition Hv.c:1022
VOID ProtectedHvRemoveUndefinedInstructionForDisablingSyscallSysretCommands(VIRTUAL_MACHINE_STATE *VCpu)
Reset exception bitmap in VMCS because of clearing !exception commands.
Definition ProtectedHv.c:160
UCHAR VmxVmread32P(size_t Field, UINT32 *FieldValue)
VMX VMREAD instruction (32-bit)
Definition Vmx.c:86
#define VM_EXIT_SAVE_IA32_EFER
Definition Vmx.h:89
#define VM_ENTRY_LOAD_IA32_EFER
Definition Vmx.h:103
@ EXCEPTION_VECTOR_UNDEFINED_OPCODE
Definition Events.h:30

◆ SyscallHookEmulateSYSCALL()

BOOLEAN SyscallHookEmulateSYSCALL ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu)

◆ SyscallHookEmulateSYSRET()

BOOLEAN SyscallHookEmulateSYSRET ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu)

◆ SyscallHookHandleUD()

BOOLEAN SyscallHookHandleUD ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu)

◆ SyscallHookTest()

VOID SyscallHookTest ( )

Make examples for testing hidden hooks.

THIS EXAMPLE IS NOT VALID ANYMORE, PLEASE USE !syscall OR !epthook2 COMMANDS

Returns
VOID
272{
273 //
274 // THIS EXAMPLE IS NOT VALID ANYMORE, PLEASE USE !syscall OR !epthook2 COMMANDS
275 //
276
277 //
278 // Note that this syscall number is only valid for Windows 10 1909,
279 // you have to find the syscall number of NtCreateFile based on
280 // Your Windows version, please visit https://j00ru.vexillium.org/syscalls/nt/64/
281 // for finding NtCreateFile's Syscall number for your Windows
282 //
283
284 INT32 ApiNumberOfNtCreateFile = 0x0055;
285 PVOID ApiLocationFromSSDTOfNtCreateFile = SyscallHookGetFunctionAddress(ApiNumberOfNtCreateFile, FALSE);
286
287 if (!ApiLocationFromSSDTOfNtCreateFile)
288 {
289 LogError("Err, address finding for syscall base address");
290 return;
291 }
292
293 //
294 // THIS EXAMPLE IS NOT VALID ANYMORE, PLEASE USE !syscall OR !epthook2 COMMANDS
295 //
296 if (EptHookInlineHook(&g_GuestState[KeGetCurrentProcessorNumberEx(NULL)],
297 ApiLocationFromSSDTOfNtCreateFile,
298 (PVOID)NtCreateFileHook,
299 HANDLE_TO_UINT32(PsGetCurrentProcessId())))
300 {
301 LogInfo("Hook appkied to address of API Number : 0x%x at %llx\n", ApiNumberOfNtCreateFile, ApiLocationFromSSDTOfNtCreateFile);
302 }
303}
signed int INT32
Definition BasicTypes.h:44
BOOLEAN EptHookInlineHook(VIRTUAL_MACHINE_STATE *VCpu, PVOID TargetAddress, PVOID HookFunction, UINT32 ProcessId)
This function applies EPT hook 2 (inline) to the target EPT table.
Definition EptHook.c:1542
#define LogInfo(format,...)
Define log variables.
Definition HyperDbgHyperLogIntrinsics.h:71
#define HANDLE_TO_UINT32(_var)
Definition MetaMacros.h:39
PVOID SyscallHookGetFunctionAddress(INT32 ApiNumber, BOOLEAN GetFromWin32k)
Find entry from SSDT table of Nt functions and W32Table syscalls.
Definition SsdtHook.c:159
NTSTATUS NtCreateFileHook(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength)
Hook function that hooks NtCreateFile.
Definition SsdtHook.c:217

Variable Documentation

◆ AllocationSize

PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK PLARGE_INTEGER AllocationSize

◆ CreateDisposition

PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK PLARGE_INTEGER ULONG ULONG ULONG CreateDisposition

◆ CreateOptions

PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK PLARGE_INTEGER ULONG ULONG ULONG ULONG CreateOptions

◆ DesiredAccess

PHANDLE ACCESS_MASK DesiredAccess

◆ EaBuffer

PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK PLARGE_INTEGER ULONG ULONG ULONG ULONG PVOID EaBuffer

◆ EaLength

PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK PLARGE_INTEGER ULONG ULONG ULONG ULONG PVOID ULONG EaLength

◆ FileAttributes

PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK PLARGE_INTEGER ULONG FileAttributes

◆ FileHandle

PHANDLE FileHandle

◆ IoStatusBlock

PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK IoStatusBlock

◆ NumberOfBytes

POOL_TYPE SIZE_T NumberOfBytes

◆ ObjectAttributes

PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES ObjectAttributes

◆ PoolType

POOL_TYPE PoolType

◆ ShareAccess

PHANDLE ACCESS_MASK POBJECT_ATTRIBUTES PIO_STATUS_BLOCK PLARGE_INTEGER ULONG ULONG ShareAccess

◆ Tag

POOL_TYPE SIZE_T ULONG Tag