merge from private repo

merge-requests/1/merge
_xeroxz 2 years ago
parent ce7d94c49a
commit 34cacd54a9

@ -79,4 +79,67 @@ rename it to `payload.dll`. Put both `bootmgfw.efi` (Voyager.efi rename), and `p
<div>
<img src="https://githacks.org/xerox/voyager/uploads/fb3b24b28282a0cfe4c1b0440246844f/image.png"/>
</div>
</div>
</div>
### libvoyager
libvoyager is a tiny lib that allows a programmer to integrate voyager into VDM or other projects that require reading and writing to physical and virtual memory. There is
an example in the repo which contains example code for integrating into VDM.
```cpp
vdm::read_phys_t _read_phys =
[&](void* addr, void* buffer, std::size_t size) -> bool
{
const auto read_result =
voyager::read_phys((u64)addr, (u64)buffer, size);
return read_result ==
voyager::vmxroot_error_t::error_success;
};
vdm::write_phys_t _write_phys =
[&](void* addr, void* buffer, std::size_t size) -> bool
{
const auto write_result =
voyager::write_phys((u64)addr, (u64)buffer, size);
return write_result ==
voyager::vmxroot_error_t::error_success;
};
```
Any project that uses VDM can now use Voyager instead of a vulnerable driver. This includes all PTM projects.
### Page Table Code
mm.cpp and mm.hpp contain all of the memory managment code. Hyper-v has a self referencing PML4E at index 510. This is the same index for all versions of Hyper-v.
This is crucial as without knowing where the PML4 of the current logical processor is located in virtual memory, there is no way to interface with physical memory.
Each logical processor running under hyper-v has its own host cr3 value (each core has its own host PML4).
###### Mapping PTE's
In the Intel and AMD payloads of this project, there is a section for PDPT, PD, and PT. These sections need to be page aligned in
order for them to work (they are just putting this here as a warning). Each logical processor has two PTE's, one for source and one for destination. This allows for
copying of physical memory between two pages without requiring a buffer.
```cpp
auto mm::map_page(host_phys_t phys_addr, map_type_t map_type) -> u64
{
cpuid_eax_01 cpuid_value;
__cpuid((int*)&cpuid_value, 1);
mm::pt[(cpuid_value
.cpuid_additional_information
.initial_apic_id * 2)
+ (unsigned)map_type].pfn = phys_addr >> 12;
__invlpg(reinterpret_cast<void*>(
get_map_virt(virt_addr_t{ phys_addr }.offset_4kb, map_type)));
return get_map_virt(virt_addr_t{ phys_addr }.offset_4kb, map_type);
}
```
As you can see from the code above, the logical processor number which is obtained from CPUID instruction is mulitplied by the `map_type`. There can be a max of 256 cores on the system, if there
are more then 256 cores on the system then this code above will not work.

@ -1,31 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30503.244
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Example", "Example.vcxproj", "{09B41831-3164-48AD-8660-23457D82B73B}"
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
{09B41831-3164-48AD-8660-23457D82B73B}.Debug|x64.ActiveCfg = Debug|x64
{09B41831-3164-48AD-8660-23457D82B73B}.Debug|x64.Build.0 = Debug|x64
{09B41831-3164-48AD-8660-23457D82B73B}.Debug|x86.ActiveCfg = Debug|Win32
{09B41831-3164-48AD-8660-23457D82B73B}.Debug|x86.Build.0 = Debug|Win32
{09B41831-3164-48AD-8660-23457D82B73B}.Release|x64.ActiveCfg = Release|x64
{09B41831-3164-48AD-8660-23457D82B73B}.Release|x64.Build.0 = Release|x64
{09B41831-3164-48AD-8660-23457D82B73B}.Release|x86.ActiveCfg = Release|Win32
{09B41831-3164-48AD-8660-23457D82B73B}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E132D109-7F0D-4125-B737-B5D83E6FBCA8}
EndGlobalSection
EndGlobal

@ -1,158 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<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>{09b41831-3164-48ad-8660-23457d82b73b}</ProjectGuid>
<RootNamespace>DeepSpaceNetwork</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>Example</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<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|Win32'">
<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|Win32'">
<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)'=='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|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<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|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<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="com.asm">
<FileType>Document</FileType>
</MASM>
</ItemGroup>
<ItemGroup>
<ClInclude Include="com.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>

@ -1,9 +0,0 @@
#pragma once
#define VMEXIT_KEY 0xDEADBEEFDEADBEEF
enum class vmexit_command_t
{
init_paging_tables = 0x111
// add your commands here...
};
extern "C" size_t hypercall(size_t key, vmexit_command_t command);

@ -1,9 +0,0 @@
#include <iostream>
#include "com.h"
int main()
{
auto result = hypercall(VMEXIT_KEY, vmexit_command_t::init_paging_tables);
std::printf("[+] hyper-v (CPUID) init page table result -> %d\n", result);
std::getchar();
}

@ -56,7 +56,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='1909|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
@ -65,7 +65,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='1903|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
@ -74,7 +74,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='1809|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
@ -83,7 +83,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='1803|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
@ -92,7 +92,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='1709|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
@ -101,7 +101,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='1703|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
@ -110,7 +110,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='1607|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
@ -119,7 +119,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='1511|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
@ -128,7 +128,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='1507|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
@ -137,7 +137,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='2004|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
@ -198,9 +198,13 @@
<ControlFlowGuard>false</ControlFlowGuard>
<TreatWarningAsError>false</TreatWarningAsError>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);WINVER=1909;</PreprocessorDefinitions>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<EntryPointSymbol>vmexit_handler</EntryPointSymbol>
<AdditionalDependencies>libcmt.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='1903|x64'">
@ -210,9 +214,13 @@
<ControlFlowGuard>false</ControlFlowGuard>
<TreatWarningAsError>false</TreatWarningAsError>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);WINVER=1903;</PreprocessorDefinitions>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<EntryPointSymbol>vmexit_handler</EntryPointSymbol>
<AdditionalDependencies>libcmt.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='1809|x64'">
@ -222,9 +230,13 @@
<ControlFlowGuard>false</ControlFlowGuard>
<TreatWarningAsError>false</TreatWarningAsError>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);WINVER=1809;</PreprocessorDefinitions>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<EntryPointSymbol>vmexit_handler</EntryPointSymbol>
<AdditionalDependencies>libcmt.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='1803|x64'">
@ -234,9 +246,13 @@
<ControlFlowGuard>false</ControlFlowGuard>
<TreatWarningAsError>false</TreatWarningAsError>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);WINVER=1803;</PreprocessorDefinitions>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<EntryPointSymbol>vmexit_handler</EntryPointSymbol>
<AdditionalDependencies>libcmt.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='1709|x64'">
@ -246,9 +262,13 @@
<ControlFlowGuard>false</ControlFlowGuard>
<TreatWarningAsError>false</TreatWarningAsError>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);WINVER=1709</PreprocessorDefinitions>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<EntryPointSymbol>vmexit_handler</EntryPointSymbol>
<AdditionalDependencies>libcmt.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='1703|x64'">
@ -258,9 +278,13 @@
<ControlFlowGuard>false</ControlFlowGuard>
<TreatWarningAsError>false</TreatWarningAsError>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);WINVER=1703</PreprocessorDefinitions>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<EntryPointSymbol>vmexit_handler</EntryPointSymbol>
<AdditionalDependencies>libcmt.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='1607|x64'">
@ -270,9 +294,13 @@
<ControlFlowGuard>false</ControlFlowGuard>
<TreatWarningAsError>false</TreatWarningAsError>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);WINVER=1607</PreprocessorDefinitions>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<EntryPointSymbol>vmexit_handler</EntryPointSymbol>
<AdditionalDependencies>libcmt.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='1511|x64'">
@ -282,9 +310,13 @@
<ControlFlowGuard>false</ControlFlowGuard>
<TreatWarningAsError>false</TreatWarningAsError>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);WINVER=1511;</PreprocessorDefinitions>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<EntryPointSymbol>vmexit_handler</EntryPointSymbol>
<AdditionalDependencies>libcmt.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='1507|x64'">
@ -293,10 +325,14 @@
<BufferSecurityCheck>false</BufferSecurityCheck>
<ControlFlowGuard>false</ControlFlowGuard>
<TreatWarningAsError>false</TreatWarningAsError>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);WINVER=1903;</PreprocessorDefinitions>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);WINVER=1507;</PreprocessorDefinitions>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<EntryPointSymbol>vmexit_handler</EntryPointSymbol>
<AdditionalDependencies>libcmt.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='2004|x64'">
@ -306,21 +342,29 @@
<ControlFlowGuard>false</ControlFlowGuard>
<TreatWarningAsError>false</TreatWarningAsError>
<PreprocessorDefinitions>_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);WINVER=2004;</PreprocessorDefinitions>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<EntryPointSymbol>vmexit_handler</EntryPointSymbol>
<AdditionalDependencies>libcmt.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="debug.h" />
<ClInclude Include="ia32.hpp" />
<ClInclude Include="pg_table.h" />
<ClInclude Include="mm.h" />
<ClInclude Include="types.h" />
<ClInclude Include="vmexit.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="pg_table.cpp" />
<ClCompile Include="debug.cpp" />
<ClCompile Include="mm.cpp" />
<ClCompile Include="vmexit.cpp" />
<ClCompile Include="vmexit_handler.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

@ -14,10 +14,16 @@
<ClInclude Include="types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pg_table.h">
<ClInclude Include="ia32.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ia32.hpp">
<ClInclude Include="debug.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="vmexit.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
@ -25,7 +31,13 @@
<ClCompile Include="vmexit_handler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pg_table.cpp">
<ClCompile Include="debug.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mm.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="vmexit.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>

@ -0,0 +1,69 @@
#include "debug.h"
auto dbg::debug_print_decimal(long long number) -> void
{
if (number < 0)
{
__outbyte(PORT_NUM, '-');
number = -number;
}
for (auto d = 1000000000000000000; d != 0; d /= 10)
if ((number / d) != 0)
__outbyte(PORT_NUM, alphabet[(number / d) % 10]);
}
auto dbg::debug_print_hex(u64 number, const bool show_zeros) -> void
{
for (auto d = 0x1000000000000000; d != 0; d /= 0x10)
if (show_zeros || (number / d) != 0)
__outbyte(PORT_NUM, alphabet[(number / d) % 0x10]);
}
auto dbg::print(const char* format, ...) -> void
{
va_list args;
va_start(args, format);
while (format[0])
{
if (format[0] == '%')
{
switch (format[1])
{
case 'd':
debug_print_decimal(va_arg(args, int));
format += 2;
continue;
case 'x':
debug_print_hex(va_arg(args, u32), false);
format += 2;
continue;
case 'l':
if (format[2] == 'l')
{
switch (format[3])
{
case 'd':
debug_print_decimal(va_arg(args, u64));
format += 4;
continue;
case 'x':
debug_print_hex(va_arg(args, u64), false);
format += 4;
continue;
}
}
break;
case 'p':
debug_print_hex(va_arg(args, u64), true);
format += 2;
continue;
}
}
__outbyte(PORT_NUM, format[0]);
++format;
}
va_end(args);
}

@ -0,0 +1,13 @@
#pragma once
#include <stdarg.h>
#include <stddef.h>
#include "types.h"
#define PORT_NUM 0x2F8
namespace dbg
{
constexpr char alphabet[] = "0123456789ABCDEF";
auto debug_print_decimal(long long number) -> void;
auto debug_print_hex(u64 number, const bool show_zeros) -> void;
auto print(const char* format, ...) -> void;
}

@ -14132,7 +14132,7 @@ typedef union
};
UINT64_t flags;
} pml4e_64;
} pml4e;
/**
* @brief Format of a 4-Level Page-Directory-Pointer-Table Entry (PDPTE) that Maps a 1-GByte Page
@ -14431,7 +14431,7 @@ typedef union
};
UINT64_t flags;
} pdpte_64;
} pdpte;
/**
* @brief Format of a 4-Level Page-Directory Entry that Maps a 2-MByte Page
@ -14730,7 +14730,7 @@ typedef union
};
UINT64_t flags;
} pde_64;
} pde;
/**
* @brief Format of a 4-Level Page-Table Entry that Maps a 4-KByte Page
@ -14891,7 +14891,7 @@ typedef union
};
UINT64_t flags;
} pte_64;
} pte;
/**
* @brief Format of a common Page-Table Entry
@ -18281,7 +18281,7 @@ typedef union
};
UINT64_t flags;
} ept_pml4;
} ept_pml4e;
/**
* @brief Format of an EPT Page-Directory-Pointer-Table Entry (PDPTE) that Maps a 1-GByte Page
@ -18412,7 +18412,7 @@ typedef union
};
UINT64_t flags;
} epdpte_1gb;
} ept_pdpte_1gb;
/**
* @brief Format of an EPT Page-Directory-Pointer-Table Entry (PDPTE) that References an EPT Page Directory
@ -18489,7 +18489,7 @@ typedef union
};
UINT64_t flags;
} epdpte;
} ept_pdpte;
/**
* @brief Format of an EPT Page-Directory Entry (PDE) that Maps a 2-MByte Page
@ -18697,7 +18697,7 @@ typedef union
};
UINT64_t flags;
} epde;
} ept_pde;
/**
* @brief Format of an EPT Page-Table Entry that Maps a 4-KByte Page
@ -18820,7 +18820,7 @@ typedef union
};
UINT64_t flags;
} epte;
} ept_pte;
/**
* @brief Format of a common EPT Entry

@ -0,0 +1,363 @@
#include "mm.h"
#include "debug.h"
auto mm::map_guest_phys(guest_phys_t phys_addr, map_type_t map_type) -> u64
{
//const auto host_phys =
//translate_guest_physical(
//phys_addr, map_type);
//if (!host_phys)
//return {};
return map_page(phys_addr, map_type);
}
auto mm::map_guest_virt(guest_phys_t dirbase, guest_virt_t virt_addr, map_type_t map_type) -> u64
{
const auto guest_phys =
translate_guest_virtual(
dirbase, virt_addr, map_type);
if (!guest_phys)
return {};
return map_guest_phys(guest_phys, map_type);
}
auto mm::map_page(host_phys_t phys_addr, map_type_t map_type) -> u64
{
cpuid_eax_01 cpuid_value;
__cpuid((int*)&cpuid_value, 1);
mm::pt[(cpuid_value
.cpuid_additional_information
.initial_apic_id * 2)
+ (unsigned)map_type].pfn = phys_addr >> 12;
__invlpg(reinterpret_cast<void*>(
get_map_virt(virt_addr_t{ phys_addr }.offset_4kb, map_type)));
return get_map_virt(virt_addr_t{ phys_addr }.offset_4kb, map_type);
}
auto mm::get_map_virt(u16 offset, map_type_t map_type) -> u64
{
cpuid_eax_01 cpuid_value;
__cpuid((int*)&cpuid_value, 1);
virt_addr_t virt_addr{ MAPPING_ADDRESS_BASE };
virt_addr.pt_index = (cpuid_value
.cpuid_additional_information
.initial_apic_id * 2)
+ (unsigned)map_type;
return virt_addr.value + offset;
}
auto mm::translate(host_virt_t host_virt) -> u64
{
virt_addr_t virt_addr{ host_virt };
virt_addr_t cursor{ (u64)hyperv_pml4 };
if (!reinterpret_cast<ppml4e>(cursor.value)[virt_addr.pml4_index].present)
return {};
cursor.pt_index = virt_addr.pml4_index;
if (!reinterpret_cast<ppdpte>(cursor.value)[virt_addr.pdpt_index].present)
return {};
// handle 1gb large page...
if (reinterpret_cast<ppdpte>(cursor.value)[virt_addr.pdpt_index].large_page)
return (reinterpret_cast<ppdpte>(cursor.value)
[virt_addr.pdpt_index].pfn << 30) + virt_addr.offset_1gb;
cursor.pd_index = virt_addr.pml4_index;
cursor.pt_index = virt_addr.pdpt_index;
if (!reinterpret_cast<ppde>(cursor.value)[virt_addr.pd_index].present)
return {};
// handle 2mb large page...
if (reinterpret_cast<ppde>(cursor.value)[virt_addr.pd_index].large_page)
return (reinterpret_cast<ppde>(cursor.value)
[virt_addr.pd_index].pfn << 21) + virt_addr.offset_2mb;
cursor.pdpt_index = virt_addr.pml4_index;
cursor.pd_index = virt_addr.pdpt_index;
cursor.pt_index = virt_addr.pd_index;
if (!reinterpret_cast<ppte>(cursor.value)[virt_addr.pt_index].present)
return {};
return (reinterpret_cast<ppte>(cursor.value)
[virt_addr.pt_index].pfn << 12) + virt_addr.offset_4kb;
}
auto mm::translate_guest_virtual(guest_phys_t dirbase, guest_virt_t guest_virt, map_type_t map_type) -> u64
{
virt_addr_t virt_addr{ guest_virt };
const auto pml4 =
reinterpret_cast<pml4e*>(
map_guest_phys(dirbase, map_type));
if (!pml4 || !pml4[virt_addr.pml4_index].present)
return {};
const auto pdpt =
reinterpret_cast<pdpte*>(map_guest_phys(
pml4[virt_addr.pml4_index].pfn << 12, map_type));
if (!pdpt || !pdpt[virt_addr.pdpt_index].present)
return {};
// handle 1gb pages...
if (pdpt[virt_addr.pdpt_index].large_page)
return (pdpt[virt_addr.pdpt_index].pfn << 12) + virt_addr.offset_1gb;
const auto pd =
reinterpret_cast<pde*>(map_guest_phys(
pdpt[virt_addr.pdpt_index].pfn << 12, map_type));
if (!pd || !pd[virt_addr.pd_index].present)
return {};
// handle 2mb pages...
if (pd[virt_addr.pd_index].large_page)
return (pd[virt_addr.pd_index].pfn << 12) + virt_addr.offset_2mb;
const auto pt =
reinterpret_cast<pte*>(map_guest_phys(
pd[virt_addr.pd_index].pfn << 12, map_type));
if (!pt || !pt[virt_addr.pt_index].present)
return {};
return (pt[virt_addr.pt_index].pfn << 12) + virt_addr.offset_4kb;
}
auto mm::translate_guest_physical(guest_phys_t phys_addr, map_type_t map_type) -> u64
{
phys_addr_t guest_phys{ phys_addr };
const auto vmcb = svm::get_vmcb();
const auto npt_pml4 =
reinterpret_cast<pnpt_pml4e>(
map_page(vmcb->ncr3, map_type));
if (!npt_pml4[guest_phys.pml4_index].present)
return {};
const auto npt_pdpt =
reinterpret_cast<pnpt_pdpte>(
map_page(npt_pml4[guest_phys.pml4_index].pfn << 12, map_type));
if (!npt_pdpt[guest_phys.pdpt_index].present)
return {};
const auto npt_pd =
reinterpret_cast<pnpt_pde>(
map_page(npt_pdpt[guest_phys.pdpt_index].pfn << 12, map_type));
if (!npt_pd[guest_phys.pd_index].present)
return {};
// handle 2mb pages...
if (reinterpret_cast<pnpt_pde_2mb>(npt_pd)[guest_phys.pd_index].large_page)
return (reinterpret_cast<pnpt_pde_2mb>(npt_pd)
[guest_phys.pd_index].pfn << 21) + guest_phys.offset_2mb;
const auto npt_pt =
reinterpret_cast<pnpt_pte>(
map_page(npt_pd[guest_phys.pd_index].pfn << 12, map_type));
if (!npt_pt[guest_phys.pt_index].present)
return {};
return (npt_pt[guest_phys.pt_index].pfn << 12) + guest_phys.offset_4kb;
}
auto mm::init() -> svm::vmxroot_error_t
{
const auto pdpt_phys =
translate(reinterpret_cast<u64>(pdpt));
const auto pd_phys =
translate(reinterpret_cast<u64>(pd));
const auto pt_phys =
translate(reinterpret_cast<u64>(pt));
if (!pdpt_phys || !pd_phys || !pt_phys)
return svm::vmxroot_error_t::invalid_host_virtual;
// setup mapping page table entries...
{
hyperv_pml4[MAPPING_PML4_IDX].present = true;
hyperv_pml4[MAPPING_PML4_IDX].pfn = pdpt_phys >> 12;
hyperv_pml4[MAPPING_PML4_IDX].user_supervisor = false;
hyperv_pml4[MAPPING_PML4_IDX].writeable = true;
pdpt[511].present = true;
pdpt[511].pfn = pd_phys >> 12;
pdpt[511].user_supervisor = false;
pdpt[511].rw = true;
pd[511].present = true;
pd[511].pfn = pt_phys >> 12;
pd[511].user_supervisor = false;
pd[511].rw = true;
}
// each core will have its own page it can use to map
// physical memory into virtual memory :^)
for (auto idx = 0u; idx < 512; ++idx)
{
pt[idx].present = true;
pt[idx].user_supervisor = false;
pt[idx].rw = true;
}
const auto mapped_pml4 =
reinterpret_cast<ppml4e>(
mm::map_page(__readcr3()));
// check to make sure translate works...
if (translate((u64)mapped_pml4) != __readcr3())
return svm::vmxroot_error_t::vmxroot_translate_failure;
// check to make sure the self ref pml4e is valid...
if (mapped_pml4[SELF_REF_PML4_IDX].pfn != __readcr3() >> 12)
return svm::vmxroot_error_t::invalid_self_ref_pml4e;
// check to make sure the mapping pml4e is valid...
if (mapped_pml4[MAPPING_PML4_IDX].pfn != pdpt_phys >> 12)
return svm::vmxroot_error_t::invalid_mapping_pml4e;
return svm::vmxroot_error_t::error_success;
}
auto mm::read_guest_phys(guest_phys_t dirbase, guest_phys_t guest_phys,
guest_virt_t guest_virt, u64 size) -> svm::vmxroot_error_t
{
// handle reading over page boundaries of both src and dest...
while (size)
{
auto dest_current_size = PAGE_4KB -
virt_addr_t{ guest_virt }.offset_4kb;
if (size < dest_current_size)
dest_current_size = size;
auto src_current_size = PAGE_4KB -
phys_addr_t{ guest_phys }.offset_4kb;
if (size < src_current_size)
src_current_size = size;
auto current_size =
min(dest_current_size, src_current_size);
const auto mapped_dest =
reinterpret_cast<void*>(
map_guest_virt(dirbase, guest_virt, map_type_t::map_dest));
if (!mapped_dest)
return svm::vmxroot_error_t::invalid_guest_virtual;
const auto mapped_src =
reinterpret_cast<void*>(
map_guest_phys(guest_phys, map_type_t::map_src));
if (!mapped_src)
return svm::vmxroot_error_t::invalid_guest_physical;
memcpy(mapped_dest, mapped_src, current_size);
guest_phys += current_size;
guest_virt += current_size;
size -= current_size;
}
return svm::vmxroot_error_t::error_success;
}
auto mm::write_guest_phys(guest_phys_t dirbase,
guest_phys_t guest_phys, guest_virt_t guest_virt, u64 size) -> svm::vmxroot_error_t
{
// handle reading over page boundaries of both src and dest...
while (size)
{
auto dest_current_size = PAGE_4KB -
virt_addr_t{ guest_virt }.offset_4kb;
if (size < dest_current_size)
dest_current_size = size;
auto src_current_size = PAGE_4KB -
phys_addr_t{ guest_phys }.offset_4kb;
if (size < src_current_size)
src_current_size = size;
auto current_size =
min(dest_current_size, src_current_size);
const auto mapped_src =
reinterpret_cast<void*>(
map_guest_virt(dirbase, guest_virt, map_type_t::map_src));
if (!mapped_src)
return svm::vmxroot_error_t::invalid_guest_virtual;
const auto mapped_dest =
reinterpret_cast<void*>(
map_guest_phys(guest_phys, map_type_t::map_dest));
if (!mapped_src)
return svm::vmxroot_error_t::invalid_guest_physical;
memcpy(mapped_dest, mapped_src, current_size);
guest_phys += current_size;
guest_virt += current_size;
size -= current_size;
}
return svm::vmxroot_error_t::error_success;
}
auto mm::copy_guest_virt(guest_phys_t dirbase_src, guest_virt_t virt_src,
guest_virt_t dirbase_dest, guest_virt_t virt_dest, u64 size) -> svm::vmxroot_error_t
{
while (size)
{
auto dest_size = PAGE_4KB - virt_addr_t{ virt_dest }.offset_4kb;
if (size < dest_size)
dest_size = size;
auto src_size = PAGE_4KB - virt_addr_t{ virt_src }.offset_4kb;
if (size < src_size)
src_size = size;
const auto mapped_src =
reinterpret_cast<void*>(
map_guest_virt(dirbase_src, virt_src, map_type_t::map_src));
if (!mapped_src)
return svm::vmxroot_error_t::invalid_guest_virtual;
const auto mapped_dest =
reinterpret_cast<void*>(
map_guest_virt(dirbase_dest, virt_dest, map_type_t::map_dest));
if (!mapped_dest)
return svm::vmxroot_error_t::invalid_guest_virtual;
auto current_size = min(dest_size, src_size);
memcpy(mapped_dest, mapped_src, current_size);
virt_src += current_size;
virt_dest += current_size;
size -= current_size;
}
return svm::vmxroot_error_t::error_success;
}

@ -0,0 +1,237 @@
#pragma once
#include "types.h"
#define SELF_REF_PML4_IDX 510
#define MAPPING_PML4_IDX 100
#define MAPPING_ADDRESS_BASE 0x0000327FFFE00000
#define SELF_REF_PML4 0xFFFFFF7FBFDFE000
#define EPT_LARGE_PDPTE_OFFSET(_) (((u64)(_)) & ((0x1000 * 0x200 * 0x200) - 1))
#define EPT_LARGE_PDE_OFFSET(_) (((u64)(_)) & ((0x1000 * 0x200) - 1))
#pragma section(".pdpt", read, write)
#pragma section(".pd", read, write)
#pragma section(".pt", read, write)
namespace mm
{
enum class map_type_t
{
map_src,
map_dest
};
typedef union _virt_addr_t
{
u64 value;
struct
{
u64 offset_4kb : 12;
u64 pt_index : 9;
u64 pd_index : 9;
u64 pdpt_index : 9;
u64 pml4_index : 9;
u64 reserved : 16;
};
struct
{
u64 offset_2mb : 21;
u64 pd_index : 9;
u64 pdpt_index : 9;
u64 pml4_index : 9;
u64 reserved : 16;
};
struct
{
u64 offset_1gb : 30;
u64 pdpt_index : 9;
u64 pml4_index : 9;
u64 reserved : 16;
};
} virt_addr_t, * pvirt_addr_t;
using phys_addr_t = virt_addr_t;
typedef union _pml4e
{
u64 value;
struct
{
u64 present : 1;
u64 writeable : 1;
u64 user_supervisor : 1;
u64 page_write_through : 1;
u64 page_cache : 1;
u64 accessed : 1;
u64 ignore_1 : 1;
u64 page_size : 1;
u64 ignore_2 : 4;
u64 pfn : 36;
u64 reserved : 4;
u64 ignore_3 : 11;
u64 nx : 1;
};
} pml4e, * ppml4e;
typedef union _pdpte
{
u64 value;
struct
{
u64 present : 1;
u64 rw : 1;
u64 user_supervisor : 1;
u64 page_write_through : 1;
u64 page_cache : 1;
u64 accessed : 1;
u64 ignore_1 : 1;
u64 large_page : 1;
u64 ignore_2 : 4;
u64 pfn : 36;
u64 reserved : 4;
u64 ignore_3 : 11;
u64 nx : 1;
};
} pdpte, * ppdpte;
typedef union _pde
{
u64 value;
struct
{
u64 present : 1;
u64 rw : 1;
u64 user_supervisor : 1;
u64 page_write_through : 1;
u64 page_cache : 1;
u64 accessed : 1;
u64 ignore_1 : 1;
u64 large_page : 1;
u64 ignore_2 : 4;
u64 pfn : 36;
u64 reserved : 4;
u64 ignore_3 : 11;
u64 nx : 1;
};
} pde, * ppde;
typedef union _pte
{
u64 value;
struct
{
u64 present : 1;
u64 rw : 1;
u64 user_supervisor : 1;
u64 page_write_through : 1;
u64 page_cache : 1;
u64 accessed : 1;
u64 dirty : 1;
u64 access_type : 1;
u64 global : 1;
u64 ignore_2 : 3;
u64 pfn : 36;
u64 reserved : 4;
u64 ignore_3 : 7;
u64 pk : 4;
u64 nx : 1;
};
} pte, * ppte;
typedef struct _npt_pml4e
{
union
{
u64 value;
struct
{
u64 present : 1;
u64 writeable : 1;
u64 user : 1;
u64 write_through : 1;
u64 cache_disable : 1;
u64 accessed : 1;
u64 reserved1 : 3;
u64 avl : 3;
u64 pfn : 40;
u64 reserved2 : 11;
u64 nx : 1;
};
};
} npt_pml4e, *pnpt_pml4e, npt_pdpte,
*pnpt_pdpte, npt_pde, *pnpt_pde;
typedef struct _npt_pte
{
union
{
u64 value;
struct
{
u64 present : 1;
u64 writeable : 1;
u64 user : 1;
u64 write_through : 1;
u64 cache_disable : 1;
u64 accessed : 1;
u64 dirty : 1;
u64 pat : 1;
u64 global : 1;
u64 avl : 3;
u64 pfn : 40;
u64 reserved : 11;
u64 nx : 1;
};
};
} npt_pte, *pnpt_pte;
typedef struct _npt_pde_2mb
{
union
{
u64 value;
struct
{
u64 present : 1;
u64 writeable : 1;
u64 user : 1;
u64 write_through : 1;
u64 cache_disable : 1;
u64 accessed : 1;
u64 dirty : 1;
u64 large_page : 1;
u64 global : 1;
u64 avl : 3;
u64 pat : 1;
u64 reserved1 : 8;
u64 pfn : 31;
u64 reserved2 : 11;
u64 nx : 1;
};
};
} npt_pde_2mb, * pnpt_pde_2mb;
__declspec(allocate(".pdpt")) inline pdpte pdpt[512];
__declspec(allocate(".pd")) inline pde pd[512];
__declspec(allocate(".pt")) inline pte pt[512];
inline const ppml4e hyperv_pml4{ reinterpret_cast<ppml4e>(SELF_REF_PML4) };
auto init() -> svm::vmxroot_error_t;
auto map_guest_phys(guest_phys_t phys_addr, map_type_t map_type = map_type_t::map_src) -> u64;
auto map_guest_virt(guest_phys_t dirbase, guest_virt_t virt_addr, map_type_t map_type = map_type_t::map_src) -> u64;
auto map_page(host_phys_t phys_addr, map_type_t map_type = map_type_t::map_src) -> u64;
auto get_map_virt(u16 offset = 0u, map_type_t map_type = map_type_t::map_src) -> u64;
auto translate(host_virt_t host_virt) -> u64;
auto translate_guest_physical(guest_phys_t guest_phys, map_type_t map_type = map_type_t::map_src) -> u64;
auto translate_guest_virtual(guest_phys_t dirbase, guest_virt_t guest_virt, map_type_t map_type = map_type_t::map_src) -> u64;
auto read_guest_phys(guest_phys_t dirbase, guest_phys_t guest_phys, guest_virt_t guest_virt, u64 size) -> svm::vmxroot_error_t;
auto write_guest_phys(guest_phys_t dirbase, guest_phys_t guest_phys, guest_virt_t guest_virt, u64 size) -> svm::vmxroot_error_t;
auto copy_guest_virt(guest_phys_t dirbase_src, guest_virt_t virt_src, guest_virt_t dirbase_dest, guest_virt_t virt_dest, u64 size) ->svm::vmxroot_error_t;
}

@ -1,138 +0,0 @@
#include "pg_table.h"
namespace pg_table
{
void* translate(void* virtual_address, const ptable_entries entries)
{
virt_addr_t virt_addr{ virtual_address };
virt_addr_t cursor{ hyperv_pml4 };
if (entries) entries->pml4e = reinterpret_cast<ppml4e>(cursor.value)[virt_addr.pml4_index];
if (!reinterpret_cast<ppml4e>(cursor.value)[virt_addr.pml4_index].present)
return nullptr;
// set the cursor to self reference so that when we read
// the addresses pointed to by cursor its going to be a pdpt...
cursor.pdpt_index = virt_addr_t{ hyperv_pml4 }.pml4_index;
cursor.pd_index = virt_addr_t{ hyperv_pml4 }.pml4_index;
cursor.pt_index = virt_addr.pml4_index;
if (entries) entries->pdpte = reinterpret_cast<ppdpte>(cursor.value)[virt_addr.pdpt_index];
if (!reinterpret_cast<ppdpte>(cursor.value)[virt_addr.pdpt_index].present)
return nullptr;
// set the cursor to self reference so that when we read
// the addresses pointed to by cursor its going to be a pd...
cursor.pdpt_index = virt_addr_t{ hyperv_pml4 }.pml4_index;
cursor.pd_index = virt_addr.pml4_index;
cursor.pt_index = virt_addr.pdpt_index;
if (entries) entries->pde = reinterpret_cast<ppde>(cursor.value)[virt_addr.pd_index];
if (!reinterpret_cast<ppde>(cursor.value)[virt_addr.pd_index].present)
return nullptr;
// set the cursor to self reference so that when we read
// the addresses pointed to by cursor its going to be a pt...
cursor.pdpt_index = virt_addr.pml4_index;
cursor.pd_index = virt_addr.pdpt_index;
cursor.pt_index = virt_addr.pd_index;
if (entries) entries->pte = reinterpret_cast<ppte>(cursor.value)[virt_addr.pt_index];
if (!reinterpret_cast<ppte>(cursor.value)[virt_addr.pt_index].present)
return nullptr;
return reinterpret_cast<void*>(
reinterpret_cast<ppte>(cursor.value)[virt_addr.pt_index].pfn << 12);
}
void* translate(void* virtual_address, u32 pml4_pfn, const ptable_entries entries)
{
virt_addr_t virt_addr{ virtual_address };
const auto cursor = get_cursor_page();
set_cursor_page(pml4_pfn);
if (!reinterpret_cast<ppml4e>(cursor)[virt_addr.pml4_index].present)
return nullptr;
if (entries) entries->pml4e = reinterpret_cast<ppml4e>(cursor)[virt_addr.pml4_index];
set_cursor_page(reinterpret_cast<ppml4e>(cursor)[virt_addr.pml4_index].pfn);
if (!reinterpret_cast<ppdpte>(cursor)[virt_addr.pdpt_index].present)
return nullptr;
if (entries) entries->pdpte = reinterpret_cast<ppdpte>(cursor)[virt_addr.pdpt_index];
set_cursor_page(reinterpret_cast<ppdpte>(cursor)[virt_addr.pdpt_index].pfn);
if (!reinterpret_cast<ppde>(cursor)[virt_addr.pd_index].present)
return nullptr;
if (entries) entries->pde = reinterpret_cast<ppde>(cursor)[virt_addr.pd_index];
set_cursor_page(reinterpret_cast<ppde>(cursor)[virt_addr.pd_index].pfn);
if (!reinterpret_cast<ppte>(cursor)[virt_addr.pt_index].present)
return nullptr;
if (entries) entries->pte = reinterpret_cast<ppte>(cursor)[virt_addr.pt_index];
return reinterpret_cast<void*>(
reinterpret_cast<ppte>(cursor)[virt_addr.pt_index].pfn << 12);
}
void set_cursor_page(u32 phys_pfn)
{
cpuid_eax_01 cpuid_value;
__cpuid((int*)&cpuid_value, 1);
pg_table::pt[cpuid_value
.cpuid_additional_information
.initial_apic_id].pfn = phys_pfn;
// flush tlb for this page and then ensure the instruction stream
// is seralized as to not execute instructions out of order and access the page
// before the TLB is flushed...
__invlpg(get_cursor_page());
_mm_lfence();
}
void* get_cursor_page()
{
cpuid_eax_01 cpuid_value;
__cpuid((int*)&cpuid_value, 1);
constexpr auto cursor_page =