diff --git a/CHANGELOG.md b/CHANGELOG.md
index 90dd4142..f19be5e1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,8 +12,13 @@ New release of the HyperDbg Debugger.
- Export the SDK functions for SMI operations ([link](https://docs.hyperdbg.org/commands/extension-commands/smi#sdk))
### Changed
+- The 'hyperhv' project now has build optimizations enabled
+- Reformat VMXOFF restoring routines to restore general-purpose and XMM registers correctly before moving to the previous stack
+- Fix unloading (VMXOFF) crash when restoring XMM registers
+- Fix the problem with restoring XMM registers (#468) ([link](https://github.com/HyperDbg/HyperDbg/issues/468))
- Enhanced the '.pe' command to support PE Rich Headers thanks to [@Alish14](https://github.com/Alish14) ([link](https://github.com/HyperDbg/HyperDbg/pull/539))
+
## [0.14.1.0] - 2025-07-27
New release of the HyperDbg Debugger.
diff --git a/hyperdbg/hyperhv/code/assembly/AsmVmexitHandler.asm b/hyperdbg/hyperhv/code/assembly/AsmVmexitHandler.asm
index 0a41fbd1..9d62847b 100644
--- a/hyperdbg/hyperhv/code/assembly/AsmVmexitHandler.asm
+++ b/hyperdbg/hyperhv/code/assembly/AsmVmexitHandler.asm
@@ -1,4 +1,5 @@
PUBLIC AsmVmexitHandler
+PUBLIC AsmVmxoffRestoreXmmRegs
EXTERN VmxVmexitHandler:PROC
EXTERN VmxVmresume:PROC
@@ -15,32 +16,36 @@ AsmVmexitHandler PROC
; irql less or equal as it doesn't exist, so we just put some extra space avoid
; these kind of errors
- pushfq
+ ; --------------- Save RFLAGS ----------------
+
+ pushfq ; Save the flags register (RFLAGS)
; ------------ Save XMM Registers ------------
- ;
- ; ;;;;;;;;;;;; 16 Byte * 16 Byte = 256 + 4 = 260 (0x106 == 0x110 but let's align it to have better performance) ;;;;;;;;;;;;
- ; sub rsp, 0110h
- ;
- ; movaps xmmword ptr [rsp+000h], xmm0 ; each xmm register 128 bit (16 Byte)
- ; movaps xmmword ptr [rsp+010h], xmm1
- ; movaps xmmword ptr [rsp+020h], xmm2
- ; movaps xmmword ptr [rsp+030h], xmm3
- ; movaps xmmword ptr [rsp+040h], xmm4
- ; movaps xmmword ptr [rsp+050h], xmm5
- ; movaps xmmword ptr [rsp+060h], xmm6
- ; movaps xmmword ptr [rsp+070h], xmm7
- ; movaps xmmword ptr [rsp+080h], xmm8
- ; movaps xmmword ptr [rsp+090h], xmm9
- ; movaps xmmword ptr [rsp+0a0h], xmm10
- ; movaps xmmword ptr [rsp+0b0h], xmm11
- ; movaps xmmword ptr [rsp+0c0h], xmm12
- ; movaps xmmword ptr [rsp+0d0h], xmm13
- ; movaps xmmword ptr [rsp+0e0h], xmm14
- ; movaps xmmword ptr [rsp+0f0h], xmm15
- ; stmxcsr dword ptr [rsp+0100h] ; MxCsr is 4 Byte
- ;
- ;---------------------------------------------
+
+ ; 16 Byte * 16 Byte = 256 + 4 = 260 (0x104 == 0x110 but let's align it to have better performance)
+
+ sub rsp, 0110h
+
+ movaps xmmword ptr [rsp+000h], xmm0 ; each xmm register 128 bit (16 Byte)
+ movaps xmmword ptr [rsp+010h], xmm1
+ movaps xmmword ptr [rsp+020h], xmm2
+ movaps xmmword ptr [rsp+030h], xmm3
+ movaps xmmword ptr [rsp+040h], xmm4
+ movaps xmmword ptr [rsp+050h], xmm5
+ movaps xmmword ptr [rsp+060h], xmm6
+ movaps xmmword ptr [rsp+070h], xmm7
+ movaps xmmword ptr [rsp+080h], xmm8
+ movaps xmmword ptr [rsp+090h], xmm9
+ movaps xmmword ptr [rsp+0a0h], xmm10
+ movaps xmmword ptr [rsp+0b0h], xmm11
+ movaps xmmword ptr [rsp+0c0h], xmm12
+ movaps xmmword ptr [rsp+0d0h], xmm13
+ movaps xmmword ptr [rsp+0e0h], xmm14
+ movaps xmmword ptr [rsp+0f0h], xmm15
+
+ stmxcsr dword ptr [rsp+0100h] ; MxCsr is 4 Byte
+
+ ; ------ Save General-purpose Registers ------
push r15
push r14
@@ -58,21 +63,28 @@ AsmVmexitHandler PROC
push rdx
push rcx
push rax
-
+
+ ; ----------- Call VM-exit Handler -----------
+
mov rcx, rsp ; Fast call argument to PGUEST_REGS
+
sub rsp, 020h ; Free some space for Shadow Section
call VmxVmexitHandler
add rsp, 020h ; Restore the state
- cmp al, 1 ; Check whether we have to turn off VMX or Not (the result is in RAX)
+ cmp al, 1 ; Check whether we have to turn off VMX or Not (the result is in RAX)
+
je AsmVmxoffHandler
-
+
+ ; ----------- Restore XMM Registers ----------
+
RestoreState:
+
pop rax
pop rcx
pop rdx
pop rbx
- pop rbp ; rsp
+ pop rbp ; rsp
pop rbp
pop rsi
pop rdi
@@ -86,71 +98,80 @@ RestoreState:
pop r15
; ------------ Restore XMM Registers ------------
- ;
- ; movaps xmm0, xmmword ptr [rsp+000h]
- ; movaps xmm1, xmmword ptr [rsp+010h]
- ; movaps xmm2, xmmword ptr [rsp+020h]
- ; movaps xmm3, xmmword ptr [rsp+030h]
- ; movaps xmm4, xmmword ptr [rsp+040h]
- ; movaps xmm5, xmmword ptr [rsp+050h]
- ; movaps xmm6, xmmword ptr [rsp+060h]
- ; movaps xmm7, xmmword ptr [rsp+070h]
- ; movaps xmm8, xmmword ptr [rsp+080h]
- ; movaps xmm9, xmmword ptr [rsp+090h]
- ; movaps xmm10, xmmword ptr [rsp+0a0h]
- ; movaps xmm11, xmmword ptr [rsp+0b0h]
- ; movaps xmm12, xmmword ptr [rsp+0c0h]
- ; movaps xmm13, xmmword ptr [rsp+0d0h]
- ; movaps xmm14, xmmword ptr [rsp+0e0h]
- ; movaps xmm15, xmmword ptr [rsp+0f0h]
- ;
- ; ldmxcsr dword ptr [rsp+0100h]
- ;
- ; add rsp, 0110h
+
+ movaps xmm0, xmmword ptr [rsp+000h]
+ movaps xmm1, xmmword ptr [rsp+010h]
+ movaps xmm2, xmmword ptr [rsp+020h]
+ movaps xmm3, xmmword ptr [rsp+030h]
+ movaps xmm4, xmmword ptr [rsp+040h]
+ movaps xmm5, xmmword ptr [rsp+050h]
+ movaps xmm6, xmmword ptr [rsp+060h]
+ movaps xmm7, xmmword ptr [rsp+070h]
+ movaps xmm8, xmmword ptr [rsp+080h]
+ movaps xmm9, xmmword ptr [rsp+090h]
+ movaps xmm10, xmmword ptr [rsp+0a0h]
+ movaps xmm11, xmmword ptr [rsp+0b0h]
+ movaps xmm12, xmmword ptr [rsp+0c0h]
+ movaps xmm13, xmmword ptr [rsp+0d0h]
+ movaps xmm14, xmmword ptr [rsp+0e0h]
+ movaps xmm15, xmmword ptr [rsp+0f0h]
+
+ ldmxcsr dword ptr [rsp+0100h]
+
+ add rsp, 0110h
+
+ ; --------------- Restore RFLAGS ---------------
+
+ popfq ; Restore the flags register (RFLAGS)
+
; ----------------------------------------------
- popfq
-
- sub rsp, 0100h ; to avoid error in future functions
jmp VmxVmresume
AsmVmexitHandler ENDP
;------------------------------------------------------------------------
+AsmVmxoffRestoreXmmRegs PROC
+
+ ; ------------ Restore XMM Registers ------------
+
+ movaps xmm0, xmmword ptr [rcx+000h]
+ movaps xmm1, xmmword ptr [rcx+010h]
+ movaps xmm2, xmmword ptr [rcx+020h]
+ movaps xmm3, xmmword ptr [rcx+030h]
+ movaps xmm4, xmmword ptr [rcx+040h]
+ movaps xmm5, xmmword ptr [rcx+050h]
+ movaps xmm6, xmmword ptr [rcx+060h]
+ movaps xmm7, xmmword ptr [rcx+070h]
+ movaps xmm8, xmmword ptr [rcx+080h]
+ movaps xmm9, xmmword ptr [rcx+090h]
+ movaps xmm10, xmmword ptr [rcx+0a0h]
+ movaps xmm11, xmmword ptr [rcx+0b0h]
+ movaps xmm12, xmmword ptr [rcx+0c0h]
+ movaps xmm13, xmmword ptr [rcx+0d0h]
+ movaps xmm14, xmmword ptr [rcx+0e0h]
+ movaps xmm15, xmmword ptr [rcx+0f0h]
+
+ ldmxcsr dword ptr [rcx+0100h]
+
+ ret
+
+AsmVmxoffRestoreXmmRegs ENDP
+
+;------------------------------------------------------------------------
+
AsmVmxoffHandler PROC
-
- sub rsp, 020h ; shadow space
- call VmxReturnStackPointerForVmxoff
- add rsp, 020h ; remove for shadow space
-
- mov [rsp+88h], rax ; now, rax contains rsp
-
- sub rsp, 020h ; shadow space
- call VmxReturnInstructionPointerForVmxoff
- add rsp, 020h ; remove for shadow space
-
- mov rdx, rsp ; save current rsp
-
- mov rbx, [rsp+88h] ; read rsp again
-
- mov rsp, rbx
-
- push rax ; push the return address as we changed the stack, we push
- ; it to the new stack
-
- mov rsp, rdx ; restore previous rsp
-
- sub rbx,08h ; we push sth, so we have to add (sub) +8 from previous stack
- ; also rbx already contains the rsp
- mov [rsp+88h], rbx ; move the new pointer to the current stack
-
+
+ ; ------ Restore General-purpose Registers ------
+
RestoreState:
+
pop rax
pop rcx
pop rdx
pop rbx
- pop rbp ; rsp
+ pop rbp ; rsp
pop rbp
pop rsi
pop rdi
@@ -163,34 +184,40 @@ RestoreState:
pop r14
pop r15
- ; ------------ Restore XMM Registers ------------
- ;
- ; movaps xmm0, xmmword ptr [rsp+000h]
- ; movaps xmm1, xmmword ptr [rsp+010h]
- ; movaps xmm2, xmmword ptr [rsp+020h]
- ; movaps xmm3, xmmword ptr [rsp+030h]
- ; movaps xmm4, xmmword ptr [rsp+040h]
- ; movaps xmm5, xmmword ptr [rsp+050h]
- ; movaps xmm6, xmmword ptr [rsp+060h]
- ; movaps xmm7, xmmword ptr [rsp+070h]
- ; movaps xmm8, xmmword ptr [rsp+080h]
- ; movaps xmm9, xmmword ptr [rsp+090h]
- ; movaps xmm10, xmmword ptr [rsp+0a0h]
- ; movaps xmm11, xmmword ptr [rsp+0b0h]
- ; movaps xmm12, xmmword ptr [rsp+0c0h]
- ; movaps xmm13, xmmword ptr [rsp+0d0h]
- ; movaps xmm14, xmmword ptr [rsp+0e0h]
- ; movaps xmm15, xmmword ptr [rsp+0f0h]
- ;
- ; ldmxcsr dword ptr [rsp+0100h]
- ;
- ; add rsp, 0110h
+ ; ------------- Pass over XMM Regs -------------
+
+ ; XMM registers are restored by AsmVmxoffRestoreXmmRegs
+ ; Size of XMM registers are 110 bytes but we also remove the RFLAGS register (+8)
+ ; so we have 118 bytes to remove from the stack
+ add rsp, 0118h
+
+ ; ------------ Get Stack Pointer ---------------
+
+ sub rsp, 020h ; shadow space
+ call VmxReturnStackPointerForVmxoff
+ add rsp, 020h ; remove for shadow space
+
+ push rax ; save the current rsp, we will restore it later
+
+
+ ; ------------ Get Instruction Pointer ---------
+
+ sub rsp, 020h ; shadow space
+ call VmxReturnInstructionPointerForVmxoff
+ add rsp, 020h ; remove for shadow space
+
+ pop rsp ; restore rsp
+ push rax ; push the instruction pointer
+
; ----------------------------------------------
- popfq
- pop rsp ; restore rsp
+ ; There might be some registers that are modified by above CALLs,
+ ; but here we do not care about them since we are also in a function,
+ ; so the caller do not expect us to preserve these volatile registers
- ret ; jump back to where we called Vmcall
+ xor rax, rax ; clear RAX to indicate VMXOFF was successful (VMCALL Status)
+
+ ret ; jump back to where we called Vmcall
AsmVmxoffHandler ENDP
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c b/hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c
index f7a99fc8..59587977 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c
@@ -31,9 +31,10 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
VCpu = &g_GuestState[KeGetCurrentProcessorNumberEx(NULL)];
//
- // Set the registers
+ // Set the registers (general-purpose and XMM)
//
- VCpu->Regs = GuestRegs;
+ VCpu->Regs = GuestRegs;
+ VCpu->XmmRegs = (GUEST_XMM_REGS *)(((CHAR *)GuestRegs) + sizeof(GUEST_REGS));
//
// Indicates we are in Vmx root mode in this logical core
@@ -77,6 +78,7 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
// LogInfo("VM_EXIT_REASON : 0x%x", ExitReason);
// LogInfo("VMCS_EXIT_QUALIFICATION : 0x%llx", VCpu->ExitQualification);
//
+
switch (ExitReason)
{
case VMX_EXIT_REASON_TRIPLE_FAULT:
diff --git a/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c b/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c
index 939242f6..d17558b5 100644
--- a/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c
+++ b/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c
@@ -1156,6 +1156,15 @@ VmxVmxoff(VIRTUAL_MACHINE_STATE * VCpu)
//
HvRestoreRegisters();
+ //
+ // Restore XMM registers
+ // We restore XMM registers here because we are going to execute vmxoff instruction
+ // which enables interrupts and we don't want to lose the XMM registers
+ // since immediately after vmxoff, an interrupt might occur and context switch
+ // might change the XMM registers
+ //
+ AsmVmxoffRestoreXmmRegs((unsigned long long)VCpu->XmmRegs);
+
//
// Before using vmxoff, you first need to use vmclear on any VMCSes that you want to be able to use again.
// See sections 24.1 and 24.11 of the SDM.
@@ -1167,6 +1176,11 @@ VmxVmxoff(VIRTUAL_MACHINE_STATE * VCpu)
//
__vmx_off();
+ //
+ // *** Note: After executing VMXOFF, XMM registers should not be used anymore
+ // Since we already restored them ***
+ //
+
//
// Indicate the current core is not currently virtualized
//
diff --git a/hyperdbg/hyperhv/header/assembly/InlineAsm.h b/hyperdbg/hyperhv/header/assembly/InlineAsm.h
index b1ec773d..464de5ec 100644
--- a/hyperdbg/hyperhv/header/assembly/InlineAsm.h
+++ b/hyperdbg/hyperhv/header/assembly/InlineAsm.h
@@ -97,6 +97,12 @@ AsmVmexitHandler();
*/
extern void inline AsmSaveVmxOffState();
+/**
+ * @brief Restore XMM registers
+ *
+ */
+extern void inline AsmVmxoffRestoreXmmRegs(unsigned long long XmmRegs);
+
//
// ==================== Extended Page Tables ====================
// File : AsmEpt.asm
@@ -143,7 +149,7 @@ AsmGetCs();
extern unsigned short
AsmGetDs();
-extern void
+extern void
AsmSetDs(unsigned short DsSelector);
/**
diff --git a/hyperdbg/hyperhv/header/common/State.h b/hyperdbg/hyperhv/header/common/State.h
index c6a587e2..be58354d 100644
--- a/hyperdbg/hyperhv/header/common/State.h
+++ b/hyperdbg/hyperhv/header/common/State.h
@@ -302,52 +302,53 @@ typedef struct _NMI_BROADCASTING_STATE
*/
typedef struct _VIRTUAL_MACHINE_STATE
{
- BOOLEAN IsOnVmxRootMode; // Detects whether the current logical core is on Executing on VMX Root Mode
- BOOLEAN IncrementRip; // Checks whether it has to redo the previous instruction or not (it used mainly in Ept routines)
- BOOLEAN HasLaunched; // Indicate whether the core is virtualized or not
- BOOLEAN IgnoreMtfUnset; // Indicate whether the core should ignore unsetting the MTF or not
- BOOLEAN WaitForImmediateVmexit; // Whether the current core is waiting for an immediate vm-exit or not
- BOOLEAN EnableExternalInterruptsOnContinue; // Whether to enable external interrupts on the continue or not
- BOOLEAN EnableExternalInterruptsOnContinueMtf; // Whether to enable external interrupts on the continue state of MTF or not
- BOOLEAN RegisterBreakOnMtf; // Registered Break in the case of MTFs (used in instrumentation step-in)
- BOOLEAN IgnoreOneMtf; // Ignore (mark as handled) for one MTF
- BOOLEAN NotNormalEptp; // Indicate that the target processor is on the normal EPTP or not
- BOOLEAN MbecEnabled; // Indicate that the target processor is on MBEC-enabled mode or not
- PUINT64 PmlBufferAddress; // Address of buffer used for dirty logging
- BOOLEAN Test; // Used for test purposes
- UINT64 TestNumber; // Used for test purposes (Number)
- GUEST_REGS * Regs; // The virtual processor's general-purpose registers
- UINT32 CoreId; // The core's unique identifier
- UINT32 ExitReason; // The core's exit reason
- UINT32 ExitQualification; // The core's exit qualification
- UINT64 LastVmexitRip; // RIP in the current VM-exit
- UINT64 VmxonRegionPhysicalAddress; // Vmxon region physical address
- UINT64 VmxonRegionVirtualAddress; // VMXON region virtual address
- UINT64 VmcsRegionPhysicalAddress; // VMCS region physical address
- UINT64 VmcsRegionVirtualAddress; // VMCS region virtual address
- UINT64 VmmStack; // Stack for VMM in VM-Exit State
- UINT64 MsrBitmapVirtualAddress; // Msr Bitmap Virtual Address
- UINT64 MsrBitmapPhysicalAddress; // Msr Bitmap Physical Address
- UINT64 IoBitmapVirtualAddressA; // I/O Bitmap Virtual Address (A)
- UINT64 IoBitmapPhysicalAddressA; // I/O Bitmap Physical Address (A)
- UINT64 IoBitmapVirtualAddressB; // I/O Bitmap Virtual Address (B)
- UINT64 IoBitmapPhysicalAddressB; // I/O Bitmap Physical Address (B)
- UINT32 QueuedNmi; // Queued NMIs
- UINT32 PendingExternalInterrupts[PENDING_INTERRUPTS_BUFFER_CAPACITY]; // This list holds a buffer for external-interrupts that are in pending state due to the external-interrupt
- // blocking and waits for interrupt-window exiting
- // From hvpp :
- // Pending interrupt queue (FIFO).
- // Make storage for up-to 64 pending interrupts.
- // In practice I haven't seen more than 2 pending interrupts.
- VMX_VMXOFF_STATE VmxoffState; // Shows the vmxoff state of the guest
- NMI_BROADCASTING_STATE NmiBroadcastingState; // Shows the state of NMI broadcasting
- VM_EXIT_TRANSPARENCY TransparencyState; // The state of the debugger in transparent-mode
- PEPT_HOOKED_PAGE_DETAIL MtfEptHookRestorePoint; // It shows the detail of the hooked paged that should be restore in MTF vm-exit
- UINT8 LastExceptionOccuredInHost; // The vector of last exception occured in host
- UINT64 HostIdt; // host Interrupt Descriptor Table (actual type is SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64*)
- UINT64 HostGdt; // host Global Descriptor Table (actual type is SEGMENT_DESCRIPTOR_32* or SEGMENT_DESCRIPTOR_64*)
- UINT64 HostTss; // host Task State Segment (actual type is TASK_STATE_SEGMENT_64*)
- UINT64 HostInterruptStack; // host interrupt RSP
+ BOOLEAN IsOnVmxRootMode; // Detects whether the current logical core is on Executing on VMX Root Mode
+ BOOLEAN IncrementRip; // Checks whether it has to redo the previous instruction or not (it used mainly in Ept routines)
+ BOOLEAN HasLaunched; // Indicate whether the core is virtualized or not
+ BOOLEAN IgnoreMtfUnset; // Indicate whether the core should ignore unsetting the MTF or not
+ BOOLEAN WaitForImmediateVmexit; // Whether the current core is waiting for an immediate vm-exit or not
+ BOOLEAN EnableExternalInterruptsOnContinue; // Whether to enable external interrupts on the continue or not
+ BOOLEAN EnableExternalInterruptsOnContinueMtf; // Whether to enable external interrupts on the continue state of MTF or not
+ BOOLEAN RegisterBreakOnMtf; // Registered Break in the case of MTFs (used in instrumentation step-in)
+ BOOLEAN IgnoreOneMtf; // Ignore (mark as handled) for one MTF
+ BOOLEAN NotNormalEptp; // Indicate that the target processor is on the normal EPTP or not
+ BOOLEAN MbecEnabled; // Indicate that the target processor is on MBEC-enabled mode or not
+ PUINT64 PmlBufferAddress; // Address of buffer used for dirty logging
+ BOOLEAN Test; // Used for test purposes
+ UINT64 TestNumber; // Used for test purposes (Number)
+ GUEST_REGS * Regs; // The virtual processor's general-purpose registers
+ GUEST_XMM_REGS * XmmRegs; // The virtual processor's XMM registers
+ UINT32 CoreId; // The core's unique identifier
+ UINT32 ExitReason; // The core's exit reason
+ UINT32 ExitQualification; // The core's exit qualification
+ UINT64 LastVmexitRip; // RIP in the current VM-exit
+ UINT64 VmxonRegionPhysicalAddress; // Vmxon region physical address
+ UINT64 VmxonRegionVirtualAddress; // VMXON region virtual address
+ UINT64 VmcsRegionPhysicalAddress; // VMCS region physical address
+ UINT64 VmcsRegionVirtualAddress; // VMCS region virtual address
+ UINT64 VmmStack; // Stack for VMM in VM-Exit State
+ UINT64 MsrBitmapVirtualAddress; // Msr Bitmap Virtual Address
+ UINT64 MsrBitmapPhysicalAddress; // Msr Bitmap Physical Address
+ UINT64 IoBitmapVirtualAddressA; // I/O Bitmap Virtual Address (A)
+ UINT64 IoBitmapPhysicalAddressA; // I/O Bitmap Physical Address (A)
+ UINT64 IoBitmapVirtualAddressB; // I/O Bitmap Virtual Address (B)
+ UINT64 IoBitmapPhysicalAddressB; // I/O Bitmap Physical Address (B)
+ UINT32 QueuedNmi; // Queued NMIs
+ UINT32 PendingExternalInterrupts[PENDING_INTERRUPTS_BUFFER_CAPACITY]; // This list holds a buffer for external-interrupts that are in pending state due to the external-interrupt
+ // blocking and waits for interrupt-window exiting
+ // From hvpp :
+ // Pending interrupt queue (FIFO).
+ // Make storage for up-to 64 pending interrupts.
+ // In practice I haven't seen more than 2 pending interrupts.
+ VMX_VMXOFF_STATE VmxoffState; // Shows the vmxoff state of the guest
+ NMI_BROADCASTING_STATE NmiBroadcastingState; // Shows the state of NMI broadcasting
+ VM_EXIT_TRANSPARENCY TransparencyState; // The state of the debugger in transparent-mode
+ PEPT_HOOKED_PAGE_DETAIL MtfEptHookRestorePoint; // It shows the detail of the hooked paged that should be restore in MTF vm-exit
+ UINT8 LastExceptionOccuredInHost; // The vector of last exception occured in host
+ UINT64 HostIdt; // host Interrupt Descriptor Table (actual type is SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64*)
+ UINT64 HostGdt; // host Global Descriptor Table (actual type is SEGMENT_DESCRIPTOR_32* or SEGMENT_DESCRIPTOR_64*)
+ UINT64 HostTss; // host Task State Segment (actual type is TASK_STATE_SEGMENT_64*)
+ UINT64 HostInterruptStack; // host interrupt RSP
//
// EPT Descriptors
diff --git a/hyperdbg/hyperhv/hyperhv.vcxproj b/hyperdbg/hyperhv/hyperhv.vcxproj
index 115bc667..4adf66c0 100644
--- a/hyperdbg/hyperhv/hyperhv.vcxproj
+++ b/hyperdbg/hyperhv/hyperhv.vcxproj
@@ -111,7 +111,7 @@
pch.h
$(IntDir)$(TargetName).pch
Neither
- Disabled
+ Full
ZYDIS_STATIC_BUILD;ZYCORE_STATIC_BUILD;ZYAN_NO_LIBC;ZYDIS_NO_LIBC;%(PreprocessorDefinitions)
stdcpp20
diff --git a/hyperdbg/include/SDK/headers/BasicTypes.h b/hyperdbg/include/SDK/headers/BasicTypes.h
index 0df9d348..24da1a35 100644
--- a/hyperdbg/include/SDK/headers/BasicTypes.h
+++ b/hyperdbg/include/SDK/headers/BasicTypes.h
@@ -66,6 +66,7 @@ typedef unsigned __int64 UINT64, *PUINT64;
//
// DO NOT FUCKING TOUCH THIS STRUCTURE WITHOUT COORDINATION WITH SINA
//
+#pragma pack(push, 1) // Ensure no padding
typedef struct GUEST_REGS
{
//
@@ -94,6 +95,38 @@ typedef struct GUEST_REGS
//
} GUEST_REGS, *PGUEST_REGS;
+#pragma pack(pop)
+
+typedef struct XMM_REG
+{
+ UINT64 XmmLow; // Low 64 bits
+ UINT64 XmmHigh; // High 64 bits
+
+} XMM_REG;
+
+#pragma pack(push, 1) // Ensure no padding
+typedef struct GUEST_XMM_REGS
+{
+ XMM_REG xmm0; // 0x00
+ XMM_REG xmm1; // 0x10
+ XMM_REG xmm2; // 0x20
+ XMM_REG xmm3; // 0x30
+ XMM_REG xmm4; // 0x40
+ XMM_REG xmm5; // 0x50
+ XMM_REG xmm6; // 0x60
+ XMM_REG xmm7; // 0x70
+ XMM_REG xmm8; // 0x80
+ XMM_REG xmm9; // 0x90
+ XMM_REG xmm10; // 0xA0
+ XMM_REG xmm11; // 0xB0
+ XMM_REG xmm12; // 0xC0
+ XMM_REG xmm13; // 0xD0
+ XMM_REG xmm14; // 0xE0
+ XMM_REG xmm15; // 0xF0
+ UINT32 mxcsr; // 0x100
+
+} GUEST_XMM_REGS, *PGUEST_XMM_REGS;
+#pragma pack(pop)
/**
* @brief struct for extra registers