idk what i added

merge-requests/1/head
_xeroxz 3 years ago
parent ed7ec28813
commit 761e6b16ac

@ -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

@ -85,6 +85,7 @@
<ItemGroup>
<ClCompile Include="entry.cpp" />
<ClCompile Include="exit_handler.cpp" />
<ClCompile Include="mm.cpp" />
<ClCompile Include="segment.cpp" />
<ClCompile Include="vmcs.cpp" />
<ClCompile Include="vmxlaunch.cpp" />
@ -92,6 +93,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="ia32.hpp" />
<ClInclude Include="mm.hpp" />
<ClInclude Include="segment_intrin.h" />
<ClInclude Include="hv_types.hpp" />
<ClInclude Include="vmcs.hpp" />

@ -29,6 +29,9 @@
<ClCompile Include="segment.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mm.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="vmxon.hpp">
@ -52,6 +55,9 @@
<ClInclude Include="vmcs.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mm.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<MASM Include="segment_intrin.asm">

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{a3d028d7-1650-4036-9fb0-4b8cc16268fe}</ProjectGuid>
<RootNamespace>demo</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<MASM Include="hypercall.asm">
<FileType>Document</FileType>
</MASM>
</ItemGroup>
<ItemGroup>
<ClInclude Include="hypercall.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="hypercall.asm">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClInclude Include="hypercall.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

@ -0,0 +1,6 @@
.code
hypercall proc
cpuid
ret
hypercall endp
end

@ -0,0 +1,20 @@
#pragma once
#include <Windows.h>
#include <intrin.h>
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);
}

@ -0,0 +1,8 @@
#include <iostream>
#include "hypercall.h"
int main()
{
std::printf("hypercall result: 0x%x\n", bluepill::hypercall(bluepill::key));
std::getchar();
}

@ -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(

@ -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);
}

@ -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;

@ -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;
/**

@ -0,0 +1,6 @@
#include "mm.hpp"
namespace mm
{
}

125
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<ppml4e>(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;
}

@ -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<segment_descriptor_64*>(

@ -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<mm::ppml4e>(
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<u64>(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);
}
}

@ -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

Loading…
Cancel
Save