diff --git a/bluepill.sln b/bluepill.sln
index 08d6100..8823095 100644
--- a/bluepill.sln
+++ b/bluepill.sln
@@ -7,9 +7,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bluepill", "bluepill.vcxpro
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
Release|x64 = Release|x64
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}.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
diff --git a/bluepill.vcxproj b/bluepill.vcxproj
index e62f178..94f6559 100644
--- a/bluepill.vcxproj
+++ b/bluepill.vcxproj
@@ -1,6 +1,10 @@
+
+ Debug
+ x64
+
Release
x64
@@ -28,6 +32,16 @@
false
false
+
+ Windows10
+ false
+ WindowsKernelModeDriver10.0
+ Driver
+ KMDF
+ Universal
+ false
+ false
+
@@ -40,6 +54,10 @@
DbgengKernelDebugger
false
+
+ DbgengKernelDebugger
+ false
+
false
@@ -50,6 +68,17 @@
false
+
+
+ false
+ driver_entry
+
+
+ stdcpp17
+ false
+ DBG_PRINT_BOOL;%(PreprocessorDefinitions)
+
+
diff --git a/bluepill.vcxproj.user b/bluepill.vcxproj.user
index b2a2bcc..d906e66 100644
--- a/bluepill.vcxproj.user
+++ b/bluepill.vcxproj.user
@@ -3,4 +3,7 @@
Off
+
+ Off
+
\ No newline at end of file
diff --git a/hv_types.hpp b/hv_types.hpp
index 3fb6156..d5e6524 100644
--- a/hv_types.hpp
+++ b/hv_types.hpp
@@ -18,29 +18,18 @@ using s64 = long long;
extern "C" void _sgdt(void*);
#pragma intrinsic(_sgdt);
+#ifdef DBG_PRINT_BOOL
+#define DBG_PRINT(format, ...) DbgPrintEx( DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, "[hv [core number = %d]]" format, KeGetCurrentProcessorNumber(), __VA_ARGS__)
+#else
+#define DBG_PRINT(format, ...)
+#endif
-#define DBG_PRINT(...) DbgPrintEx( DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, "[hv]" __VA_ARGS__)
#define HOST_STACK_PAGES 6
namespace hv
{
typedef struct _guest_registers
{
- u64 r15;
- u64 r14;
- u64 r13;
- u64 r12;
- u64 r11;
- u64 r10;
- u64 r9;
- u64 r8;
- u64 rbp;
- u64 rdi;
- u64 rsi;
- u64 rdx;
- u64 rcx;
- u64 rax;
-
u128 xmm0;
u128 xmm1;
u128 xmm2;
@@ -57,6 +46,21 @@ namespace hv
u128 xmm13;
u128 xmm14;
u128 xmm15;
+
+ u64 r15;
+ u64 r14;
+ u64 r13;
+ u64 r12;
+ u64 r11;
+ u64 r10;
+ u64 r9;
+ u64 r8;
+ u64 rbp;
+ u64 rdi;
+ u64 rsi;
+ u64 rdx;
+ u64 rcx;
+ u64 rax;
} guest_registers, * pguest_registers;
union ia32_efer_t
diff --git a/segment.cpp b/segment.cpp
index b991148..8e7c0b4 100644
--- a/segment.cpp
+++ b/segment.cpp
@@ -18,20 +18,38 @@ namespace segment
auto get_info(segment_descriptor_register_64 gdt_value, segment_selector segment_selector) -> hv::segment_info_ctx
{
hv::segment_info_ctx segment_info;
+
+ // GDT->BaseAddress + (segment index << 3)
+ // gives us a pointer to the segment descriptor...
const auto segment_descriptor =
reinterpret_cast(
gdt_value.base_address + (segment_selector.index << SEGMENT_SELECTOR_INDEX_BIT));
+ // access rights are spread out over the segment
+ // descriptor so those need to picked out and assigned
+ // to the vmx segment access rights variable...
segment_info.limit = __segmentlimit(segment_selector.flags);
segment_info.rights = get_access_rights(segment_descriptor);
- segment_info.base_addr = (u32)((segment_descriptor->base_address_high << SEGMENT__BASE_ADDRESS_HIGH_BIT) |
- (segment_descriptor->base_address_middle << SEGMENT__BASE_ADDRESS_MIDDLE_BIT) |
+ // base address of a segment is spread over the segment descriptor in 3 places. 2 parts of the
+ // address are 8 bits each (1 byte each) and the lowest part of the address is 2 bytes (4 bytes in total)...
+ // by shifting the values to the correct bit offset and adding them all together we get the address...
+ segment_info.base_addr = (u32)((segment_descriptor->base_address_high << SEGMENT__BASE_ADDRESS_HIGH_BIT) +
+ (segment_descriptor->base_address_middle << SEGMENT__BASE_ADDRESS_MIDDLE_BIT) +
(segment_descriptor->base_address_low));
- segment_info.base_addr &= 0xFFFFFFFF;
+ // Example:
+ // - high bits: 0b1111 0000 0000 0000
+ // - middle bits: 0b0000 1111 0000 0000
+ // - low bits: 0b0000 0000 1011 1000
+ // --------------------- +
+ // 0b1111 1111 1011 1000 <==== full address...
+ // if you add all of these together you will get the full address...
+
+ // if the base address is 64bits then go ahead
+ // and add the top 32bits onto the address..
if (!segment_descriptor->descriptor_type)
- segment_info.base_addr |= ((u64)segment_descriptor->base_address_upper << SEGMENT__BASE_ADDRESS_SHIFT);
+ segment_info.base_addr += ((u64)segment_descriptor->base_address_upper << SEGMENT__BASE_ADDRESS_SHIFT);
return segment_info;
}
diff --git a/vmcs.cpp b/vmcs.cpp
index 8e261d7..9774b7b 100644
--- a/vmcs.cpp
+++ b/vmcs.cpp
@@ -10,12 +10,14 @@ namespace vmcs
__sidt(&idt_value);
_sgdt(&gdt_value);
+ // use guest values for now... later on CR3 will be custom...
__vmx_vmwrite(VMCS_HOST_CR0, __readcr0());
__vmx_vmwrite(VMCS_HOST_CR3, __readcr3());
__vmx_vmwrite(VMCS_HOST_CR4, __readcr4());
+ // stack growns down...
+ __vmx_vmwrite(VMCS_HOST_RSP, host_rsp + (PAGE_SIZE * HOST_STACK_PAGES) - 8);
__vmx_vmwrite(VMCS_HOST_RIP, reinterpret_cast(host_rip));
- __vmx_vmwrite(VMCS_HOST_RSP, host_rsp);
__vmx_vmwrite(VMCS_HOST_SYSENTER_CS, __readmsr(IA32_SYSENTER_CS));
__vmx_vmwrite(VMCS_HOST_SYSENTER_EIP, __readmsr(IA32_SYSENTER_EIP));
@@ -24,13 +26,43 @@ namespace vmcs
__vmx_vmwrite(VMCS_HOST_GDTR_BASE, gdt_value.base_address);
__vmx_vmwrite(VMCS_HOST_IDTR_BASE, idt_value.base_address);
- __vmx_vmwrite(VMCS_HOST_ES_SELECTOR, reades());
- __vmx_vmwrite(VMCS_HOST_CS_SELECTOR, readcs());
- __vmx_vmwrite(VMCS_HOST_DS_SELECTOR, readds());
- __vmx_vmwrite(VMCS_HOST_FS_SELECTOR, readfs());
- __vmx_vmwrite(VMCS_HOST_GS_SELECTOR, readgs());
- __vmx_vmwrite(VMCS_HOST_SS_SELECTOR, readss());
- __vmx_vmwrite(VMCS_HOST_TR_SELECTOR, readtr());
+ // manual says that the priv level must be 0 and
+ // that the table flag also needs to be 0 so it uses the GDT...
+ segment_selector es{ reades() };
+ es.request_privilege_level = NULL;
+ es.table = NULL;
+
+ segment_selector cs{ readcs() };
+ cs.request_privilege_level = NULL;
+ cs.table = NULL;
+
+ segment_selector ds{ readds() };
+ ds.request_privilege_level = NULL;
+ ds.table = NULL;
+
+ segment_selector fs{ readfs() };
+ fs.request_privilege_level = NULL;
+ fs.table = NULL;
+
+ segment_selector gs{ readgs() };
+ gs.request_privilege_level = NULL;
+ gs.table = NULL;
+
+ segment_selector ss{ readss() };
+ ss.request_privilege_level = NULL;
+ ss.table = NULL;
+
+ segment_selector tr{ readtr() };
+ tr.request_privilege_level = NULL;
+ tr.table = NULL;
+
+ __vmx_vmwrite(VMCS_HOST_ES_SELECTOR, es.flags);
+ __vmx_vmwrite(VMCS_HOST_CS_SELECTOR, cs.flags);
+ __vmx_vmwrite(VMCS_HOST_DS_SELECTOR, ds.flags);
+ __vmx_vmwrite(VMCS_HOST_FS_SELECTOR, fs.flags);
+ __vmx_vmwrite(VMCS_HOST_GS_SELECTOR, gs.flags);
+ __vmx_vmwrite(VMCS_HOST_SS_SELECTOR, ss.flags);
+ __vmx_vmwrite(VMCS_HOST_TR_SELECTOR, tr.flags);
__vmx_vmwrite(VMCS_HOST_GS_BASE, __readmsr(IA32_GS_BASE));
__vmx_vmwrite(VMCS_HOST_FS_BASE, __readmsr(IA32_FS_BASE));
@@ -157,25 +189,91 @@ 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;
- procbased_ctls.activate_secondary_controls = true;
__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.flags &= msr_fix_value.allowed_1_settings;
entry_ctls.flags |= msr_fix_value.allowed_0_settings;
- entry_ctls.ia32e_mode_guest = true;
- entry_ctls.conceal_vmx_from_pt = true;
__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;
- exit_ctls.host_address_space_size = true;
- exit_ctls.conceal_vmx_from_pt = true;
__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
{
@@ -184,33 +282,129 @@ 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;
- procbased_ctls.activate_secondary_controls = true;
__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.flags &= msr_fix_value.allowed_1_settings;
- entry_ctls.flags |= msr_fix_value.allowed_0_settings;
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);
+ 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.flags &= msr_fix_value.allowed_1_settings;
- exit_ctls.flags |= msr_fix_value.allowed_0_settings;
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; // although my xeons dont support xsave... other cpus do!
+ procbased_ctls2.conceal_vmx_from_pt = true; // although my xeons dont support processor tracing... other cpus do!
procbased_ctls2.flags &= msr_fix_value.allowed_1_settings;
procbased_ctls2.flags |= msr_fix_value.allowed_0_settings;
- procbased_ctls2.enable_rdtscp = true;
- procbased_ctls2.enable_xsaves = true;
- procbased_ctls2.conceal_vmx_from_pt = true;
__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 d5602d7..ee4158d 100644
--- a/vmxexit_handler.asm
+++ b/vmxexit_handler.asm
@@ -10,7 +10,6 @@ vmxexit_handler proc
push rsi
push rdi
push rbp
- push rbp ; gotta keep the stack aligned...
push r8
push r9
push r10
@@ -69,7 +68,6 @@ vmxexit_handler proc
pop r10
pop r9
pop r8
- pop rbp ; gotta keep the stack aligned...
pop rbp
pop rdi
pop rsi
diff --git a/vmxon.cpp b/vmxon.cpp
index cd7b364..6a25880 100644
--- a/vmxon.cpp
+++ b/vmxon.cpp
@@ -72,11 +72,17 @@ namespace vmxon
reinterpret_cast(
ExAllocatePool(NonPagedPool, sizeof hv::vcpu_ctx));
+ // allocate host stack...
vmx_ctx->vcpus[idx]->host_stack =
reinterpret_cast(
ExAllocatePool(NonPagedPool,
PAGE_SIZE * HOST_STACK_PAGES));
+ // zero host stack...
+ RtlZeroMemory(reinterpret_cast(
+ vmx_ctx->vcpus[idx]->host_stack), PAGE_SIZE * HOST_STACK_PAGES);
+
+ // setup VMCS and VMXON region...
create_vmxon_region(vmx_ctx->vcpus[idx]);
create_vmcs(vmx_ctx->vcpus[idx]);
@@ -85,6 +91,7 @@ namespace vmxon
DBG_PRINT(" - vmxon region (physical): 0x%p\n", vmx_ctx->vcpus[idx]->vmxon_phys);
DBG_PRINT(" - vmcs (virtual): 0x%p\n", vmx_ctx->vcpus[idx]->vmcs);
DBG_PRINT(" - vmcs (physical): 0x%p\n", vmx_ctx->vcpus[idx]->vmcs_phys);
+ DBG_PRINT(" - host stack: 0x%p\n", vmx_ctx->vcpus[idx]->host_stack);
}
}
@@ -95,7 +102,7 @@ namespace vmxon
hv::cr0_t cr0 = { 0 };
hv::cr4_t cr4 = { 0 };
- // should check to see if this is locked or not...
+ // TODO: should check to see if this is locked or not...
feature_msr.control = __readmsr(IA32_FEATURE_CONTROL);
feature_msr.bits.vmxon_outside_smx = true;
feature_msr.bits.lock = true;
@@ -117,14 +124,17 @@ namespace vmxon
cr4.flags &= cr_fixed.split.low;
__writecr4(cr4.flags);
+ // enable vmx instructions on this core...
cr4.flags = __readcr4();
cr4.vmx_enable = true;
__writecr4(cr4.flags);
- DBG_PRINT("vmxon for processor: %d\n", KeGetCurrentProcessorNumber());
- DBG_PRINT(" - vmxon result (0 == success): %d\n",
+ const auto vmxon_result =
__vmx_on((unsigned long long*)
&vmxon::g_vmx_ctx->vcpus[
- KeGetCurrentProcessorNumber()]->vmxon_phys));
+ KeGetCurrentProcessorNumber()]->vmxon_phys);
+
+ DBG_PRINT("vmxon for processor: %d\n", KeGetCurrentProcessorNumber());
+ DBG_PRINT(" - vmxon result (0 == success): %d\n", vmxon_result);
}
}
\ No newline at end of file