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

Hook headers. More...

Go to the source code of this file.

Classes

struct  _HIDDEN_HOOKS_DETOUR_DETAILS
 Details of detours style EPT hooks. 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 _HIDDEN_HOOKS_DETOUR_DETAILS HIDDEN_HOOKS_DETOUR_DETAILS
 Details of detours style EPT hooks.
typedef struct _HIDDEN_HOOKS_DETOUR_DETAILSPHIDDEN_HOOKS_DETOUR_DETAILS

Functions

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

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:52
51#define IS_SYSCALL_INSTRUCTION(Code) \
52 (*((PUINT8)(Code) + 0) == 0x0F && \
53 *((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

47#define IS_SYSRET_INSTRUCTION(Code) \
48 (*((PUINT8)(Code) + 0) == 0x48 && \
49 *((PUINT8)(Code) + 1) == 0x0F && \
50 *((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

Function Documentation

◆ EptHook()

BOOLEAN EptHook ( PVOID TargetAddress,
UINT32 ProcessId )

Hook in VMX non-root Mode (hidden breakpoint).

This function invokes a VMCALL to set the hook and broadcast the exiting for the breakpoints on exception bitmap.

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
621{
622 //
623 // Should be called from vmx non-root
624 //
626 {
627 return FALSE;
628 }
629
630 return EptHookPerformHook(TargetAddress, ProcessId, FALSE);
631}
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:548
BOOLEAN VmxGetCurrentExecutionMode()
Check current execution mode (vmx-root and non-root).
Definition Vmx.c:76
#define TRUE
Definition BasicTypes.h:114
#define FALSE
Definition BasicTypes.h:113

◆ EptHook2GeneralDetourEventHandler()

PVOID EptHook2GeneralDetourEventHandler ( PGUEST_REGS Regs,
PVOID CalledFrom )

routines to generally handle breakpoint hit for detour

Parameters
Regs
CalledFrom
Returns
PVOID
2504{
2505 PLIST_ENTRY TempList = 0;
2506 EPT_HOOKS_CONTEXT TempContext = {0};
2507
2508 //
2509 // The RSP register is the at the RCX and we just added (reverse by stack) to it's
2510 // values by the size of the GUEST_REGS
2511 //
2512 Regs->rsp = (UINT64)Regs - sizeof(GUEST_REGS);
2513
2514 //
2515 // test
2516 //
2517
2518 //
2519 // LogInfo("Hidden Hooked function Called with : rcx = 0x%llx , rdx = 0x%llx , r8 = 0x%llx , r9 = 0x%llx",
2520 // Regs->rcx,
2521 // Regs->rdx,
2522 // Regs->r8,
2523 // Regs->r9);
2524 //
2525
2526 //
2527 // Create temporary context
2528 //
2529 TempContext.VirtualAddress = (UINT64)CalledFrom;
2530 TempContext.PhysicalAddress = VirtualAddressToPhysicalAddress(CalledFrom);
2531
2532 //
2533 // Create a temporary VCpu
2534 //
2535 VIRTUAL_MACHINE_STATE * VCpu = &g_GuestState[KeGetCurrentProcessorNumberEx(NULL)];
2536
2537 //
2538 // Set the register for the temporary VCpu
2539 //
2540 VCpu->Regs = Regs;
2541
2542 //
2543 // As the context to event trigger, we send the address of function
2544 // which is current hidden hook is triggered for it
2545 //
2546 DispatchEventHiddenHookExecDetours(VCpu, &TempContext);
2547
2548 //
2549 // Iterate through the list of hooked pages details to find
2550 // and return where want to jump after this functions
2551 //
2552 TempList = &g_EptHook2sDetourListHead;
2553
2554 while (&g_EptHook2sDetourListHead != TempList->Flink)
2555 {
2556 TempList = TempList->Flink;
2557 PHIDDEN_HOOKS_DETOUR_DETAILS CurrentHookedDetails = CONTAINING_RECORD(TempList, HIDDEN_HOOKS_DETOUR_DETAILS, OtherHooksList);
2558
2559 if (CurrentHookedDetails->HookedFunctionAddress == CalledFrom)
2560 {
2561 return CurrentHookedDetails->ReturnAddress;
2562 }
2563 }
2564
2565 //
2566 // If we reach here, means that we didn't find the return address
2567 // that's an error, generally we can't do anything but as the user
2568 // might already cleaned the hook and the structures are removed
2569 // so we just return the original caller address and continue the
2570 // guest normally
2571 //
2572 return CalledFrom;
2573}
VOID DispatchEventHiddenHookExecDetours(VIRTUAL_MACHINE_STATE *VCpu, PVOID Context)
Handling debugger functions related to hidden hook exec detours events.
Definition Dispatch.c:1063
struct _HIDDEN_HOOKS_DETOUR_DETAILS * PHIDDEN_HOOKS_DETOUR_DETAILS
struct _HIDDEN_HOOKS_DETOUR_DETAILS HIDDEN_HOOKS_DETOUR_DETAILS
Details of detours style EPT hooks.
struct _EPT_HOOKS_CONTEXT EPT_HOOKS_CONTEXT
Temporary $context used in some EPT hook commands.
IMPORT_EXPORT_VMM UINT64 VirtualAddressToPhysicalAddress(_In_ PVOID VirtualAddress)
Converts Virtual Address to Physical Address.
Definition Conversion.c:154
struct _VIRTUAL_MACHINE_STATE VIRTUAL_MACHINE_STATE
The status of each core after and before VMX.
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:56
#define CONTAINING_RECORD(address, type, field)
Definition nt-list.h:36
UINT64 VirtualAddress
Definition DataTypes.h:372
UINT64 PhysicalAddress
Definition DataTypes.h:371
PVOID HookedFunctionAddress
Definition Hooks.h:25
PVOID ReturnAddress
Definition Hooks.h:26
GUEST_REGS * Regs
Definition State.h:326
Definition BasicTypes.h:136
UINT64 rsp
Definition BasicTypes.h:145

◆ 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}
BOOLEAN PoolManagerCallbackRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention)
routine callback to request pool allocation
Definition Callback.c:335
struct _VMM_EPT_DYNAMIC_SPLIT VMM_EPT_DYNAMIC_SPLIT
Split 2MB granularity to 4 KB granularity.
unsigned long ULONG
Definition BasicTypes.h:31
@ SPLIT_2MB_PAGING_TO_4KB_PAGE
Definition DataTypes.h:76
@ TRACKING_HOOKED_PAGES
Definition DataTypes.h:74
struct _EPT_HOOKED_PAGE_DETAIL EPT_HOOKED_PAGE_DETAIL
Structure to save the state of each hooked pages.

◆ 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
647{
648 //
649 // Should be called from VMX root-mode
650 //
652 {
653 return FALSE;
654 }
655
656 return EptHookPerformHook(TargetAddress, NULL_ZERO, TRUE);
657}
#define NULL_ZERO
Definition BasicTypes.h:110

◆ 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
1886{
1887 UINT32 Count = 0;
1888
1889 LIST_FOR_EACH_LINK(g_EptState->HookedPagesList, EPT_HOOKED_PAGE_DETAIL, PageHookList, HookedEntry)
1890 {
1891 if (IsEptHook2)
1892 {
1893 if (HookedEntry->IsHiddenBreakpoint == FALSE)
1894 {
1895 Count++;
1896 }
1897 }
1898 else
1899 {
1900 if (HookedEntry->IsHiddenBreakpoint == TRUE)
1901 {
1902 Count++;
1903 }
1904 }
1905 }
1906
1907 return Count;
1908}
#define LIST_FOR_EACH_LINK(_head, _struct_type, _member, _var)
Definition MetaMacros.h:34
unsigned int UINT32
Definition BasicTypes.h:54
EPT_STATE * g_EptState
Save the state and variables related to EPT.
Definition GlobalVariables.h:50

◆ 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.

Handles page hooks (trigger events).

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
1713{
1714 UINT64 ExactAccessedVirtualAddress;
1715 UINT64 AlignedVirtualAddress;
1716 UINT64 AlignedPhysicalAddress;
1717 BOOLEAN IsTriggeringPostEventAllowed = FALSE;
1718
1719 //
1720 // Get alignment
1721 //
1722 AlignedVirtualAddress = (UINT64)PAGE_ALIGN(HookedEntryDetails->VirtualAddress);
1723 AlignedPhysicalAddress = (UINT64)PAGE_ALIGN(PhysicalAddress);
1724
1725 //
1726 // Let's read the exact address that was accessed
1727 //
1728 ExactAccessedVirtualAddress = AlignedVirtualAddress + PhysicalAddress - AlignedPhysicalAddress;
1729
1730 //
1731 // Set the last context
1732 //
1733 LastContext->HookingTag = HookedEntryDetails->HookingTag;
1734 LastContext->PhysicalAddress = PhysicalAddress;
1735 LastContext->VirtualAddress = ExactAccessedVirtualAddress;
1736
1737 if (!ViolationQualification.EptReadable && ViolationQualification.ReadAccess)
1738 {
1739 //
1740 // LogInfo("Guest RIP : 0x%llx tries to read the page at : 0x%llx", GuestRip, ExactAccessedAddress);
1741 //
1742
1743 //
1744 // Set last violation
1745 //
1746 HookedEntryDetails->LastViolation = EPT_HOOKED_LAST_VIOLATION_READ;
1747
1748 //
1749 // Trigger the event related to Monitor Read and Monitor Read & Write and
1750 // Monitor Read & Execute and Monitor Read & Write & Execute
1751 //
1752 *IgnoreReadOrWriteOrExec = DispatchEventHiddenHookPageReadWriteExecuteReadPreEvent(VCpu, LastContext, &IsTriggeringPostEventAllowed);
1753
1754 //
1755 // It's not an execution violation
1756 //
1757 *IsExecViolation = FALSE;
1758 }
1759 else if (!ViolationQualification.EptWriteable && ViolationQualification.WriteAccess)
1760 {
1761 //
1762 // LogInfo("Guest RIP : 0x%llx tries to write on the page at : 0x%llx", GuestRip, ExactAccessedAddress);
1763 //
1764
1765 //
1766 // Set last violation
1767 //
1768 HookedEntryDetails->LastViolation = EPT_HOOKED_LAST_VIOLATION_WRITE;
1769
1770 //
1771 // Trigger the event related to Monitor Write and Monitor Read & Write and
1772 // Monitor Write & Execute and Monitor Read & Write & Execute
1773 //
1774 *IgnoreReadOrWriteOrExec = DispatchEventHiddenHookPageReadWriteExecuteWritePreEvent(VCpu, LastContext, &IsTriggeringPostEventAllowed);
1775
1776 //
1777 // It's not an execution violation
1778 //
1779 *IsExecViolation = FALSE;
1780 }
1781 else if (!ViolationQualification.EptExecutable && ViolationQualification.ExecuteAccess)
1782 {
1783 //
1784 // LogInfo("Guest RIP : 0x%llx tries to execute the page at : 0x%llx", GuestRip, ExactAccessedAddress);
1785 //
1786
1787 //
1788 // Set last violation
1789 //
1790 HookedEntryDetails->LastViolation = EPT_HOOKED_LAST_VIOLATION_EXEC;
1791
1792 //
1793 // Trigger the event related to Monitor Execute and Monitor Read & Execute and
1794 // Monitor Write & Execute and Monitor Read & Write & Execute
1795 //
1796 *IgnoreReadOrWriteOrExec = DispatchEventHiddenHookPageReadWriteExecuteExecutePreEvent(VCpu, LastContext, &IsTriggeringPostEventAllowed);
1797
1798 //
1799 // It's an execution violation
1800 //
1801 *IsExecViolation = TRUE;
1802 }
1803 else
1804 {
1805 //
1806 // triggering post event is not allowed as it's not valid
1807 //
1808 HookedEntryDetails->IsPostEventTriggerAllowed = FALSE;
1809
1810 //
1811 // there was an unexpected ept violation
1812 //
1813 return FALSE;
1814 }
1815
1816 //
1817 // Set whether the post event trigger is allowed or not
1818 // If only one event short-circuit a special EPT hook the 'post' mode will be ignored for all of the same events
1819 //
1820 if (*IgnoreReadOrWriteOrExec == FALSE)
1821 {
1822 HookedEntryDetails->IsPostEventTriggerAllowed = IsTriggeringPostEventAllowed;
1823 }
1824 else
1825 {
1826 //
1827 // Ignoring read/write/exec will remove the 'post' event
1828 //
1829 HookedEntryDetails->IsPostEventTriggerAllowed = FALSE;
1830 }
1831
1832 //
1833 // Means that restore the Entry to the previous state after current
1834 // instruction executed in the guest
1835 //
1836 return TRUE;
1837}
BOOLEAN DispatchEventHiddenHookPageReadWriteExecuteWritePreEvent(VIRTUAL_MACHINE_STATE *VCpu, PVOID Context, BOOLEAN *IsTriggeringPostEventAllowed)
Handling debugger functions related to read & write & execute, write events (pre).
Definition Dispatch.c:1181
BOOLEAN DispatchEventHiddenHookPageReadWriteExecuteExecutePreEvent(VIRTUAL_MACHINE_STATE *VCpu, PVOID Context, BOOLEAN *IsTriggeringPostEventAllowed)
Handling debugger functions related to read & write & execute, execute events (pre).
Definition Dispatch.c:1275
BOOLEAN DispatchEventHiddenHookPageReadWriteExecuteReadPreEvent(VIRTUAL_MACHINE_STATE *VCpu, PVOID Context, BOOLEAN *IsTriggeringPostEventAllowed)
Handling debugger functions related to read & write & execute, read events (pre).
Definition Dispatch.c:1087
UCHAR BOOLEAN
Definition BasicTypes.h:35
@ EPT_HOOKED_LAST_VIOLATION_READ
Definition State.h:65
@ EPT_HOOKED_LAST_VIOLATION_EXEC
Definition State.h:67
@ EPT_HOOKED_LAST_VIOLATION_WRITE
Definition State.h:66
#define PAGE_ALIGN(Va)
Aligning a page.
Definition common.h:86
UINT64 VirtualAddress
The virtual address from the caller perspective view (cr3).
Definition State.h:191
UINT64 HookingTag
Tag used for notifying the caller.
Definition State.h:218
BOOLEAN IsPostEventTriggerAllowed
This field shows whether the hook should call the post event trigger after restoring the state or not...
Definition State.h:269
EPT_HOOKED_LAST_VIOLATION LastViolation
This field shows the last violation happened to this EPT hook.
Definition State.h:274
UINT64 HookingTag
Definition DataTypes.h:370

◆ 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
1984{
1985 PVOID TargetPage;
1986 //
1987 // Pointer to the page entry in the page table
1988 //
1990
1991 //
1992 // restore the hooked state
1993 //
1995 TargetPage,
1997 InveptSingleContext);
1998
1999 //
2000 // Check to trigger the post event (for events relating the !monitor command
2001 // and the emulation hardware debug registers)
2002 //
2004 {
2006 {
2007 //
2008 // This is a "read" hook
2009 //
2012 }
2014 {
2015 //
2016 // This is a "write" hook
2017 //
2020 }
2022 {
2023 //
2024 // This is a "execute" hook
2025 //
2028 }
2029 }
2030
2031 //
2032 // Check for user-mode attaching mechanisms and callback
2033 // (we call it here, because this callback might change the EPTP entries and invalidate EPTP)
2034 //
2036}
BOOLEAN VmmCallbackRestoreEptState(UINT32 CoreId)
routine callback to restore EPT state
Definition Callback.c:145
VOID DispatchEventHiddenHookPageReadWriteExecReadPostEvent(VIRTUAL_MACHINE_STATE *VCpu, PVOID Context)
Handling debugger functions related to read & write & execute, read events (post).
Definition Dispatch.c:1368
VOID DispatchEventHiddenHookPageReadWriteExecWritePostEvent(VIRTUAL_MACHINE_STATE *VCpu, PVOID Context)
Handling debugger functions related to read & write & execute, write events (post).
Definition Dispatch.c:1415
VOID DispatchEventHiddenHookPageReadWriteExecExecutePostEvent(VIRTUAL_MACHINE_STATE *VCpu, PVOID Context)
Handling debugger functions related to read & write & execute, execute events (post).
Definition Dispatch.c:1460
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:337
_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:1181
void * PVOID
Definition BasicTypes.h:56
EPT_HOOKS_CONTEXT LastContextState
Temporary context for the post event monitors It shows the context of the last address that triggered...
Definition State.h:263
EPT_PML1_ENTRY ChangedEntry
The original page entry. Will be copied back when the hook is remove from the page.
Definition State.h:235
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:203
PVMM_EPT_PAGE_TABLE EptPageTable
Definition State.h:364
PEPT_HOOKED_PAGE_DETAIL MtfEptHookRestorePoint
Definition State.h:353
UINT32 CoreId
Definition State.h:328

◆ EptHookInlineHook()

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

Hook in VMX non-root mode (hidden detours).

This function applies EPT hook 2 (inline) to the target EPT table.

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
1566{
1567 EPT_HOOKS_ADDRESS_DETAILS_FOR_EPTHOOK2 HookingDetail = {0};
1568
1569 //
1570 // Should be called from vmx non-root
1571 //
1573 {
1574 return FALSE;
1575 }
1576
1577 //
1578 // Set the hooking details
1579 //
1580 HookingDetail.TargetAddress = TargetAddress;
1581 HookingDetail.HookFunction = HookFunction;
1582
1584 &HookingDetail,
1585 NULL,
1586 ProcessId,
1587 TRUE,
1588 FALSE);
1589}
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:1390
struct _EPT_HOOKS_ADDRESS_DETAILS_FOR_EPTHOOK2 EPT_HOOKS_ADDRESS_DETAILS_FOR_EPTHOOK2
Setting details for EPT Hooks (!epthook2).
PVOID HookFunction
Definition DataTypes.h:398
PVOID TargetAddress
Definition DataTypes.h:397

◆ EptHookInlineHookFromVmxRoot()

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

Hook in VMX root-mode (hidden detours).

This function applies EPT inline to the target EPT table.

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
1636{
1637 EPT_HOOKS_ADDRESS_DETAILS_FOR_EPTHOOK2 HookingDetail = {0};
1638
1639 //
1640 // Should be called from vmx root-mode
1641 //
1643 {
1644 return FALSE;
1645 }
1646
1647 //
1648 // Configure the details
1649 //
1650 HookingDetail.TargetAddress = TargetAddress;
1651 HookingDetail.HookFunction = HookFunction;
1652
1654 &HookingDetail,
1655 NULL,
1656 NULL_ZERO,
1657 TRUE,
1658 TRUE);
1659}

◆ 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
2589{
2590 PVOID PmlEntry = NULL;
2591 BOOLEAN IsLargePage = FALSE;
2592
2593 PmlEntry = EptGetPml1OrPml2Entry(VCpu->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
2594
2595 if (PmlEntry)
2596 {
2597 if (IsLargePage)
2598 {
2599 if (IsUnset)
2600 {
2601 ((PEPT_PML2_ENTRY)PmlEntry)->ExecuteAccess = FALSE;
2602 }
2603 else
2604 {
2605 ((PEPT_PML2_ENTRY)PmlEntry)->ExecuteAccess = TRUE;
2606 }
2607 }
2608 else
2609 {
2610 if (IsUnset)
2611 {
2612 ((PEPT_PML1_ENTRY)PmlEntry)->ExecuteAccess = FALSE;
2613 }
2614 else
2615 {
2616 ((PEPT_PML1_ENTRY)PmlEntry)->ExecuteAccess = TRUE;
2617 }
2618 }
2619 }
2620 else
2621 {
2622 return FALSE;
2623 }
2624
2625 //
2626 // Invalidate the EPTP (single-context)
2627 //
2628 EptInveptSingleContext(VCpu->EptPointer.AsUInt);
2629
2630 return TRUE;
2631}
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:394
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:23
EPT_PDE_2MB * PEPT_PML2_ENTRY
Definition State.h:21
NULL()
Definition test-case-generator.py:530
EPT_POINTER EptPointer
Definition State.h:363

◆ 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
2647{
2648 PVOID PmlEntry = NULL;
2649 BOOLEAN IsLargePage = FALSE;
2650
2651 PmlEntry = EptGetPml1OrPml2Entry(VCpu->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
2652
2653 if (PmlEntry)
2654 {
2655 if (IsLargePage)
2656 {
2657 if (IsUnset)
2658 {
2659 ((PEPT_PML2_ENTRY)PmlEntry)->ReadAccess = FALSE;
2660 }
2661 else
2662 {
2663 ((PEPT_PML2_ENTRY)PmlEntry)->ReadAccess = TRUE;
2664 }
2665 }
2666 else
2667 {
2668 if (IsUnset)
2669 {
2670 ((PEPT_PML1_ENTRY)PmlEntry)->ReadAccess = FALSE;
2671 }
2672 else
2673 {
2674 ((PEPT_PML1_ENTRY)PmlEntry)->ReadAccess = TRUE;
2675 }
2676 }
2677 }
2678 else
2679 {
2680 return FALSE;
2681 }
2682
2683 //
2684 // Invalidate the EPTP (single-context)
2685 //
2686 EptInveptSingleContext(VCpu->EptPointer.AsUInt);
2687
2688 return TRUE;
2689}

◆ 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
2705{
2706 PVOID PmlEntry = NULL;
2707 BOOLEAN IsLargePage = FALSE;
2708
2709 PmlEntry = EptGetPml1OrPml2Entry(VCpu->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
2710
2711 if (PmlEntry)
2712 {
2713 if (IsLargePage)
2714 {
2715 if (IsUnset)
2716 {
2717 ((PEPT_PML2_ENTRY)PmlEntry)->WriteAccess = FALSE;
2718 }
2719 else
2720 {
2721 ((PEPT_PML2_ENTRY)PmlEntry)->WriteAccess = TRUE;
2722 }
2723 }
2724 else
2725 {
2726 if (IsUnset)
2727 {
2728 ((PEPT_PML1_ENTRY)PmlEntry)->WriteAccess = FALSE;
2729 }
2730 else
2731 {
2732 ((PEPT_PML1_ENTRY)PmlEntry)->WriteAccess = TRUE;
2733 }
2734 }
2735 }
2736 else
2737 {
2738 return FALSE;
2739 }
2740
2741 //
2742 // Invalidate the EPTP (single-context)
2743 //
2744 EptInveptSingleContext(VCpu->EptPointer.AsUInt);
2745
2746 return TRUE;
2747}

◆ 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
1673{
1674 //
1675 // Should be called from vmx root-mode
1676 //
1678 {
1679 return FALSE;
1680 }
1681
1683 NULL,
1684 MemoryAddressDetails,
1685 NULL_ZERO,
1686 FALSE,
1687 TRUE);
1688}

◆ 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
1605{
1606 //
1607 // Should be called from vmx non-root
1608 //
1610 {
1611 return FALSE;
1612 }
1613
1615 NULL,
1616 HookingDetails,
1617 ProcessId,
1618 FALSE,
1619 FALSE);
1620}

◆ 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).

The main function that performs EPT page hook with hidden breakpoint.

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
483{
484 SIZE_T PhysicalBaseAddress;
485 PVOID VirtualTarget;
486 EPT_HOOKED_PAGE_DETAIL * HookedEntry = NULL;
487
488 //
489 // Translate the page from a physical address to virtual so we can read its memory.
490 // This function will return NULL if the physical address was not already mapped in
491 // virtual memory.
492 //
493 VirtualTarget = PAGE_ALIGN(TargetAddress);
494
495 //
496 // Here we have to change the CR3, it is because we are in SYSTEM process
497 // and if the target address is not mapped in SYSTEM address space (e.g
498 // user mode address of another process) then the translation is invalid
499 //
500
501 //
502 // Find cr3 of target core
503 //
504 PhysicalBaseAddress = (SIZE_T)VirtualAddressToPhysicalAddressByProcessCr3(VirtualTarget, ProcessCr3);
505
506 if (!PhysicalBaseAddress)
507 {
509 return FALSE;
510 }
511
512 //
513 // Check if the physical address is bigger than 512 GB
514 //
515 if (PhysicalBaseAddress >= SIZE_512_GB)
516 {
518 return FALSE;
519 }
520
521 //
522 // try to see if we can find the address
523 //
524
525 HookedEntry = EptHookFindByPhysAddress(PhysicalBaseAddress);
526
527 if (HookedEntry != NULL)
528 {
529 return EptHookUpdateHookPage(TargetAddress, HookedEntry);
530 }
531 else
532 {
533 return EptHookCreateHookPage(VCpu, TargetAddress, ProcessCr3);
534 }
535}
VOID VmmCallbackSetLastError(UINT32 LastError)
routine callback to set last error
Definition Callback.c:47
#define SIZE_512_GB
Integer 512GB.
Definition Ept.h:43
#define DEBUGGER_ERROR_CANNOT_PUT_EPT_HOOKS_ON_PHYSICAL_ADDRESS_ABOVE_512_GB
error, cannot put EPT hooks on addresses above 512 GB
Definition ErrorCodes.h:564
#define DEBUGGER_ERROR_INVALID_ADDRESS
error, invalid address specified for debugger
Definition ErrorCodes.h:63
IMPORT_EXPORT_VMM UINT64 VirtualAddressToPhysicalAddressByProcessCr3(_In_ PVOID VirtualAddress, _In_ CR3_TYPE TargetCr3)

◆ 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).

The main function that performs EPT page hook with hidden detours and monitor.

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
999{
1000 ULONG ProcessorsCount;
1001 EPT_PML1_ENTRY ChangedEntry;
1002 SIZE_T PhysicalBaseAddress;
1003 PVOID AlignedTargetVaOrPa;
1004 PVOID TargetAddress;
1005 PVOID HookFunction;
1006 UINT64 TargetAddressInSafeMemory;
1007 PEPT_PML1_ENTRY TargetPage;
1008 PEPT_HOOKED_PAGE_DETAIL HookedPage;
1009 CR3_TYPE Cr3OfCurrentProcess;
1010 PLIST_ENTRY TempList = 0;
1011 PEPT_HOOKED_PAGE_DETAIL HookedEntry = NULL;
1012 BOOLEAN UnsetExecute = FALSE;
1013 BOOLEAN UnsetRead = FALSE;
1014 BOOLEAN UnsetWrite = FALSE;
1015 BOOLEAN EptHiddenHook = FALSE;
1016
1017 UnsetRead = (PageHookMask & PAGE_ATTRIB_READ) ? TRUE : FALSE;
1018 UnsetWrite = (PageHookMask & PAGE_ATTRIB_WRITE) ? TRUE : FALSE;
1019 UnsetExecute = (PageHookMask & PAGE_ATTRIB_EXEC) ? TRUE : FALSE;
1020 EptHiddenHook = (PageHookMask & PAGE_ATTRIB_EXEC_HIDDEN_HOOK) ? TRUE : FALSE;
1021
1022 //
1023 // Get number of processors
1024 //
1025 ProcessorsCount = KeQueryActiveProcessorCount(0);
1026
1027 //
1028 // Translate the page from a physical address to virtual so we can read its memory.
1029 // This function will return NULL if the physical address was not already mapped in
1030 // virtual memory.
1031 //
1032 if (EptHiddenHook)
1033 {
1034 TargetAddress = ((EPT_HOOKS_ADDRESS_DETAILS_FOR_EPTHOOK2 *)HookingDetails)->TargetAddress;
1035 }
1036 else
1037 {
1038 TargetAddress = (PVOID)((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->StartAddress;
1039 }
1040
1041 AlignedTargetVaOrPa = PAGE_ALIGN(TargetAddress);
1042
1043 //
1044 // Here we have to change the CR3, it is because we are in SYSTEM process
1045 // and if the target address is not mapped in SYSTEM address space (e.g
1046 // user mode address of another process) then the translation is invalid
1047 //
1048
1049 if (!EptHiddenHook &&
1051 {
1052 //
1053 // The address itself is a physical address, no need for conversion
1054 //
1055 PhysicalBaseAddress = (SIZE_T)AlignedTargetVaOrPa;
1056 }
1057 else
1058 {
1059 //
1060 // based on the CR3 of target core
1061 //
1062 PhysicalBaseAddress = (SIZE_T)VirtualAddressToPhysicalAddressByProcessCr3(AlignedTargetVaOrPa, ProcessCr3);
1063 }
1064
1065 //
1066 // Check if the physical address is valid
1067 //
1068 if (!PhysicalBaseAddress)
1069 {
1071 return FALSE;
1072 }
1073
1074 //
1075 // Check if the physical address is bigger than 512 GB
1076 //
1077 if (PhysicalBaseAddress >= SIZE_512_GB)
1078 {
1080 return FALSE;
1081 }
1082
1083 //
1084 // try to see if we can find the address
1085 //
1086 TempList = &g_EptState->HookedPagesList;
1087
1088 while (&g_EptState->HookedPagesList != TempList->Flink)
1089 {
1090 TempList = TempList->Flink;
1091 HookedEntry = CONTAINING_RECORD(TempList, EPT_HOOKED_PAGE_DETAIL, PageHookList);
1092
1093 if (HookedEntry->PhysicalBaseAddress == PhysicalBaseAddress)
1094 {
1095 //
1096 // Means that we find the address and !epthook2 doesn't support
1097 // multiple breakpoints in on page
1098 //
1100 return FALSE;
1101 }
1102 }
1103
1104 //
1105 // Save the detail of hooked page to keep track of it
1106 //
1108
1109 if (!HookedPage)
1110 {
1112 return FALSE;
1113 }
1114
1115 //
1116 // Save the virtual address
1117 //
1118 HookedPage->VirtualAddress = (UINT64)TargetAddress;
1119
1120 //
1121 // Save the physical address
1122 //
1123 HookedPage->PhysicalBaseAddress = PhysicalBaseAddress;
1124
1125 //
1126 // If it's a monitor hook, then we need to hold the address of the start
1127 // physical address as well as the end physical address, plus tagging information
1128 //
1129 if (!EptHiddenHook)
1130 {
1131 //
1132 // Save the target tag
1133 //
1134 HookedPage->HookingTag = ((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->Tag;
1135
1136 //
1137 // Save the start of the target physical address
1138 //
1140 {
1141 //
1142 // Physical address
1143 //
1144 HookedPage->StartOfTargetPhysicalAddress = (SIZE_T)(((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->StartAddress);
1145 }
1146 else
1147 {
1148 //
1149 // Virtual address
1150 //
1152 (PVOID)(((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->StartAddress),
1153 ProcessCr3);
1154 }
1155
1156 if (!HookedPage->StartOfTargetPhysicalAddress)
1157 {
1158 PoolManagerCallbackFreePool((UINT64)HookedPage);
1159
1161 return FALSE;
1162 }
1163
1164 //
1165 // Save the end of the target physical address
1166 //
1168 {
1169 //
1170 // Physical address
1171 //
1172 HookedPage->EndOfTargetPhysicalAddress = (SIZE_T)(((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->EndAddress);
1173 }
1174 else
1175 {
1176 //
1177 // Virtual address
1178 //
1180 (PVOID)(((EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR *)HookingDetails)->EndAddress),
1181 ProcessCr3);
1182 }
1183
1184 if (!HookedPage->EndOfTargetPhysicalAddress)
1185 {
1186 PoolManagerCallbackFreePool((UINT64)HookedPage);
1187
1189 return FALSE;
1190 }
1191 }
1192
1193 //
1194 // Fake page content physical address
1195 //
1197
1198 if (EptHiddenHook)
1199 {
1200 //
1201 // Show that entry has hidden hooks for execution
1202 //
1203 HookedPage->IsExecutionHook = TRUE;
1204
1205 //
1206 // Switch to target process
1207 //
1208 Cr3OfCurrentProcess = SwitchToProcessMemoryLayoutByCr3(ProcessCr3);
1209
1210 //
1211 // Copy the content to the fake page
1212 // The following line can't be used in user mode addresses
1213 // RtlCopyBytes(&HookedPage->FakePageContents, VirtualTarget, PAGE_SIZE);
1214 //
1215 MemoryMapperReadMemorySafe((UINT64)AlignedTargetVaOrPa, &HookedPage->FakePageContents, PAGE_SIZE);
1216
1217 //
1218 // Restore to original process
1219 //
1220 SwitchToPreviousProcess(Cr3OfCurrentProcess);
1221
1222 //
1223 // Compute new offset of target offset into a safe bufferr
1224 // It will be used to compute the length of the detours
1225 // address because we might have a user mode code
1226 //
1227 TargetAddressInSafeMemory = EptHookCalcBreakpointOffset(TargetAddress, HookedPage);
1228
1229 //
1230 // Make sure if handler function is valid or if it's default
1231 // then we set it to the default handler
1232 //
1233 if (((EPT_HOOKS_ADDRESS_DETAILS_FOR_EPTHOOK2 *)HookingDetails)->HookFunction == NULL)
1234 {
1235 HookFunction = (PVOID)AsmGeneralDetourHook;
1236 }
1237 else
1238 {
1239 HookFunction = ((EPT_HOOKS_ADDRESS_DETAILS_FOR_EPTHOOK2 *)HookingDetails)->HookFunction;
1240 }
1241
1242 //
1243 // Create Hook
1244 //
1245 if (!EptHookInstructionMemory(HookedPage, ProcessCr3, TargetAddress, (PVOID)TargetAddressInSafeMemory, HookFunction))
1246 {
1247 PoolManagerCallbackFreePool((UINT64)HookedPage);
1248
1250 return FALSE;
1251 }
1252 }
1253
1254 for (SIZE_T i = 0; i < ProcessorsCount; i++)
1255 {
1256 //
1257 // We need to split the large page to 4KB page using pre-allocated pools
1258 //
1259 if (!EptSplitLargePage(g_GuestState[i].EptPageTable, TRUE, PhysicalBaseAddress))
1260 {
1261 PoolManagerCallbackFreePool((UINT64)HookedPage);
1262
1263 //
1264 // Here also other previous pools should be specified, but we forget it for now
1265 //
1266 LogDebugInfo("Err, could not split page for the address : 0x%llx", PhysicalBaseAddress);
1268 return FALSE;
1269 }
1270
1271 //
1272 // Pointer to the page entry in the page table
1273 //
1274 TargetPage = EptGetPml1Entry(g_GuestState[i].EptPageTable, PhysicalBaseAddress);
1275
1276 //
1277 // Ensure the target is valid
1278 //
1279 if (!TargetPage)
1280 {
1281 PoolManagerCallbackFreePool((UINT64)HookedPage);
1282
1283 //
1284 // Here also other previous pools should be specified, but we forget it for now
1285 //
1286
1288 return FALSE;
1289 }
1290
1291 //
1292 // Save the original entry (only one of the page tables as the base original entry
1293 // is enough)
1294 //
1295 HookedPage->OriginalEntry = *TargetPage;
1296
1297 //
1298 // Save the original permissions of the page
1299 //
1300 ChangedEntry = *TargetPage;
1301
1302 //
1303 // Execution is treated differently
1304 //
1305 if (UnsetRead)
1306 ChangedEntry.ReadAccess = 0;
1307 else
1308 ChangedEntry.ReadAccess = 1;
1309
1310 if (UnsetWrite)
1311 ChangedEntry.WriteAccess = 0;
1312 else
1313 ChangedEntry.WriteAccess = 1;
1314
1315 if (UnsetExecute)
1316 ChangedEntry.ExecuteAccess = 0;
1317 else
1318 ChangedEntry.ExecuteAccess = 1;
1319
1320 //
1321 // If it's Execution hook then we have to set extra fields
1322 //
1323 if (EptHiddenHook)
1324 {
1325 //
1326 // In execution hook, we have to make sure to unset read, write because
1327 // an EPT violation should occur for these cases and we can swap the original page
1328 //
1329 ChangedEntry.ReadAccess = 0;
1330 ChangedEntry.WriteAccess = 0;
1331 ChangedEntry.ExecuteAccess = 1;
1332
1333 //
1334 // Also set the current pfn to fake page
1335 //
1336 ChangedEntry.PageFrameNumber = HookedPage->PhysicalBaseAddressOfFakePageContents;
1337 }
1338
1339 //
1340 // Only for the first time execution of the loop, we save these details,
1341 // it is because after this condition, the hook is applied and by applying
1342 // the hook, we have to make sure that the address is saved g_EptState->HookedPagesList
1343 // because the hook might be simultaneously triggered from other cores
1344 //
1345 if (i == 0)
1346 {
1347 //
1348 // Save the modified entry
1349 //
1350 HookedPage->ChangedEntry = ChangedEntry;
1351
1352 //
1353 // Add it to the list
1354 //
1355 InsertHeadList(&g_EptState->HookedPagesList, &(HookedPage->PageHookList));
1356 }
1357
1358 //
1359 // Apply the hook to EPT
1360 //
1361 TargetPage->AsUInt = ChangedEntry.AsUInt;
1362
1363 //
1364 // If it's the current core then we invalidate the EPT
1365 //
1366 if (VCpu->CoreId == i && g_GuestState[i].HasLaunched)
1367 {
1368 EptInveptSingleContext(VCpu->EptPointer.AsUInt);
1369 }
1370 }
1371
1372 return TRUE;
1373}
BOOLEAN PoolManagerCallbackFreePool(UINT64 AddressToFree)
routine callback to free pool
Definition Callback.c:378
UINT64 PoolManagerCallbackRequestPool(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size)
routine callback to request pool
Definition Callback.c:358
BOOLEAN EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable, BOOLEAN UsePreAllocatedBuffer, SIZE_T PhysicalAddress)
Convert large pages to 4KB pages.
Definition Ept.c:481
#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:849
VOID AsmGeneralDetourHook(VOID)
Detour hook handler.
struct _CR3_TYPE CR3_TYPE
CR3 Structure.
@ DEBUGGER_MEMORY_HOOK_PHYSICAL_ADDRESS
Definition DataTypes.h:361
struct _EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR EPT_HOOKS_ADDRESS_DETAILS_FOR_MEMORY_MONITOR
Setting details for EPT Hooks (!monitor).
#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
IMPORT_EXPORT_VMM VOID SwitchToPreviousProcess(_In_ CR3_TYPE PreviousProcess)
IMPORT_EXPORT_VMM BOOLEAN MemoryMapperReadMemorySafe(_In_ UINT64 VaAddressToRead, _Inout_ PVOID BufferToSaveMemory, _In_ SIZE_T SizeToRead)
IMPORT_EXPORT_VMM CR3_TYPE SwitchToProcessMemoryLayoutByCr3(_In_ CR3_TYPE TargetCr3)
struct _EPT_HOOKED_PAGE_DETAIL * PEPT_HOOKED_PAGE_DETAIL
EPT_PTE EPT_PML1_ENTRY
Definition State.h:23
#define PAGE_SIZE
Size of each page (4096 bytes).
Definition common.h:80
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:224
BOOLEAN IsExecutionHook
This field shows whether the hook contains a hidden hook for execution or not.
Definition State.h:245
LIST_ENTRY PageHookList
Linked list entries for each page hook.
Definition State.h:186
CHAR FakePageContents[PAGE_SIZE]
Definition State.h:181
SIZE_T EndOfTargetPhysicalAddress
End address of the target physical address.
Definition State.h:213
SIZE_T StartOfTargetPhysicalAddress
Start address of the target physical address.
Definition State.h:208
EPT_PML1_ENTRY OriginalEntry
The original page entry. Will be copied back when the hook is removed from the page.
Definition State.h:230

◆ EptHookRemoveEntryAndFreePoolFromEptHook2sDetourList()

BOOLEAN EptHookRemoveEntryAndFreePoolFromEptHook2sDetourList ( UINT64 Address)

Remove an entry from g_EptHook2sDetourListHead.

Remove the entry from g_EptHook2sDetourListHead in the case of !epthook2 details.

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
1847{
1848 //
1849 // Iterate through the list of hooked pages details to find
1850 // the entry in the list
1851 //
1852 LIST_FOR_EACH_LINK(g_EptHook2sDetourListHead, HIDDEN_HOOKS_DETOUR_DETAILS, OtherHooksList, CurrentHookedDetails)
1853 {
1854 if (CurrentHookedDetails->HookedFunctionAddress == (PVOID)Address)
1855 {
1856 //
1857 // We found the address, we should remove it and add it for
1858 // future deallocation
1859 //
1860 RemoveEntryList(&CurrentHookedDetails->OtherHooksList);
1861
1862 //
1863 // Free the pool in next ioctl
1864 //
1865 if (!PoolManagerCallbackFreePool((UINT64)CurrentHookedDetails))
1866 {
1867 LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
1868 }
1869 return TRUE;
1870 }
1871 }
1872 //
1873 // No entry found !
1874 //
1875 return FALSE;
1876}
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113

◆ EptHookReservePreallocatedPoolsForEptHooks()

VOID EptHookReservePreallocatedPoolsForEptHooks ( UINT32 Count)

Allocate pre-allocated pools for EPT hooks.

Reserve 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}
#define MAX_EXEC_TRAMPOLINE_SIZE
Maximum number of supported execution trampoline.
Definition Hooks.h:95
@ EXEC_TRAMPOLINE
Definition DataTypes.h:75
@ DETOUR_HOOK_DETAILS
Definition DataTypes.h:77

◆ EptHookRestoreAllHooksToOriginalEntry()

VOID EptHookRestoreAllHooksToOriginalEntry ( VIRTUAL_MACHINE_STATE * VCpu)

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

Remove and Invalidate Hook in TLB.

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
720{
721 PEPT_PML1_ENTRY TargetPage;
722
723 //
724 // Should be called from vmx-root, for calling from vmx non-root use the corresponding VMCALL
725 //
727 {
728 return;
729 }
730
731 LIST_FOR_EACH_LINK(g_EptState->HookedPagesList, EPT_HOOKED_PAGE_DETAIL, PageHookList, HookedEntry)
732 {
733 //
734 // Pointer to the page entry in the page table
735 //
736 TargetPage = EptGetPml1Entry(VCpu->EptPageTable, HookedEntry->PhysicalBaseAddress);
737
738 //
739 // Apply the hook to EPT
740 //
741 TargetPage->AsUInt = HookedEntry->OriginalEntry.AsUInt;
742 }
743
744 //
745 // Invalidate EPT Cache
746 //
748}

◆ EptHookRestoreSingleHookToOriginalEntry()

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

Remove a special hook from the hooked pages lists.

Remove and Invalidate Hook in TLB (Hidden Detours and if counter of hidden breakpoint is zero).

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
674{
675 PEPT_PML1_ENTRY TargetPage;
676
677 //
678 // Should be called from vmx-root, for calling from vmx non-root use the corresponding VMCALL
679 //
681 {
682 return FALSE;
683 }
684 //
685 // Pointer to the page entry in the page table
686 //
687 TargetPage = EptGetPml1Entry(VCpu->EptPageTable, PhysicalAddress);
688
689 if (TargetPage != NULL)
690 {
691 //
692 // Apply the hook to EPT
693 //
694 TargetPage->AsUInt = OriginalEntry;
695
696 //
697 // Invalidate EPT Cache
698 //
700
701 return TRUE;
702 }
703
704 //
705 // The PML1 entry not found
706 //
707 return FALSE;
708}

◆ EptHookUnHookAll()

VOID EptHookUnHookAll ( )

Remove all hooks from the hooked pages lists.

Remove all hooks from the hooked pages list and invalidate TLB @detailsShould be called from Vmx Non-root.

Returns
VOID

Remove all hooks from the hooked pages lists.

Returns
VOID
2452{
2453 //
2454 // Should be called from vmx non-root
2455 //
2457 {
2458 return;
2459 }
2460
2461 //
2462 // Remove it in all the cores
2463 //
2465
2466 //
2467 // In the case of unhooking all pages, we remove the hooked
2468 // from EPT table in vmx-root and at last, we need to deallocate
2469 // it from the buffers
2470 //
2471
2472 LIST_FOR_EACH_LINK(g_EptState->HookedPagesList, EPT_HOOKED_PAGE_DETAIL, PageHookList, CurrEntity)
2473 {
2474 //
2475 // Now that we removed this hidden detours hook, it is
2476 // time to remove it from g_EptHook2sDetourListHead
2477 // if the hook is detours
2478 //
2479 if (!CurrEntity->IsHiddenBreakpoint)
2480 {
2481 EptHookRemoveEntryAndFreePoolFromEptHook2sDetourList(CurrEntity->VirtualAddress);
2482 }
2483
2484 //
2485 // As we are in vmx-root here, we add the hooked entry to the list
2486 // of pools that will be deallocated on next IOCTL
2487 //
2488 if (!PoolManagerCallbackFreePool((UINT64)CurrEntity))
2489 {
2490 LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
2491 }
2492 }
2493}
BOOLEAN EptHookRemoveEntryAndFreePoolFromEptHook2sDetourList(UINT64 Address)
Remove the entry from g_EptHook2sDetourListHead in the case of !epthook2 details.
Definition EptHook.c:1846
VOID DpcRoutineRemoveHookAndInvalidateAllEntriesOnAllCores(KDPC *Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
The broadcast function which removes all the hooks and invalidate TLB.
Definition DpcRoutines.c:1417

◆ 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
2317{
2318 EPT_SINGLE_HOOK_UNHOOKING_DETAILS TargetUnhookingDetails; // not used
2319 BOOLEAN AtLeastOneUnhooked = FALSE;
2320 BOOLEAN UnhookingResult = FALSE;
2321
2322 //
2323 // Should be called from vmx non-root
2324 //
2326 {
2327 return FALSE;
2328 }
2329
2330KeepUnhooking:
2332 NULL_ZERO,
2333 HookingTag,
2334 NULL_ZERO,
2335 FALSE,
2336 &TargetUnhookingDetails);
2337
2338 if (UnhookingResult)
2339 {
2340 AtLeastOneUnhooked = TRUE;
2341
2342 //
2343 // Keep unhooking until there is no more hooking details
2344 //
2345 goto KeepUnhooking;
2346 }
2347
2348 return AtLeastOneUnhooked;
2349}
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:2229
struct _EPT_SINGLE_HOOK_UNHOOKING_DETAILS EPT_SINGLE_HOOK_UNHOOKING_DETAILS
Details of unhooking single EPT hooks.

◆ 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.

Remove single hook from the hooked pages list and invalidate TLB.

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
2393{
2394 EPT_SINGLE_HOOK_UNHOOKING_DETAILS TargetUnhookingDetails; // not used
2395
2396 //
2397 // Should be called from VMX non-root
2398 //
2400 {
2401 return FALSE;
2402 }
2403
2404 return EptHookPerformUnHookSingleAddress(VirtualAddress,
2405 PhysAddress,
2406 NULL_ZERO,
2407 ProcessId,
2408 FALSE,
2409 &TargetUnhookingDetails);
2410}

◆ 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.

Remove single hook from the hooked pages list and invalidate TLB.

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
2427{
2428 //
2429 // Should be called from VMX root-mode
2430 //
2432 {
2433 return FALSE;
2434 }
2435
2436 return EptHookPerformUnHookSingleAddress(VirtualAddress,
2437 PhysAddress,
2439 NULL_ZERO,
2440 TRUE,
2441 TargetUnhookingDetails);
2442}
#define NULL64_ZERO
Definition BasicTypes.h:111

◆ 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
2361{
2362 //
2363 // Should be called from VMX root-mode
2364 //
2366 {
2367 return FALSE;
2368 }
2369
2372 HookingTag,
2373 NULL_ZERO,
2374 TRUE,
2375 TargetUnhookingDetails);
2376}

◆ 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 = CpuReadMsr(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 = CpuReadMsr(IA32_EFER);
50
51 if (EnableEFERSyscallHook)
52 {
53 MsrValue.SyscallEnable = FALSE;
54
55 //
56 // Set VM-Entry controls to load EFER
57 //
58 VmxVmwrite32(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls | IA32_VMX_ENTRY_CTLS_LOAD_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
59
60 //
61 // Set VM-Exit controls to save EFER
62 //
63 VmxVmwrite32(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls | IA32_VMX_EXIT_CTLS_SAVE_IA32_EFER_FLAG, 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 VmxVmwrite64(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 VmxVmwrite32(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls & ~IA32_VMX_ENTRY_CTLS_LOAD_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
83
84 //
85 // Set VM-Exit controls to save EFER
86 //
87 VmxVmwrite32(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls & ~IA32_VMX_EXIT_CTLS_SAVE_IA32_EFER_FLAG, 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 VmxVmwrite64(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 CpuWriteMsr(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:1069
VOID CpuWriteMsr(ULONG MsrAddress, UINT64 MsrValue)
Write an MSR.
Definition PlatformIntrinsics.c:233
UINT64 CpuReadMsr(ULONG MsrAddress)
Read an MSR.
Definition PlatformIntrinsics.c:213
UCHAR VmxVmwrite64(size_t Field, UINT64 FieldValue)
VMX VMWRITE instruction (64-bit).
Definition PlatformIntrinsicsVmx.c:273
UCHAR VmxVmwrite32(size_t Field, UINT32 FieldValue)
VMX VMWRITE instruction (32-bit).
Definition PlatformIntrinsicsVmx.c:293
UCHAR VmxVmread32P(size_t Field, UINT32 *FieldValue)
VMX VMREAD instruction (32-bit, pointer variant).
Definition PlatformIntrinsicsVmx.c:227
VOID ProtectedHvRemoveUndefinedInstructionForDisablingSyscallSysretCommands(VIRTUAL_MACHINE_STATE *VCpu)
Reset exception bitmap in VMCS because of clearing !exception commands.
Definition ProtectedHv.c:161
@ 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)

Variable Documentation

◆ NumberOfBytes

POOL_TYPE SIZE_T NumberOfBytes

◆ PoolType

POOL_TYPE PoolType

◆ Tag

POOL_TYPE SIZE_T ULONG Tag