mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-07-09 17:19:26 +00:00
244 lines
6.7 KiB
NASM
244 lines
6.7 KiB
NASM
PUBLIC AsmVmexitHandler
|
|
PUBLIC AsmVmxoffRestoreXmmRegs
|
|
|
|
EXTERN VmxVmexitHandler:PROC
|
|
EXTERN VmxPerformVmresume:PROC
|
|
EXTERN VmxReturnStackPointerForVmxoff:PROC
|
|
EXTERN VmxReturnInstructionPointerForVmxoff:PROC
|
|
|
|
.code _text
|
|
|
|
;------------------------------------------------------------------------
|
|
|
|
AsmVmexitHandler PROC
|
|
|
|
push 0 ; we might be in an unaligned stack state, so the memory before stack might cause
|
|
; irql less or equal as it doesn't exist, so we just put some extra space avoid
|
|
; these kind of errors
|
|
|
|
; --------------- Save RFLAGS ----------------
|
|
|
|
pushfq ; Save the flags register (RFLAGS)
|
|
|
|
; ------------ Save XMM Registers ------------
|
|
|
|
; 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
|
|
|
|
;
|
|
; As per Microsoft ABI documentation, the following registers are nonvolatile
|
|
; So, MSVC compiler will save them on the stack if they are used in the function
|
|
; Thus, for the sake of performance, we comment them out
|
|
;
|
|
; 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
|
|
push r13
|
|
push r12
|
|
push r11
|
|
push r10
|
|
push r9
|
|
push r8
|
|
push rdi
|
|
push rsi
|
|
push rbp
|
|
push rbp ; rsp
|
|
push rbx
|
|
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)
|
|
|
|
je AsmVmxoffHandler
|
|
|
|
; ----------- Restore XMM Registers ----------
|
|
|
|
RestoreState:
|
|
|
|
pop rax
|
|
pop rcx
|
|
pop rdx
|
|
pop rbx
|
|
pop rbp ; rsp
|
|
pop rbp
|
|
pop rsi
|
|
pop rdi
|
|
pop r8
|
|
pop r9
|
|
pop r10
|
|
pop r11
|
|
pop r12
|
|
pop r13
|
|
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]
|
|
|
|
;
|
|
; As per Microsoft ABI documentation, the following registers are nonvolatile
|
|
; So, MSVC compiler will save them on the stack if they are used in the function
|
|
; Thus, for the sake of performance, we comment them out
|
|
;
|
|
; 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)
|
|
|
|
; ----------------------------------------------
|
|
|
|
jmp VmxPerformVmresume
|
|
|
|
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]
|
|
|
|
;
|
|
; As per Microsoft ABI documentation, the following registers are nonvolatile
|
|
; So, MSVC compiler will save them on the stack if they are used in the function
|
|
; Thus, for the sake of performance, we comment them out
|
|
;
|
|
; 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
|
|
|
|
; ------ Restore General-purpose Registers ------
|
|
|
|
RestoreState:
|
|
|
|
pop rax
|
|
pop rcx
|
|
pop rdx
|
|
pop rbx
|
|
pop rbp ; rsp
|
|
pop rbp
|
|
pop rsi
|
|
pop rdi
|
|
pop r8
|
|
pop r9
|
|
pop r10
|
|
pop r11
|
|
pop r12
|
|
pop r13
|
|
pop r14
|
|
pop r15
|
|
|
|
; ------------- 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
|
|
|
|
; ----------------------------------------------
|
|
|
|
; 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
|
|
|
|
xor rax, rax ; clear RAX to indicate VMXOFF was successful (VMCALL Status)
|
|
|
|
ret ; jump back to where we called Vmcall
|
|
|
|
AsmVmxoffHandler ENDP
|
|
|
|
;------------------------------------------------------------------------
|
|
|
|
END
|