diff --git a/bluepill.sln b/bluepill.sln index 8823095..c023079 100644 --- a/bluepill.sln +++ b/bluepill.sln @@ -5,18 +5,30 @@ VisualStudioVersion = 16.0.30621.155 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bluepill", "bluepill.vcxproj", "{881CCCA6-80EB-486F-8923-4F4B7DD41F9A}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo", "demo\demo.vcxproj", "{A3D028D7-1650-4036-9FB0-4B8CC16268FE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Debug|x64.ActiveCfg = Debug|x64 {881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Debug|x64.Build.0 = Debug|x64 {881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Debug|x64.Deploy.0 = Debug|x64 + {881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Debug|x86.ActiveCfg = Debug|x64 {881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Release|x64.ActiveCfg = Release|x64 {881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Release|x64.Build.0 = Release|x64 {881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Release|x64.Deploy.0 = Release|x64 + {881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Release|x86.ActiveCfg = Release|x64 + {A3D028D7-1650-4036-9FB0-4B8CC16268FE}.Debug|x64.ActiveCfg = Debug|x64 + {A3D028D7-1650-4036-9FB0-4B8CC16268FE}.Debug|x64.Build.0 = Debug|x64 + {A3D028D7-1650-4036-9FB0-4B8CC16268FE}.Debug|x86.ActiveCfg = Debug|x64 + {A3D028D7-1650-4036-9FB0-4B8CC16268FE}.Release|x64.ActiveCfg = Release|x64 + {A3D028D7-1650-4036-9FB0-4B8CC16268FE}.Release|x64.Build.0 = Release|x64 + {A3D028D7-1650-4036-9FB0-4B8CC16268FE}.Release|x86.ActiveCfg = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/bluepill.vcxproj b/bluepill.vcxproj index 94f6559..e716e20 100644 --- a/bluepill.vcxproj +++ b/bluepill.vcxproj @@ -85,6 +85,7 @@ + @@ -92,6 +93,7 @@ + diff --git a/bluepill.vcxproj.filters b/bluepill.vcxproj.filters index 85c041b..cab2d58 100644 --- a/bluepill.vcxproj.filters +++ b/bluepill.vcxproj.filters @@ -29,6 +29,9 @@ Source Files + + Source Files + @@ -52,6 +55,9 @@ Header Files + + Header Files + diff --git a/demo/demo.vcxproj b/demo/demo.vcxproj new file mode 100644 index 0000000..452255e --- /dev/null +++ b/demo/demo.vcxproj @@ -0,0 +1,96 @@ + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {a3d028d7-1650-4036-9fb0-4b8cc16268fe} + demo + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + true + + + false + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + Document + + + + + + + + + + \ No newline at end of file diff --git a/demo/demo.vcxproj.filters b/demo/demo.vcxproj.filters new file mode 100644 index 0000000..a921897 --- /dev/null +++ b/demo/demo.vcxproj.filters @@ -0,0 +1,28 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + + + Source Files + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/demo/demo.vcxproj.user b/demo/demo.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/demo/demo.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/demo/hypercall.asm b/demo/hypercall.asm new file mode 100644 index 0000000..8d1bb96 --- /dev/null +++ b/demo/hypercall.asm @@ -0,0 +1,6 @@ +.code +hypercall proc + cpuid + ret +hypercall endp +end \ No newline at end of file diff --git a/demo/hypercall.h b/demo/hypercall.h new file mode 100644 index 0000000..ce3a6f7 --- /dev/null +++ b/demo/hypercall.h @@ -0,0 +1,20 @@ +#pragma once +#include +#include + +using u8 = unsigned char; +using u16 = unsigned short; +using u32 = unsigned int; +using u64 = unsigned long long; +using u128 = __m128; + +using s8 = char; +using s16 = short; +using s32 = int; +using s64 = long long; + +namespace bluepill +{ + constexpr auto key = 0xC0FFEE; + extern "C" u64 hypercall(u64 key); +} \ No newline at end of file diff --git a/demo/main.cpp b/demo/main.cpp new file mode 100644 index 0000000..44eb2c7 --- /dev/null +++ b/demo/main.cpp @@ -0,0 +1,8 @@ +#include +#include "hypercall.h" + +int main() +{ + std::printf("hypercall result: 0x%x\n", bluepill::hypercall(bluepill::key)); + std::getchar(); +} \ No newline at end of file diff --git a/entry.cpp b/entry.cpp index 564ad15..e9dd4e9 100644 --- a/entry.cpp +++ b/entry.cpp @@ -4,34 +4,8 @@ auto driver_unload( PDRIVER_OBJECT driver_object ) -> void { - // TODO vmcall and ask HV to vmxoff... - KeIpiGenericCall( - [](ULONG_PTR) -> ULONG_PTR - { - __vmx_off(); - hv::cr4_t cr4 = { __readcr4() }; - cr4.vmx_enable = false; - __writecr4(cr4.flags); - - hv::ia32_feature_control_msr_t feature_msr = { __readmsr(IA32_FEATURE_CONTROL) }; - feature_msr.bits.vmxon_outside_smx = false; - feature_msr.bits.lock = false; - __writemsr(IA32_FEATURE_CONTROL, feature_msr.control); - return NULL; - }, NULL - ); - - for (auto idx = 0u; idx < vmxon::g_vmx_ctx->vcpu_num; ++idx) - { - MmFreeContiguousMemory(vmxon::g_vmx_ctx->vcpus[idx]->vmcs); - MmFreeContiguousMemory(vmxon::g_vmx_ctx->vcpus[idx]->vmxon); - - ExFreePool((void*)vmxon::g_vmx_ctx->vcpus[idx]->host_stack); - ExFreePool(vmxon::g_vmx_ctx->vcpus[idx]); - } - - ExFreePool(vmxon::g_vmx_ctx->vcpus); - ExFreePool(vmxon::g_vmx_ctx); + // test to see if invalid opcode happens... + __vmx_off(); } auto driver_entry( diff --git a/exit_handler.cpp b/exit_handler.cpp index 18408ae..cceca94 100644 --- a/exit_handler.cpp +++ b/exit_handler.cpp @@ -4,23 +4,135 @@ auto exit_handler(hv::pguest_registers regs) -> void { u64 exit_reason; __vmx_vmread(VMCS_EXIT_REASON, &exit_reason); - __debugbreak(); switch (exit_reason) { case VMX_EXIT_REASON_EXECUTE_CPUID: - case VMX_EXIT_REASON_EXECUTE_INVLPG: + { + if (regs->rcx == 0xC0FFEE) + { + regs->rax = 0xC0FFEE; + // just a demo... + } + else + { + int result[4]; + __cpuid(result, regs->rax); + regs->rax = result[0]; + regs->rbx = result[1]; + regs->rcx = result[2]; + regs->rdx = result[3]; + } + break; + } case VMX_EXIT_REASON_EXECUTE_XSETBV: - case VMX_EXIT_REASON_EXECUTE_HLT: - case VMX_EXIT_REASON_EXECUTE_VMCALL: - case VMX_EXIT_REASON_EXECUTE_VMREAD: + { + hv::msr_split value; + value.high = regs->rdx; + value.low = regs->rax; + + __try + { + /* + EXCEPTION WARNING!: (will need to handle SEH in my IDT) + #GP If the current privilege level is not 0. + If an invalid XCR is specified in ECX. + If the value in EDX:EAX sets bits that are reserved in the XCR specified by ECX. + If an attempt is made to clear bit 0 of XCR0. + If an attempt is made to set XCR0[2:1] to 10b. + + #UD If CPUID.01H:ECX.XSAVE[bit 26] = 0. + If CR4.OSXSAVE[bit 18] = 0. + If the LOCK prefix is used. + */ + _xsetbv(regs->rcx, value.value); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + vmentry_interrupt_information interrupt{}; + interrupt.flags = interruption_type::software_interrupt; + interrupt.vector = EXCEPTION_GP_FAULT; + interrupt.valid = true; + __vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags); + } + break; + } + case VMX_EXIT_REASON_EXECUTE_RDMSR: + { + __try + { + /* + EXCEPTION WARNING!: (will need to handle SEH in my IDT) + #GP(0) If the current privilege level is not 0. + If the value in ECX specifies a reserved or unimplemented MSR address. + #UD If the LOCK prefix is used. + */ + const auto result = + hv::msr_split{ __readmsr(regs->rcx) }; + + regs->rdx = result.high; + regs->rax = result.low; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + vmentry_interrupt_information interrupt{}; + interrupt.flags = interruption_type::software_interrupt; + interrupt.vector = EXCEPTION_GP_FAULT; + interrupt.valid = true; + __vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags); + } + break; + } + case VMX_EXIT_REASON_EXECUTE_WRMSR: + { + hv::msr_split value; + value.low = regs->rax; + value.high = regs->rdx; + + __try + { + __writemsr(regs->rcx, value.value); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + /* + EXCEPTION WARNING!: (will need to handle SEH in my IDT) + #GP(0) If the current privilege level is not 0. + If the value in ECX specifies a reserved or unimplemented MSR address. + #UD If the LOCK prefix is used. + */ + vmentry_interrupt_information interrupt{}; + interrupt.flags = interruption_type::software_interrupt; + interrupt.vector = EXCEPTION_GP_FAULT; + interrupt.valid = true; + __vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags); + } + break; + } case VMX_EXIT_REASON_EXECUTE_VMWRITE: - case VMX_EXIT_REASON_EXECUTE_VMPTRLD: + case VMX_EXIT_REASON_EXECUTE_VMREAD: case VMX_EXIT_REASON_EXECUTE_VMPTRST: + case VMX_EXIT_REASON_EXECUTE_VMPTRLD: case VMX_EXIT_REASON_EXECUTE_VMCLEAR: - case VMX_EXIT_REASON_EXECUTE_VMLAUNCH: - case VMX_EXIT_REASON_EXECUTE_RDTSC: + case VMX_EXIT_REASON_EXECUTE_VMXOFF: + case VMX_EXIT_REASON_EXECUTE_VMXON: + case VMX_EXIT_REASON_EXECUTE_VMCALL: + { + vmentry_interrupt_information interrupt{}; + interrupt.flags = interruption_type::software_interrupt; + interrupt.vector = EXCEPTION_INVALID_OPCODE; + interrupt.valid = true; + __vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags); + break; + } default: + // TODO: check out the vmexit reason and add support for it... + __debugbreak(); break; } + + size_t rip, exec_len; + __vmx_vmread(VMCS_GUEST_RIP, &rip); + __vmx_vmread(VMCS_VMEXIT_INSTRUCTION_LENGTH, &exec_len); + __vmx_vmwrite(VMCS_GUEST_RIP, rip + exec_len); } \ No newline at end of file diff --git a/hv_types.hpp b/hv_types.hpp index fb48330..c3e1edb 100644 --- a/hv_types.hpp +++ b/hv_types.hpp @@ -50,6 +50,8 @@ namespace hv u128 xmm14; u128 xmm15; + u64 padding_8b; + u64 r15; u64 r14; u64 r13; @@ -63,9 +65,20 @@ namespace hv u64 rsi; u64 rdx; u64 rcx; + u64 rbx; u64 rax; } guest_registers, * pguest_registers; + union msr_split + { + u64 value; + struct + { + u64 low : 32; + u64 high : 32; + }; + }; + union ia32_efer_t { unsigned __int64 control; diff --git a/ia32.hpp b/ia32.hpp index 52ba3e1..eb01a7b 100644 --- a/ia32.hpp +++ b/ia32.hpp @@ -251,6 +251,7 @@ typedef union typedef union { + uint64_t flags; struct { uint64_t reserved1 : 3; @@ -300,8 +301,6 @@ typedef union #define CR3_ADDRESS_OF_PAGE_DIRECTORY(_) (((_) >> 12) & 0xFFFFFFFFF) uint64_t reserved3 : 16; }; - - uint64_t flags; } cr3; typedef union @@ -11518,6 +11517,7 @@ typedef union #define IA32_VMX_TRUE_ENTRY_CTLS 0x00000490 typedef union { + uint64_t flags; struct { /** @@ -11540,8 +11540,6 @@ typedef union #define IA32_VMX_TRUE_CTLS_ALLOWED_1_SETTINGS_MASK 0xFFFFFFFF #define IA32_VMX_TRUE_CTLS_ALLOWED_1_SETTINGS(_) (((_) >> 32) & 0xFFFFFFFF) }; - - uint64_t flags; } ia32_vmx_true_ctls_register; /** @@ -20156,6 +20154,7 @@ typedef enum */ typedef union { + uint32_t flags; struct { /** @@ -20204,8 +20203,6 @@ typedef union #define VMENTRY_INTERRUPT_INFORMATION_VALID_MASK 0x01 #define VMENTRY_INTERRUPT_INFORMATION_VALID(_) (((_) >> 31) & 0x01) }; - - uint32_t flags; } vmentry_interrupt_information; /** diff --git a/mm.cpp b/mm.cpp new file mode 100644 index 0000000..b739c2f --- /dev/null +++ b/mm.cpp @@ -0,0 +1,6 @@ +#include "mm.hpp" + +namespace mm +{ + +} \ No newline at end of file diff --git a/mm.hpp b/mm.hpp new file mode 100644 index 0000000..c12bb4c --- /dev/null +++ b/mm.hpp @@ -0,0 +1,125 @@ +#pragma once +#include "hv_types.hpp" + +// the pml4 itself is inside of the HV... +#pragma section(".pml4", read, write) + +namespace mm +{ + typedef union _virt_addr_t + { + void* value; + struct + { + u64 offset : 12; + u64 pt_index : 9; + u64 pd_index : 9; + u64 pdpt_index : 9; + u64 pml4_index : 9; + u64 reserved : 16; + }; + } virt_addr_t, * pvirt_addr_t; + + typedef union _pml4e + { + u64 value; + struct + { + u64 present : 1; // Must be 1, region invalid if 0. + u64 rw : 1; // If 0, writes not allowed. + u64 user_supervisor : 1; // If 0, user-mode accesses not allowed. + u64 PageWriteThrough : 1; // Determines the memory type used to access PDPT. + u64 page_cache : 1; // Determines the memory type used to access PDPT. + u64 accessed : 1; // If 0, this entry has not been used for translation. + u64 Ignored1 : 1; + u64 page_size : 1; // Must be 0 for PML4E. + u64 Ignored2 : 4; + u64 pfn : 36; // The page frame number of the PDPT of this PML4E. + u64 Reserved : 4; + u64 Ignored3 : 11; + u64 nx : 1; // If 1, instruction fetches not allowed. + }; + } pml4e, * ppml4e; + + typedef union _pdpte + { + u64 value; + struct + { + u64 present : 1; // Must be 1, region invalid if 0. + u64 rw : 1; // If 0, writes not allowed. + u64 user_supervisor : 1; // If 0, user-mode accesses not allowed. + u64 PageWriteThrough : 1; // Determines the memory type used to access PD. + u64 page_cache : 1; // Determines the memory type used to access PD. + u64 accessed : 1; // If 0, this entry has not been used for translation. + u64 Ignored1 : 1; + u64 page_size : 1; // If 1, this entry maps a 1GB page. + u64 Ignored2 : 4; + u64 pfn : 36; // The page frame number of the PD of this PDPTE. + u64 Reserved : 4; + u64 Ignored3 : 11; + u64 nx : 1; // If 1, instruction fetches not allowed. + }; + } pdpte, * ppdpte; + + typedef union _pde + { + u64 value; + struct + { + u64 present : 1; // Must be 1, region invalid if 0. + u64 rw : 1; // If 0, writes not allowed. + u64 user_supervisor : 1; // If 0, user-mode accesses not allowed. + u64 PageWriteThrough : 1; // Determines the memory type used to access PT. + u64 page_cache : 1; // Determines the memory type used to access PT. + u64 accessed : 1; // If 0, this entry has not been used for translation. + u64 Ignored1 : 1; + u64 page_size : 1; // If 1, this entry maps a 2MB page. + u64 Ignored2 : 4; + u64 pfn : 36; // The page frame number of the PT of this PDE. + u64 Reserved : 4; + u64 Ignored3 : 11; + u64 nx : 1; // If 1, instruction fetches not allowed. + }; + } pde, * ppde; + + typedef union _pte + { + u64 value; + struct + { + u64 present : 1; // Must be 1, region invalid if 0. + u64 rw : 1; // If 0, writes not allowed. + u64 user_supervisor : 1; // If 0, user-mode accesses not allowed. + u64 PageWriteThrough : 1; // Determines the memory type used to access the memory. + u64 page_cache : 1; // Determines the memory type used to access the memory. + u64 accessed : 1; // If 0, this entry has not been used for translation. + u64 Dirty : 1; // If 0, the memory backing this page has not been written to. + u64 PageAccessType : 1; // Determines the memory type used to access the memory. + u64 Global : 1; // If 1 and the PGE bit of CR4 is set, translations are global. + u64 Ignored2 : 3; + u64 pfn : 36; // The page frame number of the backing physical page. + u64 reserved : 4; + u64 Ignored3 : 7; + u64 ProtectionKey : 4; // If the PKE bit of CR4 is set, determines the protection key. + u64 nx : 1; // If 1, instruction fetches not allowed. + }; + } pte, * ppte; + + enum class map_type{ dest, src }; + + constexpr auto self_ref_index = 254; + inline const ppml4e vmxroot_pml4 = reinterpret_cast(0x7f0000000000); + + // make sure this is 4kb aligned or you are going to be meeting allah... + __declspec(allocate(".pml4")) inline pml4e pml4[512]; + + // translate vmxroot address's... + auto translate(virt_addr_t virt_addr) -> u64; + + // translate guest virtual addresses... + auto translate(virt_addr_t virt_addr, u64 pml4_phys, map_type type = map_type::src) -> u64; + + // map a page into vmxroot address space... + auto map_page(u64 phys_addr, map_type type) -> u64; +} \ No newline at end of file diff --git a/segment.cpp b/segment.cpp index 0400074..6a6b564 100644 --- a/segment.cpp +++ b/segment.cpp @@ -21,8 +21,7 @@ namespace segment auto get_info(const segment_descriptor_register_64& gdt_value, segment_selector selector) -> hv::segment_info_ctx { - hv::segment_info_ctx segment_info; - memset(&segment_info, NULL, sizeof segment_info); + hv::segment_info_ctx segment_info{}; const auto segment_descriptor = reinterpret_cast( diff --git a/vmcs.cpp b/vmcs.cpp index 89f9e78..53c6f3d 100644 --- a/vmcs.cpp +++ b/vmcs.cpp @@ -1,4 +1,5 @@ #include "vmcs.hpp" +#include "mm.hpp" namespace vmcs { @@ -10,17 +11,34 @@ namespace vmcs __sidt(&idt_value); _sgdt(&gdt_value); - // use guest values for now... later on CR3 will be custom... + cr3 cr3_value; + cr3_value.flags = __readcr3(); + cr3_value.address_of_page_directory = + (MmGetPhysicalAddress(mm::pml4).QuadPart >> 12); + + memset(mm::pml4, NULL, sizeof mm::pml4); + mm::pml4[mm::self_ref_index].pfn = cr3_value.address_of_page_directory; + mm::pml4[mm::self_ref_index].present = true; + mm::pml4[mm::self_ref_index].rw = true; + mm::pml4[mm::self_ref_index].user_supervisor = false; + + PHYSICAL_ADDRESS current_pml4; + current_pml4.QuadPart = + (cr3{ __readcr3() }.address_of_page_directory << 12); + + const auto kernel_pml4 = + reinterpret_cast( + MmGetVirtualForPhysical(current_pml4)); + + // vmxroot will have the same "address space" as the current one being executed in... + memcpy(&mm::pml4[255], &kernel_pml4[255], sizeof(mm::pml4e) * 255); + __vmx_vmwrite(VMCS_HOST_CR0, __readcr0()); - __vmx_vmwrite(VMCS_HOST_CR3, __readcr3()); + __vmx_vmwrite(VMCS_HOST_CR3, cr3_value.flags); __vmx_vmwrite(VMCS_HOST_CR4, __readcr4()); - DBG_PRINT("host cr0: 0x%p\n", __readcr0()); - DBG_PRINT("host cr3: 0x%p\n", __readcr3()); - DBG_PRINT("host cr4: 0x%p\n", __readcr4()); - // stack growns down... - __vmx_vmwrite(VMCS_HOST_RSP, host_rsp + (PAGE_SIZE * HOST_STACK_PAGES) - 0x10); + __vmx_vmwrite(VMCS_HOST_RSP, host_rsp + (PAGE_SIZE * HOST_STACK_PAGES)); __vmx_vmwrite(VMCS_HOST_RIP, reinterpret_cast(host_rip)); __vmx_vmwrite(VMCS_HOST_GDTR_BASE, gdt_value.base_address); @@ -80,49 +98,19 @@ namespace vmcs __vmx_vmwrite(VMCS_GUEST_CR3, __readcr3()); __vmx_vmwrite(VMCS_GUEST_CR4, __readcr4()); - DBG_PRINT("guest cr0: 0x%p\n", __readcr0()); - DBG_PRINT("guest cr3: 0x%p\n", __readcr3()); - DBG_PRINT("guest cr4: 0x%p\n", __readcr4()); - __vmx_vmwrite(VMCS_GUEST_VMCS_LINK_POINTER, ~0ULL); __vmx_vmwrite(VMCS_GUEST_GDTR_BASE, gdt_value.base_address); __vmx_vmwrite(VMCS_GUEST_GDTR_LIMIT, gdt_value.limit); - DBG_PRINT("guest gdt base address: 0x%p\n", gdt_value.base_address); - DBG_PRINT("guest gdt limit: 0x%x\n", gdt_value.limit); - __vmx_vmwrite(VMCS_GUEST_IDTR_BASE, idt_value.base_address); __vmx_vmwrite(VMCS_GUEST_IDTR_LIMIT, idt_value.limit); - DBG_PRINT("guest idt base address: 0x%p\n", idt_value.base_address); - DBG_PRINT("guest idt limit: 0x%x\n", idt_value.limit); - __vmx_vmwrite(VMCS_GUEST_RFLAGS, __readeflags()); __vmx_vmwrite(VMCS_GUEST_DR7, __readdr(7)); - DBG_PRINT("guest rflags: 0x%p\n", __readeflags()); - DBG_PRINT("guest debug register 7: 0x%p\n", __readdr(7)); - const auto [es_rights, es_limit, es_base] = segment::get_info(gdt_value, segment_selector{ reades() }); - DBG_PRINT("es selector: 0x%p\n", reades()); - DBG_PRINT(" - es.index: %d\n", segment_selector{ reades() }.index); - DBG_PRINT(" - es.request_privilege_level: %d\n", segment_selector{ reades() }.request_privilege_level); - DBG_PRINT(" - es.table: %d\n", segment_selector{ reades() }.table); - DBG_PRINT("es base address: 0x%p\n", es_base); - DBG_PRINT("es limit: 0x%p\n", es_limit); - DBG_PRINT("es rights: 0x%p\n", es_rights.flags); - DBG_PRINT(" - es_rights.available_bit: %d\n", es_rights.available_bit); - DBG_PRINT(" - es_rights.default_big: %d\n", es_rights.default_big); - DBG_PRINT(" - es_rights.descriptor_privilege_level: %d\n", es_rights.descriptor_privilege_level); - DBG_PRINT(" - es_rights.descriptor_type: %d\n", es_rights.descriptor_type); - DBG_PRINT(" - es_rights.granularity: %d\n", es_rights.granularity); - DBG_PRINT(" - es_rights.long_mode: %d\n", es_rights.long_mode); - DBG_PRINT(" - es_rights.present: %d\n", es_rights.present); - DBG_PRINT(" - es_rights.type: %d\n", es_rights.type); - DBG_PRINT(" - es_rights.unusable: %d\n", es_rights.unusable); - __vmx_vmwrite(VMCS_GUEST_ES_BASE, es_base); __vmx_vmwrite(VMCS_GUEST_ES_LIMIT, es_limit); __vmx_vmwrite(VMCS_GUEST_ES_SELECTOR, reades()); @@ -131,23 +119,6 @@ namespace vmcs const auto [fs_rights, fs_limit, fs_base] = segment::get_info(gdt_value, segment_selector{ readfs() }); - DBG_PRINT("fs selector: 0x%p\n", readfs()); - DBG_PRINT(" - fs.index: %d\n", segment_selector{ readfs() }.index); - DBG_PRINT(" - fs.request_privilege_level: %d\n", segment_selector{ readfs() }.request_privilege_level); - DBG_PRINT(" - fs.table: %d\n", segment_selector{ readfs() }.table); - DBG_PRINT("fs base address: 0x%p\n", fs_base); - DBG_PRINT("fs limit: 0x%p\n", fs_limit); - DBG_PRINT("fs rights: 0x%p\n", fs_rights.flags); - DBG_PRINT(" - fs_rights.available_bit: %d\n", fs_rights.available_bit); - DBG_PRINT(" - fs_rights.default_big: %d\n", fs_rights.default_big); - DBG_PRINT(" - fs_rights.descriptor_privilege_level: %d\n", fs_rights.descriptor_privilege_level); - DBG_PRINT(" - fs_rights.descriptor_type: %d\n", fs_rights.descriptor_type); - DBG_PRINT(" - fs_rights.granularity: %d\n", fs_rights.granularity); - DBG_PRINT(" - fs_rights.long_mode: %d\n", fs_rights.long_mode); - DBG_PRINT(" - fs_rights.present: %d\n", fs_rights.present); - DBG_PRINT(" - fs_rights.type: %d\n", fs_rights.type); - DBG_PRINT(" - fs_rights.unusable: %d\n", fs_rights.unusable); - __vmx_vmwrite(VMCS_GUEST_FS_BASE, fs_base); __vmx_vmwrite(VMCS_GUEST_FS_LIMIT, fs_limit); __vmx_vmwrite(VMCS_GUEST_FS_SELECTOR, readfs()); @@ -156,23 +127,6 @@ namespace vmcs const auto [gs_rights, gs_limit, gs_base] = segment::get_info(gdt_value, segment_selector{ readgs() }); - DBG_PRINT("gs selector: 0x%p\n", readgs()); - DBG_PRINT(" - gs.index: %d\n", segment_selector{ readgs() }.index); - DBG_PRINT(" - gs.request_privilege_level: %d\n", segment_selector{ readgs() }.request_privilege_level); - DBG_PRINT(" - gs.table: %d\n", segment_selector{ readgs() }.table); - DBG_PRINT("gs base address: 0x%p\n", gs_base); - DBG_PRINT("gs limit: 0x%p\n", gs_limit); - DBG_PRINT("gs rights: 0x%p\n", gs_rights.flags); - DBG_PRINT(" - gs_rights.available_bit: %d\n", gs_rights.available_bit); - DBG_PRINT(" - gs_rights.default_big: %d\n", gs_rights.default_big); - DBG_PRINT(" - gs_rights.descriptor_privilege_level: %d\n", gs_rights.descriptor_privilege_level); - DBG_PRINT(" - gs_rights.descriptor_type: %d\n", gs_rights.descriptor_type); - DBG_PRINT(" - gs_rights.granularity: %d\n", gs_rights.granularity); - DBG_PRINT(" - gs_rights.long_mode: %d\n", gs_rights.long_mode); - DBG_PRINT(" - gs_rights.present: %d\n", gs_rights.present); - DBG_PRINT(" - gs_rights.type: %d\n", gs_rights.type); - DBG_PRINT(" - gs_rights.unusable: %d\n", gs_rights.unusable); - __vmx_vmwrite(VMCS_GUEST_GS_BASE, gs_base); __vmx_vmwrite(VMCS_GUEST_GS_LIMIT, gs_limit); __vmx_vmwrite(VMCS_GUEST_GS_SELECTOR, readgs()); @@ -181,23 +135,6 @@ namespace vmcs const auto [ss_rights, ss_limit, ss_base] = segment::get_info(gdt_value, segment_selector{ readss() }); - DBG_PRINT("ss selector: 0x%p\n", readss()); - DBG_PRINT(" - ss.index: %d\n", segment_selector{ readss() }.index); - DBG_PRINT(" - ss.request_privilege_level: %d\n", segment_selector{ readss() }.request_privilege_level); - DBG_PRINT(" - ss.table: %d\n", segment_selector{ readss() }.table); - DBG_PRINT("ss base address: 0x%p\n", ss_base); - DBG_PRINT("ss limit: 0x%p\n", ss_limit); - DBG_PRINT("ss rights: 0x%p\n", ss_rights.flags); - DBG_PRINT(" - ss_rights.available_bit: %d\n", ss_rights.available_bit); - DBG_PRINT(" - ss_rights.default_big: %d\n", ss_rights.default_big); - DBG_PRINT(" - ss_rights.descriptor_privilege_level: %d\n", ss_rights.descriptor_privilege_level); - DBG_PRINT(" - ss_rights.descriptor_type: %d\n", ss_rights.descriptor_type); - DBG_PRINT(" - ss_rights.granularity: %d\n", ss_rights.granularity); - DBG_PRINT(" - ss_rights.long_mode: %d\n", ss_rights.long_mode); - DBG_PRINT(" - ss_rights.present: %d\n", ss_rights.present); - DBG_PRINT(" - ss_rights.type: %d\n", ss_rights.type); - DBG_PRINT(" - ss_rights.unusable: %d\n", ss_rights.unusable); - __vmx_vmwrite(VMCS_GUEST_SS_BASE, ss_base); __vmx_vmwrite(VMCS_GUEST_SS_LIMIT, ss_limit); __vmx_vmwrite(VMCS_GUEST_SS_SELECTOR, readss()); @@ -206,23 +143,6 @@ namespace vmcs const auto [cs_rights, cs_limit, cs_base] = segment::get_info(gdt_value, segment_selector{ readcs() }); - DBG_PRINT("cs selector: 0x%p\n", readcs()); - DBG_PRINT(" - cs.index: %d\n", segment_selector{ readcs() }.index); - DBG_PRINT(" - cs.request_privilege_level: %d\n", segment_selector{ readcs() }.request_privilege_level); - DBG_PRINT(" - cs.table: %d\n", segment_selector{ readcs() }.table); - DBG_PRINT("cs base address: 0x%p\n", cs_base); - DBG_PRINT("cs limit: 0x%p\n", cs_limit); - DBG_PRINT("cs rights: 0x%p\n", cs_rights.flags); - DBG_PRINT(" - cs_rights.available_bit: %d\n", cs_rights.available_bit); - DBG_PRINT(" - cs_rights.default_big: %d\n", cs_rights.default_big); - DBG_PRINT(" - cs_rights.descriptor_privilege_level: %d\n", cs_rights.descriptor_privilege_level); - DBG_PRINT(" - cs_rights.descriptor_type: %d\n", cs_rights.descriptor_type); - DBG_PRINT(" - cs_rights.granularity: %d\n", cs_rights.granularity); - DBG_PRINT(" - cs_rights.long_mode: %d\n", cs_rights.long_mode); - DBG_PRINT(" - cs_rights.present: %d\n", cs_rights.present); - DBG_PRINT(" - cs_rights.type: %d\n", cs_rights.type); - DBG_PRINT(" - cs_rights.unusable: %d\n", cs_rights.unusable); - __vmx_vmwrite(VMCS_GUEST_CS_BASE, cs_base); __vmx_vmwrite(VMCS_GUEST_CS_LIMIT, cs_limit); __vmx_vmwrite(VMCS_GUEST_CS_SELECTOR, readcs()); @@ -231,23 +151,6 @@ namespace vmcs const auto [ds_rights, ds_limit, ds_base] = segment::get_info(gdt_value, segment_selector{ readds() }); - DBG_PRINT("ds selector: 0x%p\n", readds()); - DBG_PRINT(" - ds.index: %d\n", segment_selector{ readds() }.index); - DBG_PRINT(" - ds.request_privilege_level: %d\n", segment_selector{ readds() }.request_privilege_level); - DBG_PRINT(" - ds.table: %d\n", segment_selector{ readds() }.table); - DBG_PRINT("ds base address: 0x%p\n", ds_base); - DBG_PRINT("ds limit: 0x%p\n", ds_limit); - DBG_PRINT("ds rights: 0x%p\n", ds_rights.flags); - DBG_PRINT(" - ds_rights.available_bit: %d\n", ds_rights.available_bit); - DBG_PRINT(" - ds_rights.default_big: %d\n", ds_rights.default_big); - DBG_PRINT(" - ds_rights.descriptor_privilege_level: %d\n", ds_rights.descriptor_privilege_level); - DBG_PRINT(" - ds_rights.descriptor_type: %d\n", ds_rights.descriptor_type); - DBG_PRINT(" - ds_rights.granularity: %d\n", ds_rights.granularity); - DBG_PRINT(" - ds_rights.long_mode: %d\n", ds_rights.long_mode); - DBG_PRINT(" - ds_rights.present: %d\n", ds_rights.present); - DBG_PRINT(" - ds_rights.type: %d\n", ds_rights.type); - DBG_PRINT(" - ds_rights.unusable: %d\n", ds_rights.unusable); - __vmx_vmwrite(VMCS_GUEST_DS_BASE, ds_base); __vmx_vmwrite(VMCS_GUEST_DS_LIMIT, ds_limit); __vmx_vmwrite(VMCS_GUEST_DS_SELECTOR, readds()); @@ -256,23 +159,6 @@ namespace vmcs const auto [tr_rights, tr_limit, tr_base] = segment::get_info(gdt_value, segment_selector{ readtr() }); - DBG_PRINT("tr selector: 0x%p\n", readtr()); - DBG_PRINT(" - tr.index: %d\n", segment_selector{ readtr() }.index); - DBG_PRINT(" - tr.request_privilege_level: %d\n", segment_selector{ readtr() }.request_privilege_level); - DBG_PRINT(" - tr.table: %d\n", segment_selector{ readtr() }.table); - DBG_PRINT("tr base address: 0x%p\n", tr_base); - DBG_PRINT("tr limit: 0x%p\n", tr_limit); - DBG_PRINT("tr rights: 0x%p\n", tr_rights.flags); - DBG_PRINT(" - tr_rights.available_bit: %d\n", tr_rights.available_bit); - DBG_PRINT(" - tr_rights.default_big: %d\n", tr_rights.default_big); - DBG_PRINT(" - tr_rights.descriptor_privilege_level: %d\n", tr_rights.descriptor_privilege_level); - DBG_PRINT(" - tr_rights.descriptor_type: %d\n", tr_rights.descriptor_type); - DBG_PRINT(" - tr_rights.granularity: %d\n", tr_rights.granularity); - DBG_PRINT(" - tr_rights.long_mode: %d\n", tr_rights.long_mode); - DBG_PRINT(" - tr_rights.present: %d\n", tr_rights.present); - DBG_PRINT(" - tr_rights.type: %d\n", tr_rights.type); - DBG_PRINT(" - tr_rights.unusable: %d\n", tr_rights.unusable); - __vmx_vmwrite(VMCS_GUEST_TR_BASE, tr_base); __vmx_vmwrite(VMCS_GUEST_TR_LIMIT, tr_limit); __vmx_vmwrite(VMCS_GUEST_TR_SELECTOR, readtr()); @@ -281,34 +167,13 @@ namespace vmcs const auto [ldt_rights, ldt_limit, ldt_base] = segment::get_info(gdt_value, segment_selector{ readldt() }); - DBG_PRINT("ldt selector: 0x%p\n", readldt()); - DBG_PRINT(" - ldt.index: %d\n", segment_selector{ readldt() }.index); - DBG_PRINT(" - ldt.request_privilege_level: %d\n", segment_selector{ readldt() }.request_privilege_level); - DBG_PRINT(" - ldt.table: %d\n", segment_selector{ readldt() }.table); - DBG_PRINT("ldt base address: 0x%p\n", tr_base); - DBG_PRINT("ldt limit: 0x%p\n", tr_limit); - DBG_PRINT("ldt rights: 0x%p\n", tr_rights.flags); - DBG_PRINT(" - ldt_rights.available_bit: %d\n", tr_rights.available_bit); - DBG_PRINT(" - ldt_rights.default_big: %d\n", tr_rights.default_big); - DBG_PRINT(" - ldt_rights.descriptor_privilege_level: %d\n", tr_rights.descriptor_privilege_level); - DBG_PRINT(" - ldt_rights.descriptor_type: %d\n", tr_rights.descriptor_type); - DBG_PRINT(" - ldt_rights.granularity: %d\n", tr_rights.granularity); - DBG_PRINT(" - ldt_rights.long_mode: %d\n", tr_rights.long_mode); - DBG_PRINT(" - ldt_rights.present: %d\n", tr_rights.present); - DBG_PRINT(" - ldt_rights.type: %d\n", tr_rights.type); - DBG_PRINT(" - ldt_rights.unusable: %d\n", tr_rights.unusable); - __vmx_vmwrite(VMCS_GUEST_LDTR_BASE, ldt_base); __vmx_vmwrite(VMCS_GUEST_LDTR_LIMIT, ldt_limit); __vmx_vmwrite(VMCS_GUEST_LDTR_SELECTOR, readldt()); __vmx_vmwrite(VMCS_GUEST_LDTR_ACCESS_RIGHTS, ldt_rights.flags); - __vmx_vmwrite(VMCS_GUEST_GS_BASE, __readmsr(IA32_GS_BASE)); - DBG_PRINT("guest gs base (from readmsr): 0x%p\n", __readmsr(IA32_GS_BASE)); - __vmx_vmwrite(VMCS_GUEST_ACTIVITY_STATE, 0); - __vmx_vmwrite(VMCS_GUEST_INTERRUPTIBILITY_STATE, 0); - __vmx_vmwrite(VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS, 0); + __vmx_vmwrite(VMCS_GUEST_GS_BASE, __readmsr(IA32_GS_BASE)); } auto setup_controls() -> void @@ -335,48 +200,12 @@ namespace vmcs pinbased_ctls.flags |= msr_fix_value.allowed_0_settings; __vmx_vmwrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, pinbased_ctls.flags); - DBG_PRINT("============================== pinbased vm-exit controls ==============================\n"); - DBG_PRINT(" - pinbased_ctls.activate_vmx_preemption_timer: %d\n", pinbased_ctls.activate_vmx_preemption_timer); - DBG_PRINT(" - pinbased_ctls.external_interrupt_exiting: %d\n", pinbased_ctls.external_interrupt_exiting); - DBG_PRINT(" - pinbased_ctls.nmi_exiting: %d\n", pinbased_ctls.nmi_exiting); - DBG_PRINT(" - pinbased_ctls.process_posted_interrupts: %d\n", pinbased_ctls.process_posted_interrupts); - DBG_PRINT(" - pinbased_ctls.virtual_nmi: %d\n", pinbased_ctls.virtual_nmi); - DBG_PRINT(" - pinbased_ctls.flags: 0x%x\n", pinbased_ctls.flags); - DBG_PRINT(" - IA32_VMX_TRUE_PINBASED_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings); - DBG_PRINT(" - IA32_VMX_TRUE_PINBASED_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings); - 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); - DBG_PRINT("============================== processor based vm-exit controls ==============================\n"); - DBG_PRINT(" - procbased_ctls.activate_secondary_controls: %d\n", procbased_ctls.activate_secondary_controls); - DBG_PRINT(" - procbased_ctls.cr3_load_exiting: %d\n", procbased_ctls.cr3_load_exiting); - DBG_PRINT(" - procbased_ctls.cr3_store_exiting: %d\n", procbased_ctls.cr3_store_exiting); - DBG_PRINT(" - procbased_ctls.cr8_load_exiting: %d\n", procbased_ctls.cr8_load_exiting); - DBG_PRINT(" - procbased_ctls.cr8_store_exiting: %d\n", procbased_ctls.cr8_store_exiting); - DBG_PRINT(" - procbased_ctls.hlt_exiting: %d\n", procbased_ctls.hlt_exiting); - DBG_PRINT(" - procbased_ctls.interrupt_window_exiting: %d\n", procbased_ctls.interrupt_window_exiting); - DBG_PRINT(" - procbased_ctls.invlpg_exiting: %d\n", procbased_ctls.invlpg_exiting); - DBG_PRINT(" - procbased_ctls.monitor_exiting: %d\n", procbased_ctls.monitor_exiting); - DBG_PRINT(" - procbased_ctls.monitor_trap_flag: %d\n", procbased_ctls.monitor_trap_flag); - DBG_PRINT(" - procbased_ctls.mov_dr_exiting: %d\n", procbased_ctls.mov_dr_exiting); - DBG_PRINT(" - procbased_ctls.mwait_exiting: %d\n", procbased_ctls.mwait_exiting); - DBG_PRINT(" - procbased_ctls.nmi_window_exiting: %d\n", procbased_ctls.nmi_window_exiting); - DBG_PRINT(" - procbased_ctls.pause_exiting: %d\n", procbased_ctls.pause_exiting); - DBG_PRINT(" - procbased_ctls.rdpmc_exiting: %d\n", procbased_ctls.rdpmc_exiting); - DBG_PRINT(" - procbased_ctls.rdtsc_exiting: %d\n", procbased_ctls.rdtsc_exiting); - DBG_PRINT(" - procbased_ctls.unconditional_io_exiting: %d\n", procbased_ctls.unconditional_io_exiting); - DBG_PRINT(" - procbased_ctls.use_io_bitmaps: %d\n", procbased_ctls.use_io_bitmaps); - DBG_PRINT(" - procbased_ctls.use_msr_bitmaps: %d\n", procbased_ctls.use_msr_bitmaps); - DBG_PRINT(" - procbased_ctls.use_tpr_shadow: %d\n", procbased_ctls.use_tpr_shadow); - DBG_PRINT(" - procbased_ctls.use_tsc_offsetting: %d\n", procbased_ctls.use_tsc_offsetting); - DBG_PRINT(" - procbased_ctls.flags: 0x%x\n", procbased_ctls.flags); - DBG_PRINT(" - IA32_VMX_TRUE_PROCBASED_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings); - DBG_PRINT(" - IA32_VMX_TRUE_PROCBASED_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings); - msr_fix_value.flags = __readmsr(IA32_VMX_TRUE_ENTRY_CTLS); entry_ctls.ia32e_mode_guest = true; entry_ctls.conceal_vmx_from_pt = true; @@ -384,43 +213,11 @@ namespace vmcs entry_ctls.flags |= msr_fix_value.allowed_0_settings; __vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, entry_ctls.flags); - DBG_PRINT("============================== vm-entry controls ==============================\n"); - DBG_PRINT(" - entry_ctls.conceal_vmx_from_pt: %d\n", entry_ctls.conceal_vmx_from_pt); - DBG_PRINT(" - entry_ctls.deactivate_dual_monitor_treatment: %d\n", entry_ctls.deactivate_dual_monitor_treatment); - DBG_PRINT(" - entry_ctls.entry_to_smm: %d\n", entry_ctls.entry_to_smm); - DBG_PRINT(" - entry_ctls.ia32e_mode_guest: %d\n", entry_ctls.ia32e_mode_guest); - DBG_PRINT(" - entry_ctls.load_cet_state: %d\n", entry_ctls.load_cet_state); - DBG_PRINT(" - entry_ctls.load_debug_controls: %d\n", entry_ctls.load_debug_controls); - DBG_PRINT(" - entry_ctls.load_ia32_bndcfgs: %d\n", entry_ctls.load_ia32_bndcfgs); - DBG_PRINT(" - entry_ctls.load_ia32_efer: %d\n", entry_ctls.load_ia32_efer); - DBG_PRINT(" - entry_ctls.load_ia32_pat: %d\n", entry_ctls.load_ia32_pat); - DBG_PRINT(" - entry_ctls.load_ia32_perf_global_ctrl: %d\n", entry_ctls.load_ia32_perf_global_ctrl); - DBG_PRINT(" - entry_ctls.load_ia32_rtit_ctl: %d\n", entry_ctls.load_ia32_rtit_ctl); - DBG_PRINT(" - entry_ctls.flags: 0x%x\n", entry_ctls.flags); - DBG_PRINT(" - IA32_VMX_TRUE_ENTRY_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings); - DBG_PRINT(" - IA32_VMX_TRUE_ENTRY_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings); - 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); - - DBG_PRINT("============================== vm-exit controls ==============================\n"); - DBG_PRINT(" - exit_ctls.acknowledge_interrupt_on_exit: %d\n", exit_ctls.acknowledge_interrupt_on_exit); - DBG_PRINT(" - exit_ctls.clear_ia32_bndcfgs: %d\n", exit_ctls.clear_ia32_bndcfgs); - DBG_PRINT(" - exit_ctls.conceal_vmx_from_pt: %d\n", exit_ctls.conceal_vmx_from_pt); - DBG_PRINT(" - exit_ctls.host_address_space_size: %d\n", exit_ctls.host_address_space_size); - DBG_PRINT(" - exit_ctls.load_ia32_efer: %d\n", exit_ctls.load_ia32_efer); - DBG_PRINT(" - exit_ctls.load_ia32_pat: %d\n", exit_ctls.load_ia32_pat); - DBG_PRINT(" - exit_ctls.load_ia32_perf_global_ctrl: %d\n", exit_ctls.load_ia32_perf_global_ctrl); - DBG_PRINT(" - exit_ctls.save_debug_controls: %d\n", exit_ctls.save_debug_controls); - DBG_PRINT(" - exit_ctls.save_ia32_efer: %d\n", exit_ctls.save_ia32_efer); - DBG_PRINT(" - exit_ctls.save_ia32_pat: %d\n", exit_ctls.save_ia32_pat); - DBG_PRINT(" - exit_ctls.save_vmx_preemption_timer_value: %d\n", exit_ctls.save_vmx_preemption_timer_value); - DBG_PRINT(" - exit_ctls.flags: 0x%x\n", exit_ctls.flags); - DBG_PRINT(" - IA32_VMX_TRUE_EXIT_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings); - DBG_PRINT(" - IA32_VMX_TRUE_EXIT_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings); } else { @@ -429,48 +226,12 @@ namespace vmcs pinbased_ctls.flags |= msr_fix_value.allowed_0_settings; __vmx_vmwrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, pinbased_ctls.flags); - DBG_PRINT("============================== pinbased vm-exit controls ==============================\n"); - DBG_PRINT(" - pinbased_ctls.activate_vmx_preemption_timer: %d\n", pinbased_ctls.activate_vmx_preemption_timer); - DBG_PRINT(" - pinbased_ctls.external_interrupt_exiting: %d\n", pinbased_ctls.external_interrupt_exiting); - DBG_PRINT(" - pinbased_ctls.nmi_exiting: %d\n", pinbased_ctls.nmi_exiting); - DBG_PRINT(" - pinbased_ctls.process_posted_interrupts: %d\n", pinbased_ctls.process_posted_interrupts); - DBG_PRINT(" - pinbased_ctls.virtual_nmi: %d\n", pinbased_ctls.virtual_nmi); - DBG_PRINT(" - pinbased_ctls.flags: 0x%x\n", pinbased_ctls.flags); - DBG_PRINT(" - IA32_VMX_PINBASED_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings); - DBG_PRINT(" - IA32_VMX_PINBASED_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings); - 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); - DBG_PRINT("============================== processor based vm-exit controls ==============================\n"); - DBG_PRINT(" - procbased_ctls.activate_secondary_controls: %d\n", procbased_ctls.activate_secondary_controls); - DBG_PRINT(" - procbased_ctls.cr3_load_exiting: %d\n", procbased_ctls.cr3_load_exiting); - DBG_PRINT(" - procbased_ctls.cr3_store_exiting: %d\n", procbased_ctls.cr3_store_exiting); - DBG_PRINT(" - procbased_ctls.cr8_load_exiting: %d\n", procbased_ctls.cr8_load_exiting); - DBG_PRINT(" - procbased_ctls.cr8_store_exiting: %d\n", procbased_ctls.cr8_store_exiting); - DBG_PRINT(" - procbased_ctls.hlt_exiting: %d\n", procbased_ctls.hlt_exiting); - DBG_PRINT(" - procbased_ctls.interrupt_window_exiting: %d\n", procbased_ctls.interrupt_window_exiting); - DBG_PRINT(" - procbased_ctls.invlpg_exiting: %d\n", procbased_ctls.invlpg_exiting); - DBG_PRINT(" - procbased_ctls.monitor_exiting: %d\n", procbased_ctls.monitor_exiting); - DBG_PRINT(" - procbased_ctls.monitor_trap_flag: %d\n", procbased_ctls.monitor_trap_flag); - DBG_PRINT(" - procbased_ctls.mov_dr_exiting: %d\n", procbased_ctls.mov_dr_exiting); - DBG_PRINT(" - procbased_ctls.mwait_exiting: %d\n", procbased_ctls.mwait_exiting); - DBG_PRINT(" - procbased_ctls.nmi_window_exiting: %d\n", procbased_ctls.nmi_window_exiting); - DBG_PRINT(" - procbased_ctls.pause_exiting: %d\n", procbased_ctls.pause_exiting); - DBG_PRINT(" - procbased_ctls.rdpmc_exiting: %d\n", procbased_ctls.rdpmc_exiting); - DBG_PRINT(" - procbased_ctls.rdtsc_exiting: %d\n", procbased_ctls.rdtsc_exiting); - DBG_PRINT(" - procbased_ctls.unconditional_io_exiting: %d\n", procbased_ctls.unconditional_io_exiting); - DBG_PRINT(" - procbased_ctls.use_io_bitmaps: %d\n", procbased_ctls.use_io_bitmaps); - DBG_PRINT(" - procbased_ctls.use_msr_bitmaps: %d\n", procbased_ctls.use_msr_bitmaps); - DBG_PRINT(" - procbased_ctls.use_tpr_shadow: %d\n", procbased_ctls.use_tpr_shadow); - DBG_PRINT(" - procbased_ctls.use_tsc_offsetting: %d\n", procbased_ctls.use_tsc_offsetting); - DBG_PRINT(" - procbased_ctls.flags: 0x%x\n", procbased_ctls.flags); - DBG_PRINT(" - IA32_VMX_PROCBASED_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings); - DBG_PRINT(" - IA32_VMX_PROCBASED_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings); - msr_fix_value.flags = __readmsr(IA32_VMX_ENTRY_CTLS); entry_ctls.ia32e_mode_guest = true; entry_ctls.conceal_vmx_from_pt = true; @@ -478,80 +239,20 @@ namespace vmcs entry_ctls.flags |= msr_fix_value.allowed_0_settings; __vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, entry_ctls.flags); - DBG_PRINT("============================== vm-entry controls ==============================\n"); - DBG_PRINT(" - entry_ctls.conceal_vmx_from_pt: %d\n", entry_ctls.conceal_vmx_from_pt); - DBG_PRINT(" - entry_ctls.deactivate_dual_monitor_treatment: %d\n", entry_ctls.deactivate_dual_monitor_treatment); - DBG_PRINT(" - entry_ctls.entry_to_smm: %d\n", entry_ctls.entry_to_smm); - DBG_PRINT(" - entry_ctls.ia32e_mode_guest: %d\n", entry_ctls.ia32e_mode_guest); - DBG_PRINT(" - entry_ctls.load_cet_state: %d\n", entry_ctls.load_cet_state); - DBG_PRINT(" - entry_ctls.load_debug_controls: %d\n", entry_ctls.load_debug_controls); - DBG_PRINT(" - entry_ctls.load_ia32_bndcfgs: %d\n", entry_ctls.load_ia32_bndcfgs); - DBG_PRINT(" - entry_ctls.load_ia32_efer: %d\n", entry_ctls.load_ia32_efer); - DBG_PRINT(" - entry_ctls.load_ia32_pat: %d\n", entry_ctls.load_ia32_pat); - DBG_PRINT(" - entry_ctls.load_ia32_perf_global_ctrl: %d\n", entry_ctls.load_ia32_perf_global_ctrl); - DBG_PRINT(" - entry_ctls.load_ia32_rtit_ctl: %d\n", entry_ctls.load_ia32_rtit_ctl); - DBG_PRINT(" - entry_ctls.flags: 0x%x\n", entry_ctls.flags); - DBG_PRINT(" - IA32_VMX_ENTRY_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings); - DBG_PRINT(" - IA32_VMX_ENTRY_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings); - 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); - - DBG_PRINT("============================== vm-exit controls ==============================\n"); - DBG_PRINT(" - exit_ctls.acknowledge_interrupt_on_exit: %d\n", exit_ctls.acknowledge_interrupt_on_exit); - DBG_PRINT(" - exit_ctls.clear_ia32_bndcfgs: %d\n", exit_ctls.clear_ia32_bndcfgs); - DBG_PRINT(" - exit_ctls.conceal_vmx_from_pt: %d\n", exit_ctls.conceal_vmx_from_pt); - DBG_PRINT(" - exit_ctls.host_address_space_size: %d\n", exit_ctls.host_address_space_size); - DBG_PRINT(" - exit_ctls.load_ia32_efer: %d\n", exit_ctls.load_ia32_efer); - DBG_PRINT(" - exit_ctls.load_ia32_pat: %d\n", exit_ctls.load_ia32_pat); - DBG_PRINT(" - exit_ctls.load_ia32_perf_global_ctrl: %d\n", exit_ctls.load_ia32_perf_global_ctrl); - DBG_PRINT(" - exit_ctls.save_debug_controls: %d\n", exit_ctls.save_debug_controls); - DBG_PRINT(" - exit_ctls.save_ia32_efer: %d\n", exit_ctls.save_ia32_efer); - DBG_PRINT(" - exit_ctls.save_ia32_pat: %d\n", exit_ctls.save_ia32_pat); - DBG_PRINT(" - exit_ctls.save_vmx_preemption_timer_value: %d\n", exit_ctls.save_vmx_preemption_timer_value); - DBG_PRINT(" - exit_ctls.flags: 0x%x\n", exit_ctls.flags); - DBG_PRINT(" - IA32_VMX_EXIT_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings); - DBG_PRINT(" - IA32_VMX_EXIT_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings); } msr_fix_value.flags = __readmsr(IA32_VMX_PROCBASED_CTLS2); procbased_ctls2.enable_rdtscp = true; - procbased_ctls2.enable_xsaves = 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); - - DBG_PRINT("============================== secondary processor based vm-exec controls ==============================\n"); - DBG_PRINT(" - procbased_ctls2.apic_register_virtualization: %d\n", procbased_ctls2.apic_register_virtualization); - DBG_PRINT(" - procbased_ctls2.conceal_vmx_from_pt: %d\n", procbased_ctls2.conceal_vmx_from_pt); - DBG_PRINT(" - procbased_ctls2.descriptor_table_exiting: %d\n", procbased_ctls2.descriptor_table_exiting); - DBG_PRINT(" - procbased_ctls2.enable_encls_exiting: %d\n", procbased_ctls2.enable_encls_exiting); - DBG_PRINT(" - procbased_ctls2.enable_ept: %d\n", procbased_ctls2.enable_ept); - DBG_PRINT(" - procbased_ctls2.enable_invpcid: %d\n", procbased_ctls2.enable_invpcid); - DBG_PRINT(" - procbased_ctls2.enable_pml: %d\n", procbased_ctls2.enable_pml); - DBG_PRINT(" - procbased_ctls2.enable_rdtscp: %d\n", procbased_ctls2.enable_rdtscp); - DBG_PRINT(" - procbased_ctls2.enable_vm_functions: %d\n", procbased_ctls2.enable_vm_functions); - DBG_PRINT(" - procbased_ctls2.enable_vpid: %d\n", procbased_ctls2.enable_vpid); - DBG_PRINT(" - procbased_ctls2.enable_xsaves: %d\n", procbased_ctls2.enable_xsaves); - DBG_PRINT(" - procbased_ctls2.ept_violation: %d\n", procbased_ctls2.ept_violation); - DBG_PRINT(" - procbased_ctls2.mode_based_execute_control_for_ept: %d\n", procbased_ctls2.mode_based_execute_control_for_ept); - DBG_PRINT(" - procbased_ctls2.pause_loop_exiting: %d\n", procbased_ctls2.pause_loop_exiting); - DBG_PRINT(" - procbased_ctls2.rdrand_exiting: %d\n", procbased_ctls2.rdrand_exiting); - DBG_PRINT(" - procbased_ctls2.rdseed_exiting: %d\n", procbased_ctls2.rdseed_exiting); - DBG_PRINT(" - procbased_ctls2.unrestricted_guest: %d\n", procbased_ctls2.unrestricted_guest); - DBG_PRINT(" - procbased_ctls2.use_tsc_scaling: %d\n", procbased_ctls2.use_tsc_scaling); - DBG_PRINT(" - procbased_ctls2.virtualize_apic_accesses: %d\n", procbased_ctls2.virtualize_apic_accesses); - DBG_PRINT(" - procbased_ctls2.virtualize_x2apic_mode: %d\n", procbased_ctls2.virtualize_x2apic_mode); - DBG_PRINT(" - procbased_ctls2.virtual_interrupt_delivery: %d\n", procbased_ctls2.virtual_interrupt_delivery); - DBG_PRINT(" - procbased_ctls2.vmcs_shadowing: %d\n", procbased_ctls2.vmcs_shadowing); - DBG_PRINT(" - procbased_ctls2.wbinvd_exiting: %d\n", procbased_ctls2.wbinvd_exiting); - DBG_PRINT(" - procbased_ctls2.flags: 0x%x\n", procbased_ctls2.flags); - DBG_PRINT(" - IA32_VMX_PROCBASED_CTLS2 high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings); - DBG_PRINT(" - IA32_VMX_PROCBASED_CTLS2 low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings); } } \ No newline at end of file diff --git a/vmxexit_handler.asm b/vmxexit_handler.asm index fb44c2d..6fb97ec 100644 --- a/vmxexit_handler.asm +++ b/vmxexit_handler.asm @@ -64,22 +64,22 @@ vmxexit_handler proc call exit_handler add rsp, 20h - movaps xmm0, [rsp] - movaps xmm1, [rsp + 010h] - movaps xmm2, [rsp + 020h] - movaps xmm3, [rsp + 030h] - movaps xmm4, [rsp + 040h] - movaps xmm5, [rsp + 050h] - movaps xmm6, [rsp + 060h] - movaps xmm7, [rsp + 070h] - movaps xmm8, [rsp + 080h] - movaps xmm9, [rsp + 090h] - movaps xmm10, [rsp + 0A0h] - movaps xmm11, [rsp + 0B0h] - movaps xmm12, [rsp + 0C0h] - movaps xmm13, [rsp + 0D0h] - movaps xmm14, [rsp + 0E0h] - movaps xmm15, [rsp + 0F0h] + movups xmm0, [rsp] + movups xmm1, [rsp + 010h] + movups xmm2, [rsp + 020h] + movups xmm3, [rsp + 030h] + movups xmm4, [rsp + 040h] + movups xmm5, [rsp + 050h] + movups xmm6, [rsp + 060h] + movups xmm7, [rsp + 070h] + movups xmm8, [rsp + 080h] + movups xmm9, [rsp + 090h] + movups xmm10, [rsp + 0A0h] + movups xmm11, [rsp + 0B0h] + movups xmm12, [rsp + 0C0h] + movups xmm13, [rsp + 0D0h] + movups xmm14, [rsp + 0E0h] + movups xmm15, [rsp + 0F0h] add rsp, 0108h ; 16 xmm registers... and +8 bytes for alignment... pop r15 @@ -95,6 +95,7 @@ vmxexit_handler proc pop rsi pop rdx pop rcx + pop rbx pop rax vmresume