1
0
mirror of https://github.com/momo5502/hypervisor.git synced 2025-07-05 10:41:50 +00:00

Basic ept hooking

This commit is contained in:
momo5502
2022-04-13 20:59:49 +02:00
parent fd03a49992
commit e02e065bd5
5 changed files with 522 additions and 45 deletions

View File

@ -475,30 +475,30 @@ void vmx_handle_cpuid(vmx::guest_context& guest_context)
guest_context.vp_regs->Rdx = cpu_info[3];
}
void vmx_handle_xsetbv(const vmx::guest_context& guest_contex)
void vmx_handle_xsetbv(const vmx::guest_context& guest_context)
{
//
// Simply issue the XSETBV instruction on the native logical processor.
//
_xsetbv(static_cast<uint32_t>(guest_contex.vp_regs->Rcx),
guest_contex.vp_regs->Rdx << 32 | guest_contex.vp_regs->Rax);
_xsetbv(static_cast<uint32_t>(guest_context.vp_regs->Rcx),
guest_context.vp_regs->Rdx << 32 | guest_context.vp_regs->Rax);
}
void vmx_handle_vmx(vmx::guest_context& guest_contex)
void vmx_handle_vmx(vmx::guest_context& guest_context)
{
//
// Set the CF flag, which is how VMX instructions indicate failure
//
guest_contex.guest_e_flags |= 0x1; // VM_FAIL_INVALID
guest_context.guest_e_flags |= 0x1; // VM_FAIL_INVALID
//
// RFLAGs is actually restored from the VMCS, so update it here
//
__vmx_vmwrite(VMCS_GUEST_RFLAGS, guest_contex.guest_e_flags);
__vmx_vmwrite(VMCS_GUEST_RFLAGS, guest_context.guest_e_flags);
}
void vmx_dispatch_vm_exit(vmx::guest_context& guest_contex)
void vmx_dispatch_vm_exit(vmx::guest_context& guest_context, vmx::state& vm_state)
{
//
// This is the generic VM-Exit handler. Decode the reason for the exit and
@ -507,16 +507,16 @@ void vmx_dispatch_vm_exit(vmx::guest_context& guest_contex)
// INVD, XSETBV and other VMX instructions. GETSEC cannot happen as we do
// not run in SMX context.
//
switch (guest_contex.exit_reason)
switch (guest_context.exit_reason)
{
case VMX_EXIT_REASON_EXECUTE_CPUID:
vmx_handle_cpuid(guest_contex);
vmx_handle_cpuid(guest_context);
break;
case VMX_EXIT_REASON_EXECUTE_INVD:
vmx_handle_invd();
break;
case VMX_EXIT_REASON_EXECUTE_XSETBV:
vmx_handle_xsetbv(guest_contex);
vmx_handle_xsetbv(guest_context);
break;
case VMX_EXIT_REASON_EXECUTE_VMCALL:
case VMX_EXIT_REASON_EXECUTE_VMCLEAR:
@ -528,8 +528,10 @@ void vmx_dispatch_vm_exit(vmx::guest_context& guest_contex)
case VMX_EXIT_REASON_EXECUTE_VMWRITE:
case VMX_EXIT_REASON_EXECUTE_VMXOFF:
case VMX_EXIT_REASON_EXECUTE_VMXON:
vmx_handle_vmx(guest_contex);
vmx_handle_vmx(guest_context);
break;
case VMX_EXIT_REASON_EPT_VIOLATION:
vm_state.ept.handle_violation(guest_context);
default:
break;
}
@ -539,8 +541,11 @@ void vmx_dispatch_vm_exit(vmx::guest_context& guest_contex)
// caused the exit. Since we are not doing any special handling or changing
// of execution, this can be done for any exit reason.
//
guest_contex.guest_rip += read_vmx(VMCS_VMEXIT_INSTRUCTION_LENGTH);
__vmx_vmwrite(VMCS_GUEST_RIP, guest_contex.guest_rip);
if (guest_context.increment_rip)
{
guest_context.guest_rip += read_vmx(VMCS_VMEXIT_INSTRUCTION_LENGTH);
__vmx_vmwrite(VMCS_GUEST_RIP, guest_context.guest_rip);
}
}
extern "C" [[ noreturn ]] void vm_exit_handler(CONTEXT* context)
@ -557,14 +562,17 @@ extern "C" [[ noreturn ]] void vm_exit_handler(CONTEXT* context)
guest_context.guest_e_flags = read_vmx(VMCS_GUEST_RFLAGS);
guest_context.guest_rip = read_vmx(VMCS_GUEST_RIP);
guest_context.guest_rsp = read_vmx(VMCS_GUEST_RSP);
guest_context.guest_physical_address = read_vmx(VMCS_GUEST_PHYSICAL_ADDRESS);
guest_context.exit_reason = read_vmx(VMCS_EXIT_REASON) & 0xFFFF;
guest_context.exit_qualification = read_vmx(VMCS_EXIT_QUALIFICATION);
guest_context.vp_regs = context;
guest_context.exit_vm = false;
guest_context.increment_rip = true;
//
// Call the generic handler
//
vmx_dispatch_vm_exit(guest_context);
vmx_dispatch_vm_exit(guest_context, *vm_state);
//
// Did we hit the magic exit sequence, or should we resume back to the VM