From 427091ae2e89bb77161f8dbe862fb4d50ab1828a Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 31 Mar 2021 15:02:45 -0700 Subject: [PATCH] virtual nmi + nmi exiting are now always enabled --- binaries/bluepill.sys | Bin 25864 -> 0 bytes binaries/demo.exe | Bin 38400 -> 0 bytes exit_handler.cpp | 19 ++++++----------- ia32.hpp | 3 +-- idt.cpp | 6 ------ idt.hpp | 5 ++--- mm.hpp | 3 +-- vmcs.cpp | 48 ++++++++++++++++++------------------------ vmxexit_handler.asm | 3 +++ vmxexit_handler.h | 1 + vmxlaunch.cpp | 16 ++++++++------ 11 files changed, 44 insertions(+), 60 deletions(-) delete mode 100644 binaries/bluepill.sys delete mode 100644 binaries/demo.exe diff --git a/binaries/bluepill.sys b/binaries/bluepill.sys deleted file mode 100644 index c9fc14ac7f78c999fd12af902059ef4a89e5f4fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25864 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 diff --git a/binaries/demo.exe b/binaries/demo.exe deleted file mode 100644 index effba91d741d99f4149463dafdddfbbd66efefa7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38400 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 Hs098G?yd|G diff --git a/exit_handler.cpp b/exit_handler.cpp index 10028da..07b89fe 100644 --- a/exit_handler.cpp +++ b/exit_handler.cpp @@ -22,6 +22,13 @@ auto set_command(u64 dirbase, u64 command_ptr, const vmcall_command_t& vmcall_co *reinterpret_cast(virt_map) = vmcall_command; } +auto vmresume_failure() -> void +{ + size_t value; + __vmx_vmread(VMCS_VM_INSTRUCTION_ERROR, &value); + __debugbreak(); +} + auto exit_handler(hv::pguest_registers regs) -> void { u64 exit_reason; @@ -50,31 +57,19 @@ auto exit_handler(hv::pguest_registers regs) -> void __vmx_vmwrite(VMCS_VMEXIT_INTERRUPTION_ERROR_CODE, NULL); ia32_vmx_procbased_ctls_register procbased_ctls; - ia32_vmx_pinbased_ctls_register pinbased_ctls; - __vmx_vmread(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, &procbased_ctls.flags); - __vmx_vmread(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, &pinbased_ctls.flags); procbased_ctls.nmi_window_exiting = false; - pinbased_ctls.virtual_nmi = false; - __vmx_vmwrite(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, procbased_ctls.flags); - __vmx_vmwrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, pinbased_ctls.flags); return; // dont advance rip... } case VMX_EXIT_REASON_EXCEPTION_OR_NMI: { ia32_vmx_procbased_ctls_register procbased_ctls; - ia32_vmx_pinbased_ctls_register pinbased_ctls; - __vmx_vmread(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, &procbased_ctls.flags); - __vmx_vmread(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, &pinbased_ctls.flags); procbased_ctls.nmi_window_exiting = true; - pinbased_ctls.virtual_nmi = true; - __vmx_vmwrite(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, procbased_ctls.flags); - __vmx_vmwrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, pinbased_ctls.flags); return; // dont advance rip... } case VMX_EXIT_REASON_EXECUTE_XSETBV: diff --git a/ia32.hpp b/ia32.hpp index 10ca493..f576d1d 100644 --- a/ia32.hpp +++ b/ia32.hpp @@ -10444,6 +10444,7 @@ typedef union #define IA32_VMX_EXIT_CTLS 0x00000483 typedef union { + uint64_t flags; struct { uint64_t reserved1 : 2; @@ -10581,8 +10582,6 @@ typedef union #define IA32_VMX_EXIT_CTLS_CONCEAL_VMX_FROM_PT(_) (((_) >> 24) & 0x01) uint64_t reserved6 : 39; }; - - uint64_t flags; } ia32_vmx_exit_ctls_register; diff --git a/idt.cpp b/idt.cpp index d818b95..b65b354 100644 --- a/idt.cpp +++ b/idt.cpp @@ -96,16 +96,10 @@ auto seh_handler(hv::pidt_regs_t regs) -> void auto nmi_handler(hv::pidt_regs_t regs) -> void { ia32_vmx_procbased_ctls_register procbased_ctls; - ia32_vmx_pinbased_ctls_register pinbased_ctls; - __vmx_vmread(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, &procbased_ctls.flags); - __vmx_vmread(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, &pinbased_ctls.flags); procbased_ctls.nmi_window_exiting = true; - pinbased_ctls.virtual_nmi = true; - __vmx_vmwrite(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, procbased_ctls.flags); - __vmx_vmwrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, pinbased_ctls.flags); } namespace idt diff --git a/idt.hpp b/idt.hpp index 0efdaaf..81d515c 100644 --- a/idt.hpp +++ b/idt.hpp @@ -16,9 +16,8 @@ extern "C" void seh_handler_ecode(hv::pidt_regs_ecode_t regs); namespace idt { - __declspec(allocate(".idt")) - inline hv::idt_entry_t table[256]; - enum ist_idx : u8 { nmi = 3, de = 4, pf = 5, gp = 6}; + __declspec(allocate(".idt")) inline hv::idt_entry_t table[256]; + enum ist_idx : u8 { nmi = 3, de = 4, pf = 5, gp = 6 }; inline void* image_base = nullptr; // used for SEH... auto create_entry(hv::idt_addr_t idt_handler, u8 ist_index) -> hv::idt_entry_t; diff --git a/mm.hpp b/mm.hpp index d06c309..8455daf 100644 --- a/mm.hpp +++ b/mm.hpp @@ -129,8 +129,7 @@ namespace mm inline const ppml4e vmxroot_pml4 = reinterpret_cast(0x7fbfdfeff000); // make sure this is 4kb aligned or you are going to be meeting allah... - __declspec(allocate(".pml4")) - inline pml4e pml4[512]; + __declspec(allocate(".pml4")) inline pml4e pml4[512]; // translate vmxroot address's... auto translate(virt_addr_t virt_addr) -> u64; diff --git a/vmcs.cpp b/vmcs.cpp index 60569ac..139f385 100644 --- a/vmcs.cpp +++ b/vmcs.cpp @@ -144,44 +144,45 @@ namespace vmcs auto setup_controls() -> void { - ia32_vmx_true_ctls_register msr_fix_value; - ia32_vmx_pinbased_ctls_register pinbased_ctls; - ia32_vmx_procbased_ctls_register procbased_ctls; - ia32_vmx_procbased_ctls2_register procbased_ctls2; - ia32_vmx_entry_ctls_register entry_ctls; - ia32_vmx_exit_ctls_register exit_ctls; - ia32_vmx_basic_register vmx_basic; - - vmx_basic.flags = __readmsr(IA32_VMX_BASIC); - pinbased_ctls.flags = NULL; - procbased_ctls.flags = NULL; - procbased_ctls2.flags = NULL; - entry_ctls.flags = NULL; - exit_ctls.flags = NULL; + ia32_vmx_true_ctls_register msr_fix_value{}; + ia32_vmx_pinbased_ctls_register pinbased_ctls{}; + ia32_vmx_procbased_ctls_register procbased_ctls{}; + ia32_vmx_procbased_ctls2_register procbased_ctls2{}; + ia32_vmx_entry_ctls_register entry_ctls{}; + ia32_vmx_exit_ctls_register exit_ctls{}; + ia32_vmx_basic_register vmx_basic{ __readmsr(IA32_VMX_BASIC) }; + + pinbased_ctls.nmi_exiting = true; + pinbased_ctls.virtual_nmi = true; + + procbased_ctls.activate_secondary_controls = true; + exit_ctls.host_address_space_size = true; + + entry_ctls.ia32e_mode_guest = true; + entry_ctls.conceal_vmx_from_pt = true; + + procbased_ctls2.enable_rdtscp = true; + procbased_ctls2.enable_xsaves = true; + procbased_ctls2.conceal_vmx_from_pt = true; if (vmx_basic.vmx_controls) { msr_fix_value.flags = __readmsr(IA32_VMX_TRUE_PINBASED_CTLS); - pinbased_ctls.nmi_exiting = true; pinbased_ctls.flags &= msr_fix_value.allowed_1_settings; pinbased_ctls.flags |= msr_fix_value.allowed_0_settings; __vmx_vmwrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, pinbased_ctls.flags); msr_fix_value.flags = __readmsr(IA32_VMX_TRUE_PROCBASED_CTLS); - procbased_ctls.activate_secondary_controls = true; procbased_ctls.flags &= msr_fix_value.allowed_1_settings; procbased_ctls.flags |= msr_fix_value.allowed_0_settings; __vmx_vmwrite(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, procbased_ctls.flags); msr_fix_value.flags = __readmsr(IA32_VMX_TRUE_ENTRY_CTLS); - entry_ctls.ia32e_mode_guest = true; - entry_ctls.conceal_vmx_from_pt = true; entry_ctls.flags &= msr_fix_value.allowed_1_settings; entry_ctls.flags |= msr_fix_value.allowed_0_settings; __vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, entry_ctls.flags); msr_fix_value.flags = __readmsr(IA32_VMX_TRUE_EXIT_CTLS); - exit_ctls.host_address_space_size = true; exit_ctls.flags &= msr_fix_value.allowed_1_settings; exit_ctls.flags |= msr_fix_value.allowed_0_settings; __vmx_vmwrite(VMCS_CTRL_VMEXIT_CONTROLS, exit_ctls.flags); @@ -189,36 +190,27 @@ namespace vmcs else { msr_fix_value.flags = __readmsr(IA32_VMX_PINBASED_CTLS); - pinbased_ctls.nmi_exiting = true; pinbased_ctls.flags &= msr_fix_value.allowed_1_settings; pinbased_ctls.flags |= msr_fix_value.allowed_0_settings; __vmx_vmwrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, pinbased_ctls.flags); msr_fix_value.flags = __readmsr(IA32_VMX_PROCBASED_CTLS); - procbased_ctls.activate_secondary_controls = true; procbased_ctls.flags &= msr_fix_value.allowed_1_settings; procbased_ctls.flags |= msr_fix_value.allowed_0_settings; __vmx_vmwrite(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, procbased_ctls.flags); msr_fix_value.flags = __readmsr(IA32_VMX_ENTRY_CTLS); - entry_ctls.ia32e_mode_guest = true; - entry_ctls.conceal_vmx_from_pt = true; entry_ctls.flags &= msr_fix_value.allowed_1_settings; entry_ctls.flags |= msr_fix_value.allowed_0_settings; __vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, entry_ctls.flags); msr_fix_value.flags = __readmsr(IA32_VMX_EXIT_CTLS); - exit_ctls.host_address_space_size = true; - exit_ctls.conceal_vmx_from_pt = true; exit_ctls.flags &= msr_fix_value.allowed_1_settings; exit_ctls.flags |= msr_fix_value.allowed_0_settings; __vmx_vmwrite(VMCS_CTRL_VMEXIT_CONTROLS, exit_ctls.flags); } msr_fix_value.flags = __readmsr(IA32_VMX_PROCBASED_CTLS2); - procbased_ctls2.enable_rdtscp = true; - procbased_ctls2.enable_xsaves = true; - procbased_ctls2.conceal_vmx_from_pt = true; procbased_ctls2.flags &= msr_fix_value.allowed_1_settings; procbased_ctls2.flags |= msr_fix_value.allowed_0_settings; __vmx_vmwrite(VMCS_CTRL_SECONDARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, procbased_ctls2.flags); diff --git a/vmxexit_handler.asm b/vmxexit_handler.asm index 6fb97ec..1ab295e 100644 --- a/vmxexit_handler.asm +++ b/vmxexit_handler.asm @@ -1,4 +1,5 @@ extern exit_handler : proc +extern vmresume_failure : proc .code vmxlaunch_processor proc @@ -99,5 +100,7 @@ vmxexit_handler proc pop rax vmresume + call vmresume_failure + hlt vmxexit_handler endp end \ No newline at end of file diff --git a/vmxexit_handler.h b/vmxexit_handler.h index 7dc8978..b404baa 100644 --- a/vmxexit_handler.h +++ b/vmxexit_handler.h @@ -60,6 +60,7 @@ typedef struct _vmcall_command_t } vmcall_command_t, * pvmcall_command_t; extern "C" auto vmxexit_handler() -> void; +extern "C" auto vmresume_failure() -> void; extern "C" auto exit_handler(hv::pguest_registers regs) -> void; auto get_command(u64 dirbase, u64 command_ptr) -> vmcall_command_t; diff --git a/vmxlaunch.cpp b/vmxlaunch.cpp index 52f22f3..fc2973d 100644 --- a/vmxlaunch.cpp +++ b/vmxlaunch.cpp @@ -33,10 +33,15 @@ auto vmxlaunch::init_vmcs(cr3 cr3_value) -> void reinterpret_cast(ExAllocatePool(NonPagedPool, PAGE_SIZE * HOST_STACK_PAGES)) + (PAGE_SIZE * HOST_STACK_PAGES); - vcpu->gdt[segment_selector{ readtr() }.idx].base_address_upper = tss.upper; - vcpu->gdt[segment_selector{ readtr() }.idx].base_address_high = tss.high; - vcpu->gdt[segment_selector{ readtr() }.idx].base_address_middle = tss.middle; - vcpu->gdt[segment_selector{ readtr() }.idx].base_address_low = tss.low; + vcpu->tss.interrupt_stack_table[idt::ist_idx::nmi] = + reinterpret_cast(ExAllocatePool(NonPagedPool, + PAGE_SIZE * HOST_STACK_PAGES)) + (PAGE_SIZE * HOST_STACK_PAGES); + + const auto tr_idx = segment_selector{ readtr() }.idx; + vcpu->gdt[tr_idx].base_address_upper = tss.upper; + vcpu->gdt[tr_idx].base_address_high = tss.high; + vcpu->gdt[tr_idx].base_address_middle = tss.middle; + vcpu->gdt[tr_idx].base_address_low = tss.low; vmcs::setup_host(&vmxexit_handler, vcpu->host_stack, cr3_value, (u64)vcpu->gdt); @@ -48,9 +53,6 @@ auto vmxlaunch::init_vmcs(cr3 cr3_value) -> void auto vmxlaunch::launch() -> void { const auto vmlaunch_result = vmxlaunch_processor(); - DBG_PRINT("vmxlaunch for processor: %d\n", KeGetCurrentProcessorNumber()); - DBG_PRINT(" - vmxlaunch result: 0x%x\n", vmlaunch_result); - if (vmlaunch_result != VMX_LAUNCH_SUCCESS) { u64 vmxerror;