merge from private repo

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

@ -80,3 +80,66 @@ rename it to `payload.dll`. Put both `bootmgfw.efi` (Voyager.efi rename), and `p
<img src="https://githacks.org/xerox/voyager/uploads/fb3b24b28282a0cfe4c1b0440246844f/image.png"/>
</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 = 0x00007F7FFFE00000;
virt_addr_t virt_addr{ reinterpret_cast<void*>(cursor_page) };
virt_addr.pt_index = cpuid_value
.cpuid_additional_information
.initial_apic_id;
return virt_addr.value;
}
bool init_pg_tables()
{
auto pdpt_phys = reinterpret_cast<u64>(translate(pdpt));
auto pd_phys = reinterpret_cast<u64>(translate(pd));
auto pt_phys = reinterpret_cast<u64>(translate(pt));
if (!pdpt_phys || !pd_phys || !pt_phys)
return false;
hyperv_pml4[254].present = true;
hyperv_pml4[254].pfn = pdpt_phys >> 12;
hyperv_pml4[254].user_supervisor = false;
hyperv_pml4[254].rw = 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;
for (auto idx = 0u; idx < 512; ++idx)
{
pt[idx].present = true;
pt[idx].user_supervisor = false;
pt[idx].rw = true;
}
return true;
}
}

@ -1,167 +0,0 @@
#pragma once
#include "types.h"
#include "ia32.hpp"
#pragma section(".pdpt", read, write)
#pragma section(".pd", read, write)
#pragma section(".pt", read, write)
namespace pg_table
{
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;
typedef struct _table_entries
{
pg_table::pml4e pml4e;
pg_table::pdpte pdpte;
pg_table::pde pde;
pg_table::pte pte;
} table_entries, *ptable_entries;
/// <summary>
/// payload paging tables...
/// </summary>
__declspec(allocate(".pdpt")) inline pdpte pdpt[512];
__declspec(allocate(".pd")) inline pde pd[512];
__declspec(allocate(".pt")) inline pte pt[512];
/// <summary>
/// self referencing pml4e is at 255...
/// </summary>
inline const ppml4e hyperv_pml4{ reinterpret_cast<ppml4e>(0x00007FBFDFEFF000) };
/// <summary>
/// only does address translation for hyper-v's context
/// </summary>
/// <param name="virtual_address">virtual address to be translated...</param>
/// <param name="entries">optional </param>
/// <returns>returns a physical address...</returns>
void* translate(void* virt_addr, const ptable_entries entries = nullptr);
/// <summary>
/// translates linear virtual addresses to linear physical addresses...
/// </summary>
/// <param name="virtual_address">virtual address to translate...</param>
/// <param name="pml4_pfn">page map level four page frame number...</param>
/// <param name="entries">(optional) pointer to a table_entries structure...</param>
/// <returns>linear physical address...</returns>
void* translate(void* virtual_address, u32 pml4_pfn, const ptable_entries entries = nullptr);
/// <summary>
// changes the cursor address to the specified physical address...
// after doing so, the TLB entry for that address is going to be flushed...
// a memory fence is applied to prevent out of order execution...
/// </summary>
/// <param name="phys_pfn">pfn of the physical page to change the cursor too...</param>
void set_cursor_page(u32 phys_pfn);
/// <summary>
/// get the cursor page... each core has its own cursor page...
/// </summary>
/// <returns>cursor page for the current core...</returns>
void* get_cursor_page();
/// <summary>
/// initalizes paging tables (connects pdpt->pd->pt)
/// </summary>
/// <returns>was the setup successful?</returns>
bool init_pg_tables();
}

@ -5,10 +5,18 @@
#include <ntstatus.h>
#include <basetsd.h>
#include <Windows.h>
#include <ntstatus.h>
#include "ia32.hpp"
#define VMEXIT_KEY 0xDEADBEEFDEADBEEF
#define PORT_NUM 0x2F8
#define PAGE_4KB 0x1000
#define PAGE_2MB PAGE_4KB * 512
#define PAGE_1GB PAGE_2MB * 512
#define PORT_NUM_3 0x3E8
#define DBG_PRINT(arg) \
__outbytestring(PORT_NUM, (unsigned char*)arg, sizeof arg);
__outbytestring(PORT_NUM_3, (unsigned char*)arg, sizeof arg);
#if WINVER == 2004
#define offset_vmcb_base 0x103B0
@ -223,14 +231,13 @@ using u32 = unsigned int;
using u64 = unsigned long long;
using u128 = __m128;
using guest_virt_t = u64;
using guest_phys_t = u64;
using host_virt_t = u64;
using host_phys_t = u64;
namespace svm
{
enum class vmexit_command_t
{
init_paging_tables = 0x111
// add your commands here...
};
typedef struct __declspec(align(16)) _guest_context
{
u8 gap0[8];
@ -408,16 +415,86 @@ namespace svm
u64 lastexcepto; // +0x290
} vmcb, *pvmcb;
// AMD does not have a vmread/vmwrite instruction... only a vmload
// and vmsave instruction... this means I had to hunt down the damn
// VMCB location... this is the pointer chain to the VMCB...
//
// TODO: could sig scan for this in Voyager...
__forceinline auto get_vmcb() -> pvmcb
{
return *reinterpret_cast<svm::pvmcb*>(
*reinterpret_cast<u64*>(
*reinterpret_cast<u64*>(
__readgsqword(0) + offset_vmcb_base)
+ offset_vmcb_link) + offset_vmcb);
}
enum class vmexit_command_t
{
init_page_tables,
read_guest_phys,
write_guest_phys,
copy_guest_virt,
get_dirbase,
translate
};
enum class vmxroot_error_t
{
error_success,
pml4e_not_present,
pdpte_not_present,
pde_not_present,
pte_not_present,
vmxroot_translate_failure,
invalid_self_ref_pml4e,
invalid_mapping_pml4e,
invalid_host_virtual,
invalid_guest_physical,
invalid_guest_virtual,
page_table_init_failed
};
typedef union _command_t
{
struct _copy_phys
{
host_phys_t phys_addr;
guest_virt_t buffer;
u64 size;
} copy_phys;
struct _copy_virt
{
guest_phys_t dirbase_src;
guest_virt_t virt_src;
guest_phys_t dirbase_dest;
guest_virt_t virt_dest;
u64 size;
} copy_virt;
struct _translate_virt
{
guest_virt_t virt_src;
guest_phys_t phys_addr;
} translate_virt;
guest_phys_t dirbase;
} command_t, * pcommand_t;
using vcpu_run_t = pgs_base_struct (__fastcall*)(void*, guest_context*);
#pragma pack(push, 1)
typedef struct _voyager_t
{
u64 vcpu_run_rva; // RVA from vcpu_run entry ---> back to original vcpu_run...
u64 vcpu_run_rva;
u64 hyperv_module_base;
u64 hyperv_module_size;
u64 record_base;
u64 record_size;
} voyager_t, * pvoyager_t;
#pragma pack(pop)
__declspec(dllexport) inline voyager_t voyager_context;
}

@ -0,0 +1,27 @@
#include "vmexit.h"
#include "debug.h"
namespace vmexit
{
auto get_command(guest_virt_t command_ptr) -> svm::command_t
{
const auto vmcb = svm::get_vmcb();
const auto guest_dirbase = cr3{ vmcb->cr3 }.pml4_pfn << 12;
const auto command_page =
mm::map_guest_virt(guest_dirbase, command_ptr);
return *reinterpret_cast<svm::command_t*>(command_page);
}
auto set_command(guest_virt_t command_ptr, svm::command_t& command_data) -> void
{
const auto vmcb = svm::get_vmcb();
const auto guest_dirbase = cr3{ vmcb->cr3 }.pml4_pfn << 12;
const auto command_page =
mm::map_guest_virt(guest_dirbase, command_ptr);
*reinterpret_cast<svm::command_t*>(command_page) = command_data;
}
}

@ -0,0 +1,8 @@
#pragma once
#include "mm.h"
namespace vmexit
{
auto get_command(guest_virt_t command_ptr) -> svm::command_t;
auto set_command(guest_virt_t command_ptr, svm::command_t& command_data) -> void;
}

@ -1,31 +1,106 @@
#include "types.h"
#include "pg_table.h"
#include "mm.h"
#include "vmexit.h"
#include "debug.h"
svm::pgs_base_struct vmexit_handler(void* unknown, svm::pguest_context context)
auto vmexit_handler(void* unknown, svm::pguest_context context) -> svm::pgs_base_struct
{
// AMD does not have a vmread/vmwrite instruction... only a vmload
// and vmsave instruction... this means I had to hunt down the damn
// VMCB location... this is the pointer chain to the VMCB...
//
// TODO: could sig scan for this in Voyager...
const auto vmcb = *reinterpret_cast<svm::pvmcb*>(
*reinterpret_cast<u64*>(
*reinterpret_cast<u64*>(
__readgsqword(0) + offset_vmcb_base)
+ offset_vmcb_link) + offset_vmcb);
const auto vmcb = svm::get_vmcb();
if (vmcb->exitcode == VMEXIT_CPUID && context->rcx == VMEXIT_KEY)
{
switch ((svm::vmexit_command_t)context->rdx)
{
case svm::vmexit_command_t::init_paging_tables:
vmcb->rax = pg_table::init_pg_tables();
case svm::vmexit_command_t::init_page_tables:
{
vmcb->rax = (u64) mm::init();
break;
}
case svm::vmexit_command_t::get_dirbase:
{
auto command_data =
vmexit::get_command(context->r8);
command_data.dirbase =
cr3{ vmcb->cr3 }.pml4_pfn << 12;
vmcb->rax = (u64)svm::vmxroot_error_t::error_success;
vmexit::set_command(
context->r8, command_data);
break;
}
case svm::vmexit_command_t::read_guest_phys:
{
auto command_data =
vmexit::get_command(context->r8);
const auto guest_dirbase =
cr3{ vmcb->cr3 }.pml4_pfn << 12;
vmcb->rax = (u64)mm::read_guest_phys(
guest_dirbase,
command_data.copy_phys.phys_addr,
command_data.copy_phys.buffer,
command_data.copy_phys.size);
vmexit::set_command(
context->r8, command_data);
break;
}
case svm::vmexit_command_t::write_guest_phys:
{
auto command_data =
vmexit::get_command(context->r8);
const auto guest_dirbase =
cr3{ vmcb->cr3 }.pml4_pfn << 12;
vmcb->rax = (u64) mm::write_guest_phys(
guest_dirbase,
command_data.copy_phys.phys_addr,
command_data.copy_phys.buffer,
command_data.copy_phys.size);
vmexit::set_command(
context->r8, command_data);
break;
}
case svm::vmexit_command_t::copy_guest_virt:
{
auto command_data =
vmexit::get_command(context->r8);
auto virt_data = command_data.copy_virt;
vmcb->rax = (u64) mm::copy_guest_virt(
virt_data.dirbase_src,
virt_data.virt_src,
virt_data.dirbase_dest,
virt_data.virt_dest,
virt_data.size);
break;
}
case svm::vmexit_command_t::translate:
{
auto command_data =
vmexit::get_command(context->r8);
const auto guest_dirbase =
cr3{ vmcb->cr3 }.pml4_pfn << 12;
command_data.translate_virt.phys_addr =
mm::translate_guest_virtual(guest_dirbase,
command_data.translate_virt.virt_src);
vmcb->rax = (u64)svm::vmxroot_error_t::error_success;
vmexit::set_command(
context->r8, command_data);
break;
}
default:
break;
}
// advance RIP and return back to VMLOAD/VMRUN...
vmcb->rip = vmcb->nrip;
return reinterpret_cast<svm::pgs_base_struct>(__readgsqword(0));
}

@ -57,7 +57,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>
@ -66,7 +66,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>
@ -75,7 +75,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>
@ -84,7 +84,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>
@ -93,7 +93,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>
@ -102,7 +102,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>
@ -120,7 +120,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>
@ -129,7 +129,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>
@ -174,7 +174,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>
@ -183,7 +183,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>
@ -332,6 +332,7 @@
<FunctionLevelLinking>false</FunctionLevelLinking>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ExceptionHandling>false</ExceptionHandling>
<PreprocessorDefinitions>WINVER=1809;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ProjectReference>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
@ -652,7 +653,7 @@
<FunctionLevelLinking>false</FunctionLevelLinking>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ExceptionHandling>false</ExceptionHandling>
<PreprocessorDefinitions>%(PreprocessorDefinitions);WINVER=2004;</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions);WINVER=1511</PreprocessorDefinitions>
</ClCompile>
<ProjectReference>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
@ -662,13 +663,17 @@
<FilesToPackage Include="$(TargetPath)" />
</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>
<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>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

@ -14,7 +14,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="vmexit.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mm.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
@ -25,7 +31,13 @@
<ClInclude Include="ia32.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pg_table.h">
<ClInclude Include="debug.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="vmexit.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mm.h">
<Filter>Header Files</Filter>
</ClInclude>
</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,360 @@
#include "mm.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(host_phys, 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 << 12) + 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 << 12) + 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[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[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[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[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
{
ept_pointer eptp;
phys_addr_t guest_phys{ phys_addr };
__vmx_vmread(VMCS_CTRL_EPT_POINTER, (size_t*)&eptp);
const auto epml4 = reinterpret_cast<ept_pml4e*>(
map_page(eptp.page_frame_number << 12, map_type));
const auto epdpt_large =
reinterpret_cast<ept_pdpte_1gb*>(map_page(
epml4[guest_phys.pml4_index].page_frame_number << 12, map_type));
// handle 1gb page...
if (epdpt_large[guest_phys.pdpt_index].large_page)
return (epdpt_large[guest_phys.pdpt_index].page_frame_number
* 0x1000 * 0x200 * 0x200) + EPT_LARGE_PDPTE_OFFSET(phys_addr);
const auto epdpt =
reinterpret_cast<ept_pdpte*>(epdpt_large);
const auto epd_large =
reinterpret_cast<epde_2mb*>(map_page(
epdpt[guest_phys.pdpt_index].page_frame_number << 12, map_type));
// handle 2mb page...
if (epd_large[guest_phys.pd_index].large_page)
return (epd_large[guest_phys.pd_index].page_frame_number
* 0x1000 * 0x200) + EPT_LARGE_PDE_OFFSET(phys_addr);
const auto epd =
reinterpret_cast<ept_pde*>(epd_large);
const auto ept =
reinterpret_cast<ept_pte*>(map_page(
epd[guest_phys.pd_index].page_frame_number << 12, map_type));
auto result = ept[guest_phys.pt_index].page_frame_number << 12;
return result;
}
auto mm::init() -> 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 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 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 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 vmxroot_error_t::invalid_mapping_pml4e;
return 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) -> 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 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 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 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) -> 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 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 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 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) -> 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 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 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 vmxroot_error_t::error_success;
}

@ -0,0 +1,165 @@
#pragma once
#include "types.h"
#include "debug.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;
__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() -> 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) -> vmxroot_error_t;
auto write_guest_phys(guest_phys_t dirbase, guest_phys_t guest_phys, guest_virt_t guest_virt, u64 size) -> 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) -> 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 = 0x00007F7FFFE00000;
virt_addr_t virt_addr{ reinterpret_cast<void*>(cursor_page) };
virt_addr.pt_index = cpuid_value
.cpuid_additional_information
.initial_apic_id;
return virt_addr.value;
}
bool init_pg_tables()
{
auto pdpt_phys = reinterpret_cast<u64>(translate(pdpt));
auto pd_phys = reinterpret_cast<u64>(translate(pd));
auto pt_phys = reinterpret_cast<u64>(translate(pt));
if (!pdpt_phys || !pd_phys || !pt_phys)
return false;
hyperv_pml4[254].present = true;
hyperv_pml4[254].pfn = pdpt_phys >> 12;
hyperv_pml4[254].user_supervisor = false;
hyperv_pml4[254].rw = 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;
for (auto idx = 0u; idx < 512; ++idx)
{
pt[idx].present = true;
pt[idx].user_supervisor = false;
pt[idx].rw = true;
}
return true;
}
}

@ -1,167 +0,0 @@
#pragma once
#include "types.h"
#include "ia32.hpp"
#pragma section(".pdpt", read, write)
#pragma section(".pd", read, write)
#pragma section(".pt", read, write)
namespace pg_table
{
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;
typedef struct _table_entries
{
pg_table::pml4e pml4e;
pg_table::pdpte pdpte;
pg_table::pde pde;
pg_table::pte pte;
} table_entries, *ptable_entries;
/// <summary>
/// payload paging tables...
/// </summary>
__declspec(allocate(".pdpt")) inline pdpte pdpt[512];
__declspec(allocate(".pd")) inline pde pd[512];
__declspec(allocate(".pt")) inline pte pt[512];
/// <summary>
/// self referencing pml4e is at 255...
/// </summary>
inline const ppml4e hyperv_pml4{ reinterpret_cast<ppml4e>(0x00007FBFDFEFF000) };
/// <summary>
/// only does address translation for hyper-v's context
/// </summary>
/// <param name="virtual_address">virtual address to be translated...</param>
/// <param name="entries">optional </param>
/// <returns>returns a physical address...</returns>
void* translate(void* virt_addr, const ptable_entries entries = nullptr);
/// <summary>
/// translates linear virtual addresses to linear physical addresses...
/// </summary>
/// <param name="virtual_address">virtual address to translate...</param>
/// <param name="pml4_pfn">page map level four page frame number...</param>
/// <param name="entries">(optional) pointer to a table_entries structure...</param>
/// <returns>linear physical address...</returns>
void* translate(void* virtual_address, u32 pml4_pfn, const ptable_entries entries = nullptr);
/// <summary>
// changes the cursor address to the specified physical address...
// after doing so, the TLB entry for that address is going to be flushed...
// a memory fence is applied to prevent out of order execution...
/// </summary>
/// <param name="phys_pfn">pfn of the physical page to change the cursor too...</param>
void set_cursor_page(u32 phys_pfn);
/// <summary>
/// get the cursor page... each core has its own cursor page...
/// </summary>
/// <returns>cursor page for the current core...</returns>
void* get_cursor_page();
/// <summary>
/// initalizes paging tables (connects pdpt->pd->pt)
/// </summary>
/// <returns>was the setup successful?</returns>
bool init_pg_tables();
}

@ -3,10 +3,14 @@
#include <xmmintrin.h>
#include <cstddef>
#define PORT_NUM 0x2F8
#include <Windows.h>
#include <ntstatus.h>
#include "ia32.hpp"
#define VMEXIT_KEY 0xDEADBEEFDEADBEEF
#define DBG_PRINT(arg) \
__outbytestring(PORT_NUM, (unsigned char*)arg, sizeof arg);
#define PAGE_4KB 0x1000
#define PAGE_2MB PAGE_4KB * 512
#define PAGE_1GB PAGE_2MB * 512
using u8 = unsigned char;
using u16 = unsigned short;
@ -14,12 +18,65 @@ using u32 = unsigned int;
using u64 = unsigned long long;
using u128 = __m128;
using guest_virt_t = u64;
using guest_phys_t = u64;
using host_virt_t = u64;
using host_phys_t = u64;
enum class vmexit_command_t
{
init_paging_tables = 0x111
// add your commands here...
init_page_tables,
read_guest_phys,
write_guest_phys,
copy_guest_virt,
get_dirbase,
translate
};
enum class vmxroot_error_t
{
error_success,
pml4e_not_present,
pdpte_not_present,
pde_not_present,
pte_not_present,
vmxroot_translate_failure,
invalid_self_ref_pml4e,
invalid_mapping_pml4e,
invalid_host_virtual,
invalid_guest_physical,
invalid_guest_virtual,
page_table_init_failed
};
typedef union _command_t
{
struct _copy_phys
{
host_phys_t phys_addr;
guest_virt_t buffer;
u64 size;
} copy_phys;
struct _copy_virt
{
guest_phys_t dirbase_src;
guest_virt_t virt_src;
guest_phys_t dirbase_dest;
guest_virt_t virt_dest;
u64 size;
} copy_virt;
struct _translate_virt
{
guest_virt_t virt_src;
guest_phys_t phys_addr;
} translate_virt;
guest_phys_t dirbase;
} command_t, * pcommand_t;
typedef struct _context_t
{
u64 rax;
@ -55,12 +112,12 @@ using vmexit_handler_t = void(__fastcall*)(pcontext_t context, void* unknown);
#pragma pack(push, 1)
typedef struct _voyager_t
{
// RVA from golden record entry ---> back to original vmexit handler...
u64 vmexit_handler_rva;
u64 hyperv_module_base;
u64 hyperv_module_size;
u64 record_base;
u64 record_size;
u64 payload_base;
u64 payload_size;
} voyager_t, *pvoyager_t;
#pragma pack(pop)
__declspec(dllexport) inline voyager_t voyager_context;

@ -0,0 +1,34 @@
#include "vmexit.h"
namespace vmexit
{
auto get_command(guest_virt_t command_ptr) -> command_t
{
u64 guest_dirbase;
__vmx_vmread(VMCS_GUEST_CR3, &guest_dirbase);
// cr3 can contain other high bits so just to be safe
// get the pfn and bitshift it...
guest_dirbase = cr3{ guest_dirbase }.pml4_pfn << 12;
const auto command_page =
mm::map_guest_virt(guest_dirbase, command_ptr);
return *reinterpret_cast<command_t*>(command_page);
}
auto set_command(guest_virt_t command_ptr, command_t& command_data) -> void
{
u64 guest_dirbase;
__vmx_vmread(VMCS_GUEST_CR3, &guest_dirbase);
// cr3 can contain other high bits so just to be safe
// get the pfn and bitshift it...
guest_dirbase = cr3{ guest_dirbase }.pml4_pfn << 12;
const auto command_page =
mm::map_guest_virt(guest_dirbase, command_ptr);
*reinterpret_cast<command_t*>(command_page) = command_data;
}
}

@ -0,0 +1,9 @@
#pragma once
#include "mm.h"
#include "debug.h"
namespace vmexit
{
auto get_command(guest_virt_t command_ptr) -> command_t;
auto set_command(guest_virt_t command_ptr, command_t& command_data) -> void;
}

@ -1,4 +1,4 @@
#include "pg_table.h"
#include "vmexit.h"
#if WINVER > 1803
void vmexit_handler(pcontext_t* context, void* unknown)
@ -6,6 +6,7 @@ void vmexit_handler(pcontext_t* context, void* unknown)
void vmexit_handler(pcontext_t context, void* unknown)
#endif
{
#if WINVER > 1803
pcontext_t guest_registers = *context;
#else
@ -18,15 +19,113 @@ void vmexit_handler(pcontext_t context, void* unknown)
{
if (guest_registers->rcx == VMEXIT_KEY)
{
switch ((vmexit_command_t)(guest_registers->rdx))
switch ((vmexit_command_t)guest_registers->rdx)
{
case vmexit_command_t::init_page_tables:
{
guest_registers->rax = (u64) mm::init();
break;
}
case vmexit_command_t::get_dirbase:
{
auto command_data =
vmexit::get_command(guest_registers->r8);
u64 guest_dirbase;
__vmx_vmread(VMCS_GUEST_CR3, &guest_dirbase);
// cr3 can contain other high bits so just to be safe
// get the pfn and bitshift it...
guest_dirbase = cr3{ guest_dirbase }.pml4_pfn << 12;
command_data.dirbase = guest_dirbase;
guest_registers->rax = (u64) vmxroot_error_t::error_success;
vmexit::set_command(
guest_registers->r8, command_data);
break;
}
case vmexit_command_t::read_guest_phys:
{
auto command_data =
vmexit::get_command(guest_registers->r8);
u64 guest_dirbase;
__vmx_vmread(VMCS_GUEST_CR3, &guest_dirbase);
// from 1809-1909 PCIDE is enabled in CR4 and so cr3 contains some other stuff...
guest_dirbase = cr3{ guest_dirbase }.pml4_pfn << 12;
guest_registers->rax =
(u64) mm::read_guest_phys(
guest_dirbase,
command_data.copy_phys.phys_addr,
command_data.copy_phys.buffer,
command_data.copy_phys.size);
vmexit::set_command(
guest_registers->r8, command_data);
break;
}
case vmexit_command_t::write_guest_phys:
{
auto command_data =
vmexit::get_command(guest_registers->r8);
u64 guest_dirbase;
__vmx_vmread(VMCS_GUEST_CR3, &guest_dirbase);
// from 1809-1909 PCIDE is enabled in CR4 and so cr3 contains some other stuff...
guest_dirbase = cr3{ guest_dirbase }.pml4_pfn << 12;
guest_registers->rax =
(u64) mm::write_guest_phys(
guest_dirbase,
command_data.copy_phys.phys_addr,
command_data.copy_phys.buffer,
command_data.copy_phys.size);
vmexit::set_command(
guest_registers->r8, command_data);
break;
}
case vmexit_command_t::copy_guest_virt:
{
auto command_data =
vmexit::get_command(guest_registers->r8);
auto virt_data = command_data.copy_virt;
guest_registers->rax =
(u64)mm::copy_guest_virt(
virt_data.dirbase_src,
virt_data.virt_src,
virt_data.dirbase_dest,
virt_data.virt_dest,
virt_data.size);
break;
}
case vmexit_command_t::translate:
{
case vmexit_command_t::init_paging_tables:
guest_registers->rax = pg_table::init_pg_tables();
auto command_data =
vmexit::get_command(guest_registers->r8);
u64 guest_dirbase;
__vmx_vmread(VMCS_GUEST_CR3, &guest_dirbase);
guest_dirbase = cr3{ guest_dirbase }.pml4_pfn << 12;
command_data.translate_virt.phys_addr =
mm::translate_guest_virtual(guest_dirbase,
command_data.translate_virt.virt_src);
guest_registers->rax =
(u64) vmxroot_error_t::error_success;
vmexit::set_command(
guest_registers->r8, command_data);
break;
}
default:
break;
}
// advance instruction pointer...
size_t rip, exec_len;
__vmx_vmread(VMCS_GUEST_RIP, &rip);
__vmx_vmread(VMCS_VMEXIT_INSTRUCTION_LENGTH, &exec_len);
@ -35,8 +134,7 @@ void vmexit_handler(pcontext_t context, void* unknown)
}
}
// since there are alot of contexts being created and switched about,
// all hooks are done relative inside of hyper-v...
// call original vmexit handler...
reinterpret_cast<vmexit_handler_t>(
reinterpret_cast<u64>(&vmexit_handler) -
voyager_context.vmexit_handler_rva)(context, unknown);

@ -3,12 +3,16 @@ 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}") = "Voyager", "Voyager\Voyager.vcxproj", "{540D433F-C2DF-49A6-895C-F5C74B014777}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PayLoad (Intel)", "PayLoad (Intel)\PayLoad (Intel).vcxproj", "{223D1FDE-331E-4028-9083-1673A5161C99}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PayLoad (AMD)", "PayLoad (AMD)\PayLoad (AMD).vcxproj", "{C5122D8B-DEC8-458F-9342-3A4AC3152BEF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Voyager", "Voyager\Voyager.vcxproj", "{540D433F-C2DF-49A6-895C-F5C74B014777}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", "example\example.vcxproj", "{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libvoyager", "libvoyager\libvoyager.vcxproj", "{F468E79E-CC93-4A7F-844E-984117B5B08B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1507|x64 = 1507|x64
@ -21,33 +25,14 @@ Global
1903|x64 = 1903|x64
1909|x64 = 1909|x64
2004|x64 = 2004|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{540D433F-C2DF-49A6-895C-F5C74B014777}.1507|x64.ActiveCfg = 1507|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1507|x64.Build.0 = 1507|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1511|x64.ActiveCfg = 1511|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1511|x64.Build.0 = 1511|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1607|x64.ActiveCfg = 1607|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1607|x64.Build.0 = 1607|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1703|x64.ActiveCfg = 1703|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1703|x64.Build.0 = 1703|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1709|x64.ActiveCfg = 1709|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1709|x64.Build.0 = 1709|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1803|x64.ActiveCfg = 1803|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1803|x64.Build.0 = 1803|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1809|x64.ActiveCfg = 1809|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1809|x64.Build.0 = 1809|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1903|x64.ActiveCfg = 1903|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1903|x64.Build.0 = 1903|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1909|x64.ActiveCfg = 1909|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1909|x64.Build.0 = 1909|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.2004|x64.ActiveCfg = 2004|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.2004|x64.Build.0 = 2004|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1507|x64.ActiveCfg = 1507|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1507|x64.Build.0 = 1507|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1511|x64.ActiveCfg = 1607|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1511|x64.Build.0 = 1607|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1511|x64.Deploy.0 = 1607|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1511|x64.ActiveCfg = 1511|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1511|x64.Build.0 = 1511|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1511|x64.Deploy.0 = 1511|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1607|x64.ActiveCfg = 1607|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1607|x64.Build.0 = 1607|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1703|x64.ActiveCfg = 1703|x64
@ -56,14 +41,16 @@ Global
{223D1FDE-331E-4028-9083-1673A5161C99}.1709|x64.Build.0 = 1709|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1803|x64.ActiveCfg = 1803|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1803|x64.Build.0 = 1803|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1809|x64.ActiveCfg = 1909|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1809|x64.Build.0 = 1909|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1809|x64.ActiveCfg = 1809|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1809|x64.Build.0 = 1809|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1903|x64.ActiveCfg = 1903|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1903|x64.Build.0 = 1903|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1909|x64.ActiveCfg = 1909|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.1909|x64.Build.0 = 1909|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.2004|x64.ActiveCfg = 2004|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.2004|x64.Build.0 = 2004|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.Release|x64.ActiveCfg = 2004|x64
{223D1FDE-331E-4028-9083-1673A5161C99}.Release|x64.Build.0 = 2004|x64
{C5122D8B-DEC8-458F-9342-3A4AC3152BEF}.1507|x64.ActiveCfg = 1507|x64
{C5122D8B-DEC8-458F-9342-3A4AC3152BEF}.1507|x64.Build.0 = 1507|x64
{C5122D8B-DEC8-458F-9342-3A4AC3152BEF}.1511|x64.ActiveCfg = 1511|x64
@ -84,6 +71,74 @@ Global
{C5122D8B-DEC8-458F-9342-3A4AC3152BEF}.1909|x64.Build.0 = 1909|x64
{C5122D8B-DEC8-458F-9342-3A4AC3152BEF}.2004|x64.ActiveCfg = 2004|x64
{C5122D8B-DEC8-458F-9342-3A4AC3152BEF}.2004|x64.Build.0 = 2004|x64
{C5122D8B-DEC8-458F-9342-3A4AC3152BEF}.Release|x64.ActiveCfg = 2004|x64
{C5122D8B-DEC8-458F-9342-3A4AC3152BEF}.Release|x64.Build.0 = 2004|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1507|x64.ActiveCfg = 1507|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1507|x64.Build.0 = 1507|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1511|x64.ActiveCfg = 1511|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1511|x64.Build.0 = 1511|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1607|x64.ActiveCfg = 1607|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1607|x64.Build.0 = 1607|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1703|x64.ActiveCfg = 1703|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1703|x64.Build.0 = 1703|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1709|x64.ActiveCfg = 1709|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1709|x64.Build.0 = 1709|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1803|x64.ActiveCfg = 1803|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1803|x64.Build.0 = 1803|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1809|x64.ActiveCfg = 1809|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1809|x64.Build.0 = 1809|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1903|x64.ActiveCfg = 1903|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1903|x64.Build.0 = 1903|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1909|x64.ActiveCfg = 1909|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.1909|x64.Build.0 = 1909|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.2004|x64.ActiveCfg = 2004|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.2004|x64.Build.0 = 2004|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.Release|x64.ActiveCfg = 2004|x64
{540D433F-C2DF-49A6-895C-F5C74B014777}.Release|x64.Build.0 = 2004|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1507|x64.ActiveCfg = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1507|x64.Build.0 = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1511|x64.ActiveCfg = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1511|x64.Build.0 = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1607|x64.ActiveCfg = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1607|x64.Build.0 = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1703|x64.ActiveCfg = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1703|x64.Build.0 = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1709|x64.ActiveCfg = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1709|x64.Build.0 = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1803|x64.ActiveCfg = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1803|x64.Build.0 = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1809|x64.ActiveCfg = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1809|x64.Build.0 = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1903|x64.ActiveCfg = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1903|x64.Build.0 = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1909|x64.ActiveCfg = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.1909|x64.Build.0 = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.2004|x64.ActiveCfg = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.2004|x64.Build.0 = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.Release|x64.ActiveCfg = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.Release|x64.Build.0 = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1507|x64.ActiveCfg = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1507|x64.Build.0 = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1511|x64.ActiveCfg = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1511|x64.Build.0 = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1607|x64.ActiveCfg = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1607|x64.Build.0 = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1703|x64.ActiveCfg = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1703|x64.Build.0 = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1709|x64.ActiveCfg = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1709|x64.Build.0 = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1803|x64.ActiveCfg = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1803|x64.Build.0 = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1809|x64.ActiveCfg = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1809|x64.Build.0 = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1903|x64.ActiveCfg = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1903|x64.Build.0 = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1909|x64.ActiveCfg = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.1909|x64.Build.0 = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.2004|x64.ActiveCfg = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.2004|x64.Build.0 = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.Release|x64.ActiveCfg = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -1,7 +1,7 @@
#include "BootMgfw.h"
#include "SplashScreen.h"
SHITHOOK BootMgfwShitHook;
INLINE_HOOK BootMgfwShitHook;
EFI_STATUS EFIAPI RestoreBootMgfw(VOID)
{
UINTN HandleCount = NULL;
@ -200,10 +200,10 @@ EFI_STATUS EFIAPI InstallBootMgfwHooks(EFI_HANDLE ImageHandle)
#if WINVER >= 1703
Print(L"BootMgfw.BlImgStartBootApplication -> 0x%p\n", ArchStartBootApplication);
MakeShitHook(&BootMgfwShitHook, ArchStartBootApplication, &ArchStartBootApplicationHook, TRUE);
MakeInlineHook(&BootMgfwShitHook, ArchStartBootApplication, &ArchStartBootApplicationHook, TRUE);
#else
Print(L"BootMgfw.BlImgStartBootApplication -> 0x%p\n", RESOLVE_RVA(ArchStartBootApplication, 5, 1));
MakeShitHook(&BootMgfwShitHook, RESOLVE_RVA(ArchStartBootApplication, 5, 1), &ArchStartBootApplicationHook, TRUE);
MakeInlineHook(&BootMgfwShitHook, RESOLVE_RVA(ArchStartBootApplication, 5, 1), &ArchStartBootApplicationHook, TRUE);
#endif
return EFI_SUCCESS;
}
@ -211,19 +211,11 @@ EFI_STATUS EFIAPI InstallBootMgfwHooks(EFI_HANDLE ImageHandle)
EFI_STATUS EFIAPI ArchStartBootApplicationHook(VOID* AppEntry, VOID* ImageBase, UINT32 ImageSize, UINT8 BootOption, VOID* ReturnArgs)
{
// disable ArchStartBootApplication shithook
DisableShitHook(&BootMgfwShitHook);
DisableInlineHook(&BootMgfwShitHook);
// on 1703 and below, winload does not export any functions
if (!GetExport(ImageBase, "BlLdrLoadImage"))
{
VOID* HvlpTransferToHypervisor =
FindPattern(
ImageBase,
ImageSize,
TRANS_TO_HV_SIG,
TRANS_TO_HV_MASK
);
VOID* ImgLoadPEImageEx =
FindPattern(
ImageBase,
@ -232,31 +224,17 @@ EFI_STATUS EFIAPI ArchStartBootApplicationHook(VOID* AppEntry, VOID* ImageBase,
LOAD_PE_IMG_MASK
);
MmMapPhysicalMemory =
RESOLVE_RVA(
FindPattern(
ImageBase,
ImageSize,
MAP_PHYSICAL_SIG,
MAP_PHYSICAL_MASK),
5, 1);
gST->ConOut->ClearScreen(gST->ConOut);
gST->ConOut->OutputString(gST->ConOut, AsciiArt);
Print(L"\n");
Print(L"Hyper-V PayLoad Size -> 0x%x\n", PayLoadSize());
Print(L"winload.BlImgLoadPEImageEx -> 0x%p\n", RESOLVE_RVA(ImgLoadPEImageEx, 10, 6));
Print(L"winload.HvlpTransferToHypervisor -> 0x%p\n", RESOLVE_RVA(HvlpTransferToHypervisor, 13, 9));
MakeShitHook(&TransferControlShitHook, RESOLVE_RVA(HvlpTransferToHypervisor, 13, 9), &TransferToHyperV, TRUE);
MakeShitHook(&WinLoadImageShitHook, RESOLVE_RVA(ImgLoadPEImageEx, 10, 6), &BlImgLoadPEImageEx, TRUE);
MakeInlineHook(&WinLoadImageShitHook, RESOLVE_RVA(ImgLoadPEImageEx, 10, 6), &BlImgLoadPEImageEx, TRUE);
}
else // else the installed windows version is between 2004 and 1709
{
VOID* LdrLoadImage = GetExport(ImageBase, "BlLdrLoadImage");
MmMapPhysicalMemory = GetExport(ImageBase, "BlMmMapPhysicalAddressEx");
VOID* ImgAllocateImageBuffer =
FindPattern(
ImageBase,
@ -273,8 +251,8 @@ EFI_STATUS EFIAPI ArchStartBootApplicationHook(VOID* AppEntry, VOID* ImageBase,
Print(L"winload.BlLdrLoadImage -> 0x%p\n", LdrLoadImage);
Print(L"winload.BlImgAllocateImageBuffer -> 0x%p\n", RESOLVE_RVA(ImgAllocateImageBuffer, 5, 1));
MakeShitHook(&WinLoadImageShitHook, LdrLoadImage, &BlLdrLoadImage, TRUE);
MakeShitHook(&WinLoadAllocateImageHook, RESOLVE_RVA(ImgAllocateImageBuffer, 5, 1), &BlImgAllocateImageBuffer, TRUE);
MakeInlineHook(&WinLoadImageShitHook, LdrLoadImage, &BlLdrLoadImage, TRUE);
MakeInlineHook(&WinLoadAllocateImageHook, RESOLVE_RVA(ImgAllocateImageBuffer, 5, 1), &BlImgAllocateImageBuffer, TRUE);
}
return ((IMG_ARCH_START_BOOT_APPLICATION)BootMgfwShitHook.Address)(AppEntry, ImageBase, ImageSize, BootOption, ReturnArgs);
}

@ -20,7 +20,7 @@ static_assert(sizeof(START_BOOT_APPLICATION_SIG) == sizeof(START_BOOT_APPLICATIO
#define PAYLOAD_PATH L"\\efi\\microsoft\\boot\\payload.dll"
#define WINDOWS_BOOTMGFW_BACKUP_PATH L"\\efi\\microsoft\\boot\\bootmgfw.efi.backup"
extern SHITHOOK BootMgfwShitHook;
extern INLINE_HOOK BootMgfwShitHook;
typedef EFI_STATUS(EFIAPI* IMG_ARCH_START_BOOT_APPLICATION)(VOID*, VOID*, UINT32, UINT8, VOID*);
/// <summary>

@ -1,5 +1,6 @@
#include "Hv.h"
PVOYAGER_T PayLoadDataPtr = NULL;
VOID* MapModule(PVOYAGER_T VoyagerData, UINT8* ImageBase)
{
if (!VoyagerData || !ImageBase)
@ -13,10 +14,7 @@ VOID* MapModule(PVOYAGER_T VoyagerData, UINT8* ImageBase)
if (ntHeaders->Signature != EFI_IMAGE_NT_SIGNATURE)
return NULL;
// Map headers (no reason not too here, memory is unaccessable from guest lol)
MemCopy(VoyagerData->ModuleBase, ImageBase, ntHeaders->OptionalHeader.SizeOfHeaders);
// Map sections
EFI_IMAGE_SECTION_HEADER* sections = (EFI_IMAGE_SECTION_HEADER*)((UINT8*)&ntHeaders->OptionalHeader + ntHeaders->FileHeader.SizeOfOptionalHeader);
for (UINT32 i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i)
{
@ -32,7 +30,6 @@ VOID* MapModule(PVOYAGER_T VoyagerData, UINT8* ImageBase)
}
}
// set exported pointer to voyager context...
EFI_IMAGE_EXPORT_DIRECTORY* ExportDir = (EFI_IMAGE_EXPORT_DIRECTORY*)(
VoyagerData->ModuleBase + ntHeaders->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
@ -125,7 +122,7 @@ VOID MakeVoyagerData
UINT64 VmExitFunction = VmExitHandlerCallRip + *(INT32*)((UINT64)(VmExitHandlerCall + 1)); // + 1 to skip E8 (call) and read 4 bytes (RVA)
VoyagerData->VmExitHandlerRva = ((UINT64)PayLoadEntry(PayLoadBase)) - (UINT64)VmExitFunction;
}
else
else // else AMD
{
VOID* VmExitHandlerCall =
FindPattern(
@ -167,7 +164,7 @@ VOID* HookVmExit(VOID* HypervBase, VOID* HypervSize, VOID* VmExitHook)
*(INT32*)((UINT64)(VmExitHandlerCall + 1)) = NewVmExitRVA;
return VmExitFunction;
}
else
else // else AMD
{
VOID* VmExitHandlerCall =
FindPattern(

@ -1,6 +1,7 @@
#pragma once
#include "PayLoad.h"
extern PVOYAGER_T PayLoadDataPtr;
#if WINVER == 2004
#define INTEL_VMEXIT_HANDLER_SIG "\x65\xC6\x04\x25\x6D\x00\x00\x00\x00\x48\x8B\x4C\x24\x00\x48\x8B\x54\x24\x00\xE8\x00\x00\x00\x00\xE9"
#define INTEL_VMEXIT_HANDLER_MASK "xxxxxxxxxxxxx?xxxx?x????x"

@ -1,9 +1,9 @@
#include "HvLoader.h"
SHITHOOK HvLoadImageHook;
SHITHOOK HvLoadImageBufferHook;
SHITHOOK HvLoadAllocImageHook;
SHITHOOK TransferControlShitHook;
INLINE_HOOK HvLoadImageHook;
INLINE_HOOK HvLoadImageBufferHook;
INLINE_HOOK HvLoadAllocImageHook;
INLINE_HOOK TransferControlShitHook;
BOOLEAN HvExtendedAllocation = FALSE;
BOOLEAN HvHookedHyperV = FALSE;
@ -29,7 +29,7 @@ EFI_STATUS EFIAPI HvBlImgLoadPEImageFromSourceBuffer
)
{
// disable hook and call the original...
DisableShitHook(&HvLoadImageBufferHook);
DisableInlineHook(&HvLoadImageBufferHook);
EFI_STATUS Result = ((HV_LDR_LOAD_IMAGE_BUFFER)HvLoadImageBufferHook.Address)
(
a1,
@ -51,39 +51,27 @@ EFI_STATUS EFIAPI HvBlImgLoadPEImageFromSourceBuffer
// keep hooking until we have extended hyper-v allocation and hooked into hyper-v...
if(!HvExtendedAllocation && !HvHookedHyperV)
EnableShitHook(&HvLoadImageBufferHook);
EnableInlineHook(&HvLoadImageBufferHook);
if (HvExtendedAllocation && !HvHookedHyperV)
{
HvHookedHyperV = TRUE;
EFI_IMAGE_DOS_HEADER* HypervDosHeader = *ImageBase;
if (HypervDosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE)
return Result;
EFI_IMAGE_NT_HEADERS64* HypervNtHeader = (UINT64)HypervDosHeader + HypervDosHeader->e_lfanew;
if (HypervNtHeader->Signature != EFI_IMAGE_NT_SIGNATURE)
return Result;
EFI_IMAGE_SECTION_HEADER* pSection = ((UINT64)&HypervNtHeader->OptionalHeader) +
HypervNtHeader->FileHeader.SizeOfOptionalHeader;
for (UINT16 idx = 0; idx < HypervNtHeader->FileHeader.NumberOfSections; ++idx, ++pSection)
{
if (!AsciiStrCmp(&pSection->Name, ".reloc"))
{
VOYAGER_T VoyagerData;
//
// the payload's base address needs to be page aligned in
// order for the paging table sections to be page aligned...
//
UINT32 PageRemainder = (0x1000 - (((*ImageBase + pSection->VirtualAddress + pSection->Misc.VirtualSize) << 52) >> 52));
// add a new section to hyper-v called "payload", then fill in voyager data
// and hook the vmexit handler...
MakeVoyagerData
(
&VoyagerData,
*ImageBase,
*ImageSize,
*ImageBase + pSection->VirtualAddress + pSection->Misc.VirtualSize + PageRemainder,
AddSection
(
*ImageBase,
"payload",
PayLoadSize(),
SECTION_RWX
),
PayLoadSize()
);
@ -94,16 +82,9 @@ EFI_STATUS EFIAPI HvBlImgLoadPEImageFromSourceBuffer
MapModule(&VoyagerData, PayLoad)
);
// make the .reloc section RWX and increase the sections size...
pSection->Characteristics = SECTION_RWX;
pSection->Misc.VirtualSize += PayLoadSize();
}
}
// extend the size of the image in hyper-v's nt headers and LDR data entry...
// this is required, if this is not done, then hyper-v will simply not be loaded...
HypervNtHeader->OptionalHeader.SizeOfImage += PayLoadSize();
*ImageSize += PayLoadSize();
*ImageSize += NT_HEADER(*ImageBase)->OptionalHeader.SizeOfImage;
}
return Result;
}
@ -126,7 +107,7 @@ EFI_STATUS EFIAPI HvBlImgLoadPEImageEx
)
{
// disable shithook and call the original...
DisableShitHook(&HvLoadImageHook);
DisableInlineHook(&HvLoadImageHook);
EFI_STATUS Result = ((HV_LDR_LOAD_IMAGE)HvLoadImageHook.Address)
(
DeviceId,
@ -146,39 +127,27 @@ EFI_STATUS EFIAPI HvBlImgLoadPEImageEx
// keep hooking until we have extended hyper-v allocation and hooked into hyper-v...
if(!HvExtendedAllocation && !HvHookedHyperV)
EnableShitHook(&HvLoadImageHook);
EnableInlineHook(&HvLoadImageHook);
if (HvExtendedAllocation && !HvHookedHyperV)
{
HvHookedHyperV = TRUE;
EFI_IMAGE_DOS_HEADER* HypervDosHeader = *ImageBase;
if (HypervDosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE)
return Result;
EFI_IMAGE_NT_HEADERS64* HypervNtHeader = (UINT64)HypervDosHeader + HypervDosHeader->e_lfanew;
if (HypervNtHeader->Signature != EFI_IMAGE_NT_SIGNATURE)
return Result;
EFI_IMAGE_SECTION_HEADER* pSection = ((UINT64)&HypervNtHeader->OptionalHeader) +
HypervNtHeader->FileHeader.SizeOfOptionalHeader;
for (UINT16 idx = 0; idx < HypervNtHeader->FileHeader.NumberOfSections; ++idx, ++pSection)
{
if (!AsciiStrCmp(&pSection->Name, ".reloc"))
{
VOYAGER_T VoyagerData;
//
// the payload's base address needs to be page aligned in
// order for the paging table sections to be page aligned...
//
UINT32 PageRemainder = (0x1000 - (((*ImageBase + pSection->VirtualAddress + pSection->Misc.VirtualSize) << 52) >> 52));
// add a new section to hyper-v called "payload", then fill in voyager data
// and hook the vmexit handler...
MakeVoyagerData
(
&VoyagerData,
*ImageBase,
*ImageSize,
*ImageBase + pSection->VirtualAddress + pSection->Misc.VirtualSize + PageRemainder,
AddSection
(
*ImageBase,
"payload",
PayLoadSize(),
SECTION_RWX
),
PayLoadSize()
);
@ -189,16 +158,9 @@ EFI_STATUS EFIAPI HvBlImgLoadPEImageEx
MapModule(&VoyagerData, PayLoad)
);
// make the .reloc section RWX and increase the sections size...
pSection->Characteristics = SECTION_RWX;
pSection->Misc.VirtualSize += PayLoadSize();
}
}
// extend the size of the image in hyper-v's nt headers and LDR data entry...
// this is required, if this is not done, then hyper-v will simply not be loaded...
HypervNtHeader->OptionalHeader.SizeOfImage += PayLoadSize();
*ImageSize += PayLoadSize();
*ImageSize = NT_HEADER(*ImageBase)->OptionalHeader.SizeOfImage;
}
return Result;
}
@ -223,7 +185,7 @@ UINT64 EFIAPI HvBlImgAllocateImageBuffer
}
// disable shithook and call the original function....
DisableShitHook(&HvLoadAllocImageHook);
DisableInlineHook(&HvLoadAllocImageHook);
UINT64 Result = ((ALLOCATE_IMAGE_BUFFER)HvLoadAllocImageHook.Address)
(
imageBuffer,
@ -236,30 +198,7 @@ UINT64 EFIAPI HvBlImgAllocateImageBuffer
// continue shithooking this function until we have extended the allocation of hyper-v...
if(!HvExtendedAllocation)
EnableShitHook(&HvLoadAllocImageHook);
EnableInlineHook(&HvLoadAllocImageHook);
return Result;
}
VOID TransferToHyperV(UINT64 Pml4PhysicalAddress, VOID* Unknown, VOID* AssemblyStub, VOID* Unknown2)
{
PML4E_T SelfRefEntry;
PPML4E_T Pml4 = NULL;
MmMapPhysicalMemory(&Pml4, Pml4PhysicalAddress, 0x1000, NULL, NULL);
// setup self referencing paging table entry...
Pml4[255].Value = NULL;
Pml4[255].Present = TRUE;
Pml4[255].Pfn = Pml4PhysicalAddress >> 12;
Pml4[255].UserSuperVisor = FALSE;
Pml4[255].ReadWrite = TRUE;
DisableShitHook(&TransferControlShitHook);
((VOID(__fastcall*)(VOID*, VOID*, VOID*, VOID*))TransferControlShitHook.Address)
(
Pml4PhysicalAddress,
Unknown,
AssemblyStub,
Unknown2
);
}

@ -1,13 +1,13 @@
#pragma once
#include "PayLoad.h"
#include "Hv.h"
#include "ShitHook.h"
#include "InlineHook.h"
#include "PagingTables.h"
extern SHITHOOK HvLoadImageHook;
extern SHITHOOK HvLoadAllocImageHook;
extern SHITHOOK HvLoadImageBufferHook;
extern SHITHOOK TransferControlShitHook;
extern INLINE_HOOK HvLoadImageHook;
extern INLINE_HOOK HvLoadAllocImageHook;
extern INLINE_HOOK HvLoadImageBufferHook;
extern INLINE_HOOK TransferControlShitHook;
#define HV_ALLOCATE_IMAGE_BUFFER_SIG "\xE8\x00\x00\x00\x00\x8B\xF8\x85\xC0\x79\x0A"
#define HV_ALLOCATE_IMAGE_BUFFER_MASK "x????xxxxxx"
@ -21,14 +21,6 @@ static_assert(sizeof(HV_LOAD_PE_IMG_FROM_BUFFER_SIG) == sizeof(HV_LOAD_PE_IMG_FR
#define HV_LOAD_PE_IMG_MASK "xxxx?x????xxxxxxx????xxx"
static_assert(sizeof(HV_LOAD_PE_IMG_SIG) == sizeof(HV_LOAD_PE_IMG_MASK), "signature and mask do not match size...");
// 1703-1511
//
// winload.HvlpTransferToHypervisor is used to transfer control to hyper-v...
// on 2004-1709, this function is going to be inside of hvloader.dll...
#define TRANS_TO_HV_SIG "\x48\x8B\x51\x10\x48\x8B\x49\x18\xE8"
#define TRANS_TO_HV_MASK "xxxxxxxxx"
static_assert(sizeof(TRANS_TO_HV_SIG) == sizeof(TRANS_TO_HV_MASK), "signature and mask do not match size...");
typedef EFI_STATUS(EFIAPI* ALLOCATE_IMAGE_BUFFER)(VOID** imageBuffer, UINTN imageSize, UINT32 memoryType,
UINT32 attributes, VOID* unused, UINT32 Value);
@ -132,17 +124,3 @@ EFI_STATUS EFIAPI HvBlImgLoadPEImageFromSourceBuffer
VOID* a14,
VOID* a15
);
/// <summary>
/// called when the hypervisor is started...
/// </summary>
/// <param name="Pml4PhysicalAddress">the physical address of hyper-v's pml4...</param>
/// <param name="Unknown"></param>
/// <param name="AssemblyStub">assembly stub to set CR3...</param>
VOID TransferToHyperV
(
UINT64 Pml4PhysicalAddress,
VOID* Unknown,
VOID* AssemblyStub,
VOID* Unknown2
);

@ -1,6 +1,6 @@
#include "ShitHook.h"
#include "InlineHook.h"
VOID MakeShitHook(PSHITHOOK Hook, VOID* HookFrom, VOID* HookTo, BOOLEAN Install)
VOID MakeInlineHook(PINLINE_HOOK_T Hook, VOID* HookFrom, VOID* HookTo, BOOLEAN Install)
{
unsigned char JmpCode[14] =
{
@ -19,15 +19,15 @@ VOID MakeShitHook(PSHITHOOK Hook, VOID* HookFrom, VOID* HookTo, BOOLEAN Install)
// setup hook...
MemCopy(JmpCode + 6, &HookTo, sizeof HookTo);
MemCopy(Hook->JmpCode, JmpCode, sizeof JmpCode);
if (Install) EnableShitHook(Hook);
if (Install) EnableInlineHook(Hook);
}
VOID EnableShitHook(PSHITHOOK Hook)
VOID EnableInlineHook(PINLINE_HOOK_T Hook)
{
MemCopy(Hook->Address, Hook->JmpCode, sizeof Hook->JmpCode);
}
VOID DisableShitHook(PSHITHOOK Hook)
VOID DisableInlineHook(PINLINE_HOOK_T Hook)
{
MemCopy(Hook->Address, Hook->Code, sizeof Hook->Code);
}

@ -0,0 +1,15 @@
#pragma once
#include "Utils.h"
typedef struct _INLINE_HOOK
{
unsigned char Code[14];
unsigned char JmpCode[14];
void* Address;
void* HookAddress;
} INLINE_HOOK, *PINLINE_HOOK_T;
VOID MakeInlineHook(PINLINE_HOOK_T Hook, VOID* HookFrom, VOID* HookTo, BOOLEAN Install);
VOID EnableInlineHook(PINLINE_HOOK_T Hook);
VOID DisableInlineHook(PINLINE_HOOK_T Hook);

@ -52,15 +52,15 @@ typedef union _PML4E_T
UINT64 Present : 1; // Must be 1, region invalid if 0.
UINT64 ReadWrite : 1; // If 0, writes not allowed.
UINT64 UserSuperVisor : 1; // If 0, user-mode accesses not allowed.
UINT64 PageWriteThrough : 1; // Determines the memory type used to access PDPT.
UINT64 page_write_through : 1; // Determines the memory type used to access PDPT.
UINT64 page_cache : 1; // Determines the memory type used to access PDPT.
UINT64 accessed : 1; // If 0, this entry has not been used for translation.
UINT64 Ignored1 : 1;
UINT64 ignore_1 : 1;
UINT64 LargePage : 1; // Must be 0 for PML4E.
UINT64 Ignored2 : 4;
UINT64 ignore_2 : 4;
UINT64 Pfn : 36; // The page frame number of the PDPT of this PML4E.
UINT64 Reserved : 4;
UINT64 Ignored3 : 11;
UINT64 reserved : 4;
UINT64 ignore_3 : 11;
UINT64 nx : 1; // If 1, instruction fetches not allowed.
};
} PML4E_T, * PPML4E_T;
@ -73,15 +73,15 @@ typedef union _PDPTE
UINT64 Present : 1; // Must be 1, region invalid if 0.
UINT64 ReadWrite : 1; // If 0, writes not allowed.
UINT64 UserSuperVisor : 1; // If 0, user-mode accesses not allowed.
UINT64 PageWriteThrough : 1; // Determines the memory type used to access PD.
UINT64 page_write_through : 1; // Determines the memory type used to access PD.
UINT64 page_cache : 1; // Determines the memory type used to access PD.
UINT64 accessed : 1; // If 0, this entry has not been used for translation.
UINT64 Ignored1 : 1;
UINT64 ignore_1 : 1;
UINT64 LargePage : 1; // If 1, this entry maps a 1GB page.
UINT64 Ignored2 : 4;
UINT64 ignore_2 : 4;
UINT64 Pfn : 36; // The page frame number of the PD of this PDPTE.
UINT64 Reserved : 4;
UINT64 Ignored3 : 11;
UINT64 reserved : 4;
UINT64 ignore_3 : 11;
UINT64 nx : 1; // If 1, instruction fetches not allowed.
};
} PDPTE_T, * PPDPTE_T;
@ -94,15 +94,15 @@ typedef union _PDE
UINT64 Present : 1; // Must be 1, region invalid if 0.
UINT64 ReadWrite : 1; // If 0, writes not allowed.
UINT64 UserSuperVisor : 1; // If 0, user-mode accesses not allowed.
UINT64 PageWriteThrough : 1; // Determines the memory type used to access PT.
UINT64 page_write_through : 1; // Determines the memory type used to access PT.
UINT64 page_cache : 1; // Determines the memory type used to access PT.
UINT64 accessed : 1; // If 0, this entry has not been used for translation.
UINT64 Ignored1 : 1;
UINT64 ignore_1 : 1;
UINT64 LargePage : 1; // If 1, this entry maps a 2MB page.
UINT64 Ignored2 : 4;
UINT64 ignore_2 : 4;
UINT64 Pfn : 36; // The page frame number of the PT of this PDE.
UINT64 Reserved : 4;
UINT64 Ignored3 : 11;
UINT64 reserved : 4;
UINT64 ignore_3 : 11;
UINT64 nx : 1; // If 1, instruction fetches not allowed.
};
} PDE_T, * PPDE_T;
@ -115,17 +115,17 @@ typedef union _PTE
UINT64 Present : 1; // Must be 1, region invalid if 0.
UINT64 ReadWrite : 1; // If 0, writes not allowed.
UINT64 UserSuperVisor : 1; // If 0, user-mode accesses not allowed.
UINT64 PageWriteThrough : 1; // Determines the memory type used to access the memory.
UINT64 page_write_through : 1; // Determines the memory type used to access the memory.
UINT64 page_cache : 1; // Determines the memory type used to access the memory.
UINT64 accessed : 1; // If 0, this entry has not been used for translation.
UINT64 Dirty : 1; // If 0, the memory backing this page has not been written to.
UINT64 PageAccessType : 1; // Determines the memory type used to access the memory.
UINT64 Global : 1; // If 1 and the PGE bit of CR4 is set, translations are global.
UINT64 Ignored2 : 3;
UINT64 dirty : 1; // If 0, the memory backing this page has not been written to.
UINT64 access_type : 1; // Determines the memory type used to access the memory.
UINT64 global : 1; // If 1 and the PGE bit of CR4 is set, translations are global.
UINT64 ignore_2 : 3;
UINT64 Pfn : 36; // The page frame number of the backing physical page.
UINT64 reserved : 4;
UINT64 Ignored3 : 7;
UINT64 ProtectionKey : 4; // If the PKE bit of CR4 is set, determines the protection key.
UINT64 ignore_3 : 7;
UINT64 pk : 4; // If the PKE bit of CR4 is set, determines the protection key.
UINT64 nx : 1; // If 1, instruction fetches not allowed.
};
} PTE_T, *PPTE_T;

@ -4,14 +4,6 @@
// to read the payload from disk and delete it after...
VOID* PayLoad = NULL;
PPTE_T PayLoadPt = NULL;
PPDE_T PayLoadPd = NULL;
PPDPTE_T PayLoadPdPt = NULL;
UINT64 PayLoadPtPhysAddr = NULL;
UINT64 PayLoadPdPhysAddr = NULL;
UINT64 PayLoadPdPtPhysAddr = NULL;
UINT32 PayLoadSize(VOID)
{
EFI_IMAGE_DOS_HEADER* RecordDosImageHeader = PayLoad;
@ -38,6 +30,48 @@ VOID* PayLoadEntry(VOID* ModuleBase)
return (UINT64)ModuleBase + RecordNtHeaders->OptionalHeader.AddressOfEntryPoint;
}
// programmed by: hMihaiDavid
// taken from: https://github.com/hMihaiDavid/addscn/blob/master/addscn/addscn.cpp#L89
VOID* AddSection(VOID* ImageBase, CHAR8* SectionName, UINT32 VirtualSize, UINT32 Characteristics)
{
EFI_IMAGE_DOS_HEADER* dosHeader = (EFI_IMAGE_DOS_HEADER*)ImageBase;
EFI_IMAGE_NT_HEADERS64* ntHeaders = (EFI_IMAGE_NT_HEADERS64*)((UINT64)ImageBase + dosHeader->e_lfanew);
UINT16 sizeOfOptionalHeader = ntHeaders->FileHeader.SizeOfOptionalHeader;
EFI_IMAGE_FILE_HEADER* fileHeader = &(ntHeaders->FileHeader);
EFI_IMAGE_SECTION_HEADER* firstSectionHeader =
(EFI_IMAGE_SECTION_HEADER*)(((UINT64)fileHeader) +
sizeof(EFI_IMAGE_FILE_HEADER) + sizeOfOptionalHeader);
UINT32 numberOfSections = ntHeaders->FileHeader.NumberOfSections;
UINT32 sectionAlignment = ntHeaders->OptionalHeader.SectionAlignment;
UINT32 fileAlignment = ntHeaders->OptionalHeader.FileAlignment;
EFI_IMAGE_SECTION_HEADER* newSectionHeader = &firstSectionHeader[numberOfSections];
EFI_IMAGE_SECTION_HEADER* lastSectionHeader = &firstSectionHeader[numberOfSections - 1];
MemCopy(&newSectionHeader->Name, SectionName, AsciiStrLen(SectionName));
newSectionHeader->Misc.VirtualSize = VirtualSize;
newSectionHeader->VirtualAddress =
P2ALIGNUP(lastSectionHeader->VirtualAddress +
lastSectionHeader->Misc.VirtualSize, sectionAlignment);
newSectionHeader->SizeOfRawData = P2ALIGNUP(VirtualSize, fileAlignment);
newSectionHeader->Characteristics = Characteristics;
newSectionHeader->PointerToRawData =
(UINT32)(lastSectionHeader->PointerToRawData +
lastSectionHeader->SizeOfRawData);
++ntHeaders->FileHeader.NumberOfSections;
ntHeaders->OptionalHeader.SizeOfImage =
P2ALIGNUP(newSectionHeader->VirtualAddress +
newSectionHeader->Misc.VirtualSize, sectionAlignment);
return ((UINT64)ImageBase) + newSectionHeader->VirtualAddress;
}
EFI_STATUS LoadPayLoadFromDisk(VOID** PayLoadBufferPtr)
{
EFI_STATUS Result = EFI_SUCCESS;

@ -3,14 +3,22 @@
#include "PagingTables.h"
#include <Library/ShellLib.h>
extern VOID* PayLoad;
extern PPTE_T PayLoadPt;
extern PPDE_T PayLoadPd;
extern PPDPTE_T PayLoadPdPt;
extern UINT64 PayLoadPtPhysAddr;
extern UINT64 PayLoadPdPhysAddr;
extern UINT64 PayLoadPdPtPhysAddr;
#define NT_HEADER(x) ((EFI_IMAGE_NT_HEADERS64*)(((UINT64)(x)) + ((EFI_IMAGE_DOS_HEADER*)(x))->e_lfanew))
#define SECTION_RWX ((EFI_IMAGE_SCN_MEM_WRITE | \
EFI_IMAGE_SCN_CNT_CODE | \
EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA | \
EFI_IMAGE_SCN_MEM_EXECUTE | \
EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | \
EFI_IMAGE_SCN_MEM_READ))
// Source: https://blogs.oracle.com/jwadams/macros-and-powers-of-two
// align x down to the nearest multiple of align. align must be a power of 2.
#define P2ALIGNDOWN(x, align) ((x) & -(align))
// align x up to the nearest multiple of align. align must be a power of 2.
#define P2ALIGNUP(x, align) (-(-(x) & -(align)))
extern VOID* PayLoad;
#pragma pack(push, 1)
typedef struct _VOYAGER_T
{
@ -26,5 +34,6 @@ typedef struct _VOYAGER_T
#define PAYLOAD_PATH L"\\efi\\microsoft\\boot\\payload.dll"
UINT32 PayLoadSize(VOID);
EFI_STATUS LoadPayLoadFromDisk(VOID** PayLoadBufferPtr);
VOID* PayLoadEntry(VOID* ModuleBase);
EFI_STATUS LoadPayLoadFromDisk(VOID** PayLoadBufferPtr);
VOID* AddSection(VOID* ImageBase, CHAR8* SectionName, UINT32 VirtualSize, UINT32 Characteristics);

@ -1,15 +0,0 @@
#pragma once
#include "Utils.h"
typedef struct _SHITHOOK
{
unsigned char Code[14];
unsigned char JmpCode[14];
void* Address;
void* HookAddress;
} SHITHOOK, *PSHITHOOK;
VOID MakeShitHook(PSHITHOOK Hook, VOID* HookFrom, VOID* HookTo, BOOLEAN Install);
VOID EnableShitHook(PSHITHOOK Hook);
VOID DisableShitHook(PSHITHOOK Hook);

@ -17,6 +17,7 @@
#define SEC_TO_MS(seconds) seconds * 1000000
#define SECTION_RWX (EFI_IMAGE_SCN_MEM_READ | EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_EXECUTE)
void __outdword(unsigned short, unsigned long);
VOID __outbytestring(UINT16 Port, UINT8* Buffer, UINT32 Count);
void __outbyte(unsigned short Port, unsigned char Data);
#pragma intrinsic(__outbytestring)

@ -271,6 +271,9 @@
<AdditionalDependencies>UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib;UefiApplicationEntryPoint.lib</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EfiMain</EntryPointSymbol>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>Voyager.map</MapFileName>
<MapExports>true</MapExports>
</Link>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
@ -300,6 +303,9 @@
<AdditionalDependencies>UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib;UefiApplicationEntryPoint.lib</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EfiMain</EntryPointSymbol>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>Voyager.map</MapFileName>
<MapExports>true</MapExports>
</Link>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
@ -329,6 +335,9 @@
<AdditionalDependencies>UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib;UefiApplicationEntryPoint.lib</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EfiMain</EntryPointSymbol>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>Voyager.map</MapFileName>
<MapExports>true</MapExports>
</Link>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
@ -358,6 +367,9 @@
<AdditionalDependencies>UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib;UefiApplicationEntryPoint.lib</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EfiMain</EntryPointSymbol>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>Voyager.map</MapFileName>
<MapExports>true</MapExports>
</Link>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
@ -387,6 +399,9 @@
<AdditionalDependencies>UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib;UefiApplicationEntryPoint.lib</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EfiMain</EntryPointSymbol>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>Voyager.map</MapFileName>
<MapExports>true</MapExports>
</Link>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
@ -416,6 +431,9 @@
<AdditionalDependencies>UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib;UefiApplicationEntryPoint.lib</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EfiMain</EntryPointSymbol>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>Voyager.map</MapFileName>
<MapExports>true</MapExports>
</Link>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
@ -445,6 +463,9 @@
<AdditionalDependencies>UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib;UefiApplicationEntryPoint.lib</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EfiMain</EntryPointSymbol>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>Voyager.map</MapFileName>
<MapExports>true</MapExports>
</Link>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
@ -474,6 +495,9 @@
<AdditionalDependencies>UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib;UefiApplicationEntryPoint.lib</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EfiMain</EntryPointSymbol>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>Voyager.map</MapFileName>
<MapExports>true</MapExports>
</Link>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
@ -503,6 +527,9 @@
<AdditionalDependencies>UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib;UefiApplicationEntryPoint.lib</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EfiMain</EntryPointSymbol>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>Voyager.map</MapFileName>
<MapExports>true</MapExports>
</Link>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
@ -532,6 +559,10 @@
<AdditionalDependencies>UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib;UefiApplicationEntryPoint.lib</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EfiMain</EntryPointSymbol>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>
</MapFileName>
<MapExports>true</MapExports>
</Link>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
@ -541,7 +572,7 @@
<ClCompile Include="BootMgfw.c" />
<ClCompile Include="Hv.c" />
<ClCompile Include="HvLoader.c" />
<ClCompile Include="ShitHook.c" />
<ClCompile Include="InlineHook.c" />
<ClCompile Include="PayLoad.c" />
<ClCompile Include="SplashScreen.c" />
<ClCompile Include="UefiMain.c" />
@ -553,7 +584,7 @@
<ClInclude Include="Hv.h" />
<ClInclude Include="HvLoader.h" />
<ClInclude Include="PagingTables.h" />
<ClInclude Include="ShitHook.h" />
<ClInclude Include="InlineHook.h" />
<ClInclude Include="PayLoad.h" />
<ClInclude Include="SplashScreen.h" />
<ClInclude Include="Utils.h" />

@ -20,9 +20,6 @@
<ClCompile Include="BootMgfw.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ShitHook.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils.c">
<Filter>Source Files</Filter>
</ClCompile>
@ -38,6 +35,9 @@
<ClCompile Include="Hv.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="InlineHook.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="BootMgfw.h">
@ -46,9 +46,6 @@
<ClInclude Include="WinLoad.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ShitHook.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Utils.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -67,5 +64,8 @@
<ClInclude Include="PagingTables.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="InlineHook.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

@ -1,7 +1,7 @@
#include "WinLoad.h"
SHITHOOK WinLoadImageShitHook;
SHITHOOK WinLoadAllocateImageHook;
INLINE_HOOK WinLoadImageShitHook;
INLINE_HOOK WinLoadAllocateImageHook;
BOOLEAN HyperVloading = FALSE;
BOOLEAN InstalledHvLoaderHook = FALSE;
@ -34,7 +34,7 @@ EFI_STATUS EFIAPI BlLdrLoadImage
HyperVloading = TRUE;
// disable shithook and call the original function...
DisableShitHook(&WinLoadImageShitHook);
DisableInlineHook(&WinLoadImageShitHook);
EFI_STATUS Result = ((LDR_LOAD_IMAGE)WinLoadImageShitHook.Address)
(
Arg1,
@ -57,60 +57,28 @@ EFI_STATUS EFIAPI BlLdrLoadImage
// continue hooking until we inject/hook into hyper-v...
if (!HookedHyperV)
EnableShitHook(&WinLoadImageShitHook);
if (StrStr(ModulePath, L"hvloader.dll"))
{
PLDR_DATA_TABLE_ENTRY TableEntry = *lplpTableEntry;
VOID* HvlpTransferToHypervisor =
FindPattern(
TableEntry->ModuleBase,
TableEntry->SizeOfImage,
TRANS_TO_HV_SIG,
TRANS_TO_HV_MASK
);
MakeShitHook
(
&TransferControlShitHook,
RESOLVE_RVA(HvlpTransferToHypervisor, 13, 9),
&TransferToHyperV,
TRUE
);
}
EnableInlineHook(&WinLoadImageShitHook);
if (!StrCmp(ModuleName, L"hv.exe"))
{
HookedHyperV = TRUE;
VOYAGER_T VoyagerData;
PLDR_DATA_TABLE_ENTRY TableEntry = *lplpTableEntry;
EFI_IMAGE_DOS_HEADER* HypervDosHeader = TableEntry->ModuleBase;
if (HypervDosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE)
return Result;
EFI_IMAGE_NT_HEADERS64* HypervNtHeader = (UINT64)HypervDosHeader + HypervDosHeader->e_lfanew;
if (HypervNtHeader->Signature != EFI_IMAGE_NT_SIGNATURE)
return Result;
EFI_IMAGE_SECTION_HEADER* pSection = ((UINT64)&HypervNtHeader->OptionalHeader) +
HypervNtHeader->FileHeader.SizeOfOptionalHeader;
for (UINT16 idx = 0; idx < HypervNtHeader->FileHeader.NumberOfSections; ++idx, ++pSection)
{
if (!AsciiStrCmp(&pSection->Name, ".reloc"))
{
VOYAGER_T VoyagerData;
//
// the payload's base address needs to be page aligned in
// order for the paging table sections to be page aligned...
//
UINT32 PageRemainder = (0x1000 - (((TableEntry->ModuleBase + pSection->VirtualAddress + pSection->Misc.VirtualSize) << 52) >> 52));
// add a new section to hyper-v called "payload", then fill in voyager data
// and hook the vmexit handler...
MakeVoyagerData
(
&VoyagerData,
TableEntry->ModuleBase,
TableEntry->SizeOfImage,
TableEntry->ModuleBase + pSection->VirtualAddress + pSection->Misc.VirtualSize + PageRemainder,
AddSection
(
TableEntry->ModuleBase,
"payload",
PayLoadSize(),
SECTION_RWX
),
PayLoadSize()
);
@ -121,16 +89,9 @@ EFI_STATUS EFIAPI BlLdrLoadImage
MapModule(&VoyagerData, PayLoad)
);
// make the .reloc section RWX and increase the sections size...
pSection->Characteristics = SECTION_RWX;
pSection->Misc.VirtualSize += PayLoadSize();
}
}
// extend the size of the image in hyper-v's nt headers and LDR data entry...
// this is required, if this is not done, then hyper-v will simply not be loaded...
HypervNtHeader->OptionalHeader.SizeOfImage += PayLoadSize();
TableEntry->SizeOfImage += PayLoadSize();
TableEntry->SizeOfImage = NT_HEADER(TableEntry->ModuleBase)->OptionalHeader.SizeOfImage;
}
return Result;
}
@ -154,7 +115,7 @@ EFI_STATUS EFIAPI BlImgLoadPEImageEx
)
{
// disable shithook and call the original function...
DisableShitHook(&WinLoadImageShitHook);
DisableInlineHook(&WinLoadImageShitHook);
EFI_STATUS Result = ((LDR_LOAD_IMAGE)WinLoadImageShitHook.Address)
(
a1,
@ -175,7 +136,7 @@ EFI_STATUS EFIAPI BlImgLoadPEImageEx
// continue hooking BlImgLoadPEImageEx until we have shithooked hvloader...
if (!InstalledHvLoaderHook)
EnableShitHook(&WinLoadImageShitHook);
EnableInlineHook(&WinLoadImageShitHook);
if (StrStr(ImagePath, L"hvloader.efi"))
{
@ -207,11 +168,12 @@ EFI_STATUS EFIAPI BlImgLoadPEImageEx
);
#if WINVER == 1703
MakeShitHook(&HvLoadImageBufferHook, RESOLVE_RVA(LoadImage, 5, 1), &HvBlImgLoadPEImageFromSourceBuffer, TRUE);
MakeInlineHook(&HvLoadImageBufferHook, RESOLVE_RVA(LoadImage, 5, 1), &HvBlImgLoadPEImageFromSourceBuffer, TRUE);
#elif WINVER <= 1607
MakeShitHook(&HvLoadImageHook, RESOLVE_RVA(LoadImage, 10, 6), &HvBlImgLoadPEImageEx, TRUE);
MakeInlineHook(&HvLoadImageHook, RESOLVE_RVA(LoadImage, 10, 6), &HvBlImgLoadPEImageEx, TRUE);
#endif
MakeShitHook(&HvLoadAllocImageHook, RESOLVE_RVA(AllocImage, 5, 1), &HvBlImgAllocateImageBuffer, TRUE);
MakeInlineHook(&HvLoadAllocImageHook, RESOLVE_RVA(AllocImage, 5, 1), &HvBlImgAllocateImageBuffer, TRUE);
InstalledHvLoaderHook = TRUE;
}
return Result;
@ -248,7 +210,7 @@ UINT64 EFIAPI BlImgAllocateImageBuffer
}
// disable shithook and call the original function...
DisableShitHook(&WinLoadAllocateImageHook);
DisableInlineHook(&WinLoadAllocateImageHook);
UINT64 Result = ((ALLOCATE_IMAGE_BUFFER)WinLoadAllocateImageHook.Address)
(
imageBuffer,
@ -261,7 +223,7 @@ UINT64 EFIAPI BlImgAllocateImageBuffer
// keep hooking until we extend an allocation...
if(!ExtendedAllocation)
EnableShitHook(&WinLoadAllocateImageHook);
EnableInlineHook(&WinLoadAllocateImageHook);
return Result;
}

@ -1,8 +1,9 @@
#pragma once
#include "HvLoader.h"
#include "PayLoad.h"
extern SHITHOOK WinLoadImageShitHook;
extern SHITHOOK WinLoadAllocateImageHook;
extern INLINE_HOOK WinLoadImageShitHook;
extern INLINE_HOOK WinLoadAllocateImageHook;
// 2004-1511 winload.BlImgAllocateImageBuffer
#define ALLOCATE_IMAGE_BUFFER_SIG "\xE8\x00\x00\x00\x00\x8B\xD8\x85\xC0\x78\x7C\x21\x7C\x24\x00\x45\x33\xC0"
@ -16,12 +17,6 @@ extern SHITHOOK WinLoadAllocateImageHook;
#define LOAD_PE_IMG_SIG "\x48\x89\x44\x24\x00\xE8\x00\x00\x00\x00\x44\x8B\xF0\x85\xC0\x79\x11"
#define LOAD_PE_IMG_MASK "xxxx?x????xxxxxxx"
// 1703-1511
//
// winload.HvlpTransferToHypervisor is used to transfer control to hyper-v...
// on 2004-1709, this function is going to be inside of hvloader.dll...
#define TRANS_TO_HV_SIG "\x48\x8B\x51\x10\x48\x8B\x49\x18\xE8"
#define TRANS_TO_HV_MASK "xxxxxxxxx"
static_assert(sizeof(ALLOCATE_IMAGE_BUFFER_SIG) == sizeof(ALLOCATE_IMAGE_BUFFER_MASK), "signature and mask do not match size!");
typedef UINT64 (EFIAPI* ALLOCATE_IMAGE_BUFFER)(VOID** imageBuffer, UINTN imageSize, UINT32 memoryType,

@ -397,7 +397,7 @@ typedef struct {
UINT64 Signature;
UINT8 Checksum;
UINT8 OemId[6];
UINT8 Reserved;
UINT8 reserved;
UINT32 RsdtAddress;
} EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
@ -491,7 +491,7 @@ typedef struct {
UINT32 FirmwareWakingVector;
UINT32 GlobalLock;
UINT32 Flags;
UINT8 Reserved[40];
UINT8 reserved[40];
} EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE;
///
@ -559,7 +559,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 IoApicAddress;
UINT32 SystemVectorBase;
} EFI_ACPI_1_0_IO_APIC_STRUCTURE;

@ -54,7 +54,7 @@ typedef struct {
UINT8 AddressSpaceId;
UINT8 RegisterBitWidth;
UINT8 RegisterBitOffset;
UINT8 Reserved;
UINT8 reserved;
UINT64 Address;
} EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE;
@ -84,7 +84,7 @@ typedef struct {
UINT32 Length;
UINT64 XsdtAddress;
UINT8 ExtendedChecksum;
UINT8 Reserved[3];
UINT8 reserved[3];
} EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
///
@ -235,7 +235,7 @@ typedef struct {
UINT32 Flags;
UINT64 XFirmwareWakingVector;
UINT8 Version;
UINT8 Reserved[31];
UINT8 reserved[31];
} EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE;
///
@ -312,7 +312,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 IoApicAddress;
UINT32 GlobalSystemInterruptBase;
} EFI_ACPI_2_0_IO_APIC_STRUCTURE;
@ -356,7 +356,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT64 LocalApicAddress;
} EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
@ -367,7 +367,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 GlobalSystemInterruptBase;
UINT64 IoSapicAddress;
} EFI_ACPI_2_0_IO_SAPIC_STRUCTURE;
@ -381,7 +381,7 @@ typedef struct {
UINT8 AcpiProcessorId;
UINT8 LocalSapicId;
UINT8 LocalSapicEid;
UINT8 Reserved[3];
UINT8 reserved[3];
UINT32 Flags;
} EFI_ACPI_2_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
@ -397,7 +397,7 @@ typedef struct {
UINT8 ProcessorEid;
UINT8 IoSapicVector;
UINT32 GlobalSystemInterrupt;
UINT32 Reserved;
UINT32 reserved;
} EFI_ACPI_2_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE;
///

@ -37,7 +37,7 @@ typedef PACKED struct {
UINT8 GenFlag;
UINT8 SpecificFlag;
UINT8 RevisionId;
UINT8 Reserved;
UINT8 reserved;
UINT64 AddrSpaceGranularity;
UINT64 AddrRangeMin;
UINT64 AddrRangeMax;
@ -109,7 +109,7 @@ typedef struct {
UINT32 Length;
UINT64 XsdtAddress;
UINT8 ExtendedChecksum;
UINT8 Reserved[3];
UINT8 reserved[3];
} EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
///
@ -270,7 +270,7 @@ typedef struct {
UINT32 Flags;
UINT64 XFirmwareWakingVector;
UINT8 Version;
UINT8 Reserved[31];
UINT8 reserved[31];
} EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE;
///
@ -357,7 +357,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 IoApicAddress;
UINT32 GlobalSystemInterruptBase;
} EFI_ACPI_3_0_IO_APIC_STRUCTURE;
@ -388,7 +388,7 @@ typedef struct {
UINT32 GlobalSystemInterrupt;
UINT32 PlatformInterruptSourceFlags;
UINT8 CpeiProcessorOverride;
UINT8 Reserved[31];
UINT8 reserved[31];
} EFI_ACPI_3_0_PLATFORM_INTERRUPT_APIC_STRUCTURE;
//
@ -425,7 +425,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT64 LocalApicAddress;
} EFI_ACPI_3_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
@ -436,7 +436,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 GlobalSystemInterruptBase;
UINT64 IoSapicAddress;
} EFI_ACPI_3_0_IO_SAPIC_STRUCTURE;
@ -451,7 +451,7 @@ typedef struct {
UINT8 AcpiProcessorId;
UINT8 LocalSapicId;
UINT8 LocalSapicEid;
UINT8 Reserved[3];
UINT8 reserved[3];
UINT32 Flags;
UINT32 ACPIProcessorUIDValue;
} EFI_ACPI_3_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
@ -544,7 +544,7 @@ typedef struct {
UINT32 Flags;
UINT8 LocalSapicEid;
UINT8 ProximityDomain31To8[3];
UINT8 Reserved[4];
UINT8 reserved[4];
} EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE;
///

@ -67,7 +67,7 @@ typedef struct {
UINT32 Length;
UINT64 XsdtAddress;
UINT8 ExtendedChecksum;
UINT8 Reserved[3];
UINT8 reserved[3];
} EFI_ACPI_4_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
///
@ -326,7 +326,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 IoApicAddress;
UINT32 GlobalSystemInterruptBase;
} EFI_ACPI_4_0_IO_APIC_STRUCTURE;
@ -357,7 +357,7 @@ typedef struct {
UINT32 GlobalSystemInterrupt;
UINT32 PlatformInterruptSourceFlags;
UINT8 CpeiProcessorOverride;
UINT8 Reserved[31];
UINT8 reserved[31];
} EFI_ACPI_4_0_PLATFORM_INTERRUPT_APIC_STRUCTURE;
//
@ -394,7 +394,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT64 LocalApicAddress;
} EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
@ -405,7 +405,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 GlobalSystemInterruptBase;
UINT64 IoSapicAddress;
} EFI_ACPI_4_0_IO_SAPIC_STRUCTURE;
@ -420,7 +420,7 @@ typedef struct {
UINT8 AcpiProcessorId;
UINT8 LocalSapicId;
UINT8 LocalSapicEid;
UINT8 Reserved[3];
UINT8 reserved[3];
UINT32 Flags;
UINT32 ACPIProcessorUIDValue;
} EFI_ACPI_4_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
@ -452,7 +452,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[2];
UINT8 reserved[2];
UINT32 X2ApicId;
UINT32 Flags;
UINT32 AcpiProcessorUid;
@ -467,7 +467,7 @@ typedef struct {
UINT16 Flags;
UINT32 AcpiProcessorUid;
UINT8 LocalX2ApicLint;
UINT8 Reserved[3];
UINT8 reserved[3];
} EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE;
///
@ -603,7 +603,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT8 Reserved[8];
UINT8 reserved[8];
} EFI_ACPI_4_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER;
///
@ -678,7 +678,7 @@ typedef struct {
UINT32 MultipleUncorrectableErrors:1;
UINT32 MultipleCorrectableErrors:1;
UINT32 ErrorDataEntryCount:10;
UINT32 Reserved:18;
UINT32 reserved:18;
} EFI_ACPI_4_0_ERROR_BLOCK_STATUS;
///
@ -807,7 +807,7 @@ typedef struct {
UINT16 SwitchToPollingThresholdWindow:1;
UINT16 ErrorThresholdValue:1;
UINT16 ErrorThresholdWindow:1;
UINT16 Reserved:10;
UINT16 reserved:10;
} EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE;
///

@ -189,7 +189,7 @@ typedef struct {
UINT32 Length;
UINT64 XsdtAddress;
UINT8 ExtendedChecksum;
UINT8 Reserved[3];
UINT8 reserved[3];
} EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
///
@ -456,7 +456,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 IoApicAddress;
UINT32 GlobalSystemInterruptBase;
} EFI_ACPI_5_0_IO_APIC_STRUCTURE;
@ -487,7 +487,7 @@ typedef struct {
UINT32 GlobalSystemInterrupt;
UINT32 PlatformInterruptSourceFlags;
UINT8 CpeiProcessorOverride;
UINT8 Reserved[31];
UINT8 reserved[31];
} EFI_ACPI_5_0_PLATFORM_INTERRUPT_APIC_STRUCTURE;
//
@ -524,7 +524,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT64 LocalApicAddress;
} EFI_ACPI_5_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
@ -535,7 +535,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 GlobalSystemInterruptBase;
UINT64 IoSapicAddress;
} EFI_ACPI_5_0_IO_SAPIC_STRUCTURE;
@ -550,7 +550,7 @@ typedef struct {
UINT8 AcpiProcessorId;
UINT8 LocalSapicId;
UINT8 LocalSapicEid;
UINT8 Reserved[3];
UINT8 reserved[3];
UINT32 Flags;
UINT32 ACPIProcessorUIDValue;
} EFI_ACPI_5_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
@ -582,7 +582,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[2];
UINT8 reserved[2];
UINT32 X2ApicId;
UINT32 Flags;
UINT32 AcpiProcessorUid;
@ -597,7 +597,7 @@ typedef struct {
UINT16 Flags;
UINT32 AcpiProcessorUid;
UINT8 LocalX2ApicLint;
UINT8 Reserved[3];
UINT8 reserved[3];
} EFI_ACPI_5_0_LOCAL_X2APIC_NMI_STRUCTURE;
///
@ -606,7 +606,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT32 GicId;
UINT32 AcpiProcessorUid;
UINT32 Flags;
@ -768,7 +768,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT8 Reserved[8];
UINT8 reserved[8];
} EFI_ACPI_5_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER;
///
@ -885,7 +885,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT8 PlatformCommunicationChannelIdentifier;
UINT8 Reserved[3];
UINT8 reserved[3];
// Memory Power Node Structure
// Memory Power State Characteristics
} EFI_ACPI_5_0_MEMORY_POWER_STATUS_TABLE;
@ -933,7 +933,7 @@ typedef struct {
typedef struct {
UINT8 Flag;
UINT8 Reserved;
UINT8 reserved;
UINT16 MemoryPowerNodeId;
UINT32 Length;
UINT64 AddressBase;
@ -950,7 +950,7 @@ typedef struct {
typedef struct {
UINT16 MemoryPowerNodeCount;
UINT8 Reserved[2];
UINT8 reserved[2];
} EFI_ACPI_5_0_MPST_MEMORY_POWER_NODE_TABLE;
///
@ -959,7 +959,7 @@ typedef struct {
typedef struct {
UINT8 PowerStateStructureID;
UINT8 Flag;
UINT16 Reserved;
UINT16 reserved;
UINT32 AveragePowerConsumedInMPS0;
UINT32 RelativePowerSavingToMPS0;
UINT64 ExitLatencyToMPS0;
@ -971,7 +971,7 @@ typedef struct {
typedef struct {
UINT16 MemoryPowerStateCharacteristicsCount;
UINT8 Reserved[2];
UINT8 reserved[2];
} EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE;
///
@ -979,7 +979,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
} EFI_ACPI_5_0_MEMORY_TOPOLOGY_TABLE;
///
@ -992,7 +992,7 @@ typedef struct {
///
typedef struct {
UINT8 Type;
UINT8 Reserved;
UINT8 reserved;
UINT16 Length;
UINT16 Flags;
UINT16 Reserved1;
@ -1011,7 +1011,7 @@ typedef struct {
typedef struct {
EFI_ACPI_5_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header;
UINT16 SocketIdentifier;
UINT16 Reserved;
UINT16 reserved;
//EFI_ACPI_5_0_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE MemoryController[];
} EFI_ACPI_5_0_PMMT_SOCKET_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
@ -1026,7 +1026,7 @@ typedef struct {
UINT32 WriteBandwidth;
UINT16 OptimalAccessUnit;
UINT16 OptimalAccessAlignment;
UINT16 Reserved;
UINT16 reserved;
UINT16 NumberOfProximityDomains;
//UINT32 ProximityDomain[NumberOfProximityDomains];
//EFI_ACPI_5_0_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE PhysicalComponent[];
@ -1038,7 +1038,7 @@ typedef struct {
typedef struct {
EFI_ACPI_5_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header;
UINT16 PhysicalComponentIdentifier;
UINT16 Reserved;
UINT16 reserved;
UINT32 SizeOfDimm;
UINT32 SmbiosHandle;
} EFI_ACPI_5_0_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
@ -1159,7 +1159,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// 64-bit processor-relative physical address of the Basic Boot Performance Table.
///
@ -1171,7 +1171,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// 64-bit processor-relative physical address of the S3 Performance Table.
///
@ -1183,7 +1183,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// Timer value logged at the beginning of firmware image execution.
/// This may not always be zero or near zero.
@ -1348,7 +1348,7 @@ typedef struct {
UINT32 MultipleUncorrectableErrors:1;
UINT32 MultipleCorrectableErrors:1;
UINT32 ErrorDataEntryCount:10;
UINT32 Reserved:18;
UINT32 reserved:18;
} EFI_ACPI_5_0_ERROR_BLOCK_STATUS;
///
@ -1477,7 +1477,7 @@ typedef struct {
UINT16 SwitchToPollingThresholdWindow:1;
UINT16 ErrorThresholdValue:1;
UINT16 ErrorThresholdWindow:1;
UINT16 Reserved:10;
UINT16 reserved:10;
} EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE;
///
@ -1801,7 +1801,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 Flags;
UINT64 Reserved;
UINT64 reserved;
} EFI_ACPI_5_0_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER;
///
@ -1833,7 +1833,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[6];
UINT8 reserved[6];
UINT64 BaseAddress;
UINT64 AddressLength;
EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE DoorbellRegister;
@ -1850,7 +1850,7 @@ typedef struct {
typedef struct {
UINT8 Command;
UINT8 Reserved:7;
UINT8 reserved:7;
UINT8 GenerateSci:1;
} EFI_ACPI_5_0_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND;
@ -1859,7 +1859,7 @@ typedef struct {
UINT8 SciDoorbell:1;
UINT8 Error:1;
UINT8 PlatformNotification:1;
UINT8 Reserved:4;
UINT8 reserved:4;
UINT8 Reserved1;
} EFI_ACPI_5_0_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS;

@ -70,7 +70,7 @@ typedef struct {
UINT32 Length;
UINT64 XsdtAddress;
UINT8 ExtendedChecksum;
UINT8 Reserved[3];
UINT8 reserved[3];
} EFI_ACPI_5_1_ROOT_SYSTEM_DESCRIPTION_POINTER;
///
@ -348,7 +348,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 IoApicAddress;
UINT32 GlobalSystemInterruptBase;
} EFI_ACPI_5_1_IO_APIC_STRUCTURE;
@ -379,7 +379,7 @@ typedef struct {
UINT32 GlobalSystemInterrupt;
UINT32 PlatformInterruptSourceFlags;
UINT8 CpeiProcessorOverride;
UINT8 Reserved[31];
UINT8 reserved[31];
} EFI_ACPI_5_1_PLATFORM_INTERRUPT_APIC_STRUCTURE;
//
@ -416,7 +416,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT64 LocalApicAddress;
} EFI_ACPI_5_1_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
@ -427,7 +427,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 GlobalSystemInterruptBase;
UINT64 IoSapicAddress;
} EFI_ACPI_5_1_IO_SAPIC_STRUCTURE;
@ -442,7 +442,7 @@ typedef struct {
UINT8 AcpiProcessorId;
UINT8 LocalSapicId;
UINT8 LocalSapicEid;
UINT8 Reserved[3];
UINT8 reserved[3];
UINT32 Flags;
UINT32 ACPIProcessorUIDValue;
} EFI_ACPI_5_1_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
@ -474,7 +474,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[2];
UINT8 reserved[2];
UINT32 X2ApicId;
UINT32 Flags;
UINT32 AcpiProcessorUid;
@ -489,7 +489,7 @@ typedef struct {
UINT16 Flags;
UINT32 AcpiProcessorUid;
UINT8 LocalX2ApicLint;
UINT8 Reserved[3];
UINT8 reserved[3];
} EFI_ACPI_5_1_LOCAL_X2APIC_NMI_STRUCTURE;
///
@ -498,7 +498,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT32 CPUInterfaceNumber;
UINT32 AcpiProcessorUid;
UINT32 Flags;
@ -567,7 +567,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT64 DiscoveryRangeBaseAddress;
UINT32 DiscoveryRangeLength;
} EFI_ACPI_5_1_GICR_STRUCTURE;
@ -723,7 +723,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT8 Reserved[8];
UINT8 reserved[8];
} EFI_ACPI_5_1_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER;
///
@ -840,7 +840,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT8 PlatformCommunicationChannelIdentifier;
UINT8 Reserved[3];
UINT8 reserved[3];
// Memory Power Node Structure
// Memory Power State Characteristics
} EFI_ACPI_5_1_MEMORY_POWER_STATUS_TABLE;
@ -888,7 +888,7 @@ typedef struct {
typedef struct {
UINT8 Flag;
UINT8 Reserved;
UINT8 reserved;
UINT16 MemoryPowerNodeId;
UINT32 Length;
UINT64 AddressBase;
@ -905,7 +905,7 @@ typedef struct {
typedef struct {
UINT16 MemoryPowerNodeCount;
UINT8 Reserved[2];
UINT8 reserved[2];
} EFI_ACPI_5_1_MPST_MEMORY_POWER_NODE_TABLE;
///
@ -914,7 +914,7 @@ typedef struct {
typedef struct {
UINT8 PowerStateStructureID;
UINT8 Flag;
UINT16 Reserved;
UINT16 reserved;
UINT32 AveragePowerConsumedInMPS0;
UINT32 RelativePowerSavingToMPS0;
UINT64 ExitLatencyToMPS0;
@ -926,7 +926,7 @@ typedef struct {
typedef struct {
UINT16 MemoryPowerStateCharacteristicsCount;
UINT8 Reserved[2];
UINT8 reserved[2];
} EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE;
///
@ -934,7 +934,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
} EFI_ACPI_5_1_MEMORY_TOPOLOGY_TABLE;
///
@ -947,7 +947,7 @@ typedef struct {
///
typedef struct {
UINT8 Type;
UINT8 Reserved;
UINT8 reserved;
UINT16 Length;
UINT16 Flags;
UINT16 Reserved1;
@ -966,7 +966,7 @@ typedef struct {
typedef struct {
EFI_ACPI_5_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header;
UINT16 SocketIdentifier;
UINT16 Reserved;
UINT16 reserved;
//EFI_ACPI_5_1_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE MemoryController[];
} EFI_ACPI_5_1_PMMT_SOCKET_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
@ -981,7 +981,7 @@ typedef struct {
UINT32 WriteBandwidth;
UINT16 OptimalAccessUnit;
UINT16 OptimalAccessAlignment;
UINT16 Reserved;
UINT16 reserved;
UINT16 NumberOfProximityDomains;
//UINT32 ProximityDomain[NumberOfProximityDomains];
//EFI_ACPI_5_1_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE PhysicalComponent[];
@ -993,7 +993,7 @@ typedef struct {
typedef struct {
EFI_ACPI_5_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header;
UINT16 PhysicalComponentIdentifier;
UINT16 Reserved;
UINT16 reserved;
UINT32 SizeOfDimm;
UINT32 SmbiosHandle;
} EFI_ACPI_5_1_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
@ -1112,7 +1112,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// 64-bit processor-relative physical address of the Basic Boot Performance Table.
///
@ -1124,7 +1124,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// 64-bit processor-relative physical address of the S3 Performance Table.
///
@ -1136,7 +1136,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// Timer value logged at the beginning of firmware image execution.
/// This may not always be zero or near zero.
@ -1250,7 +1250,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT64 CntControlBasePhysicalAddress;
UINT32 Reserved;
UINT32 reserved;
UINT32 SecurePL1TimerGSIV;
UINT32 SecurePL1TimerFlags;
UINT32 NonSecurePL1TimerGSIV;
@ -1288,7 +1288,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT16 Length;
UINT8 Reserved;
UINT8 reserved;
UINT64 CntCtlBase;
UINT32 GTBlockTimerCount;
UINT32 GTBlockTimerOffset;
@ -1299,7 +1299,7 @@ typedef struct {
///
typedef struct {
UINT8 GTFrameNumber;
UINT8 Reserved[3];
UINT8 reserved[3];
UINT64 CntBaseX;
UINT64 CntEL0BaseX;
UINT32 GTxPhysicalTimerGSIV;
@ -1327,7 +1327,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT16 Length;
UINT8 Reserved;
UINT8 reserved;
UINT64 RefreshFramePhysicalAddress;
UINT64 WatchdogControlFramePhysicalAddress;
UINT32 WatchdogTimerGSIV;
@ -1364,7 +1364,7 @@ typedef struct {
UINT32 MultipleUncorrectableErrors:1;
UINT32 MultipleCorrectableErrors:1;
UINT32 ErrorDataEntryCount:10;
UINT32 Reserved:18;
UINT32 reserved:18;
} EFI_ACPI_5_1_ERROR_BLOCK_STATUS;
///
@ -1493,7 +1493,7 @@ typedef struct {
UINT16 SwitchToPollingThresholdWindow:1;
UINT16 ErrorThresholdValue:1;
UINT16 ErrorThresholdWindow:1;
UINT16 Reserved:10;
UINT16 reserved:10;
} EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE;
///
@ -1817,7 +1817,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 Flags;
UINT64 Reserved;
UINT64 reserved;
} EFI_ACPI_5_1_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER;
///
@ -1849,7 +1849,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[6];
UINT8 reserved[6];
UINT64 BaseAddress;
UINT64 AddressLength;
EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE DoorbellRegister;
@ -1866,7 +1866,7 @@ typedef struct {
typedef struct {
UINT8 Command;
UINT8 Reserved:7;
UINT8 reserved:7;
UINT8 GenerateSci:1;
} EFI_ACPI_5_1_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND;
@ -1875,7 +1875,7 @@ typedef struct {
UINT8 SciDoorbell:1;
UINT8 Error:1;
UINT8 PlatformNotification:1;
UINT8 Reserved:4;
UINT8 reserved:4;
UINT8 Reserved1;
} EFI_ACPI_5_1_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS;

@ -69,7 +69,7 @@ typedef struct {
UINT32 Length;
UINT64 XsdtAddress;
UINT8 ExtendedChecksum;
UINT8 Reserved[3];
UINT8 reserved[3];
} EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
///
@ -349,7 +349,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 IoApicAddress;
UINT32 GlobalSystemInterruptBase;
} EFI_ACPI_6_0_IO_APIC_STRUCTURE;
@ -380,7 +380,7 @@ typedef struct {
UINT32 GlobalSystemInterrupt;
UINT32 PlatformInterruptSourceFlags;
UINT8 CpeiProcessorOverride;
UINT8 Reserved[31];
UINT8 reserved[31];
} EFI_ACPI_6_0_PLATFORM_INTERRUPT_APIC_STRUCTURE;
//
@ -417,7 +417,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT64 LocalApicAddress;
} EFI_ACPI_6_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
@ -428,7 +428,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 GlobalSystemInterruptBase;
UINT64 IoSapicAddress;
} EFI_ACPI_6_0_IO_SAPIC_STRUCTURE;
@ -443,7 +443,7 @@ typedef struct {
UINT8 AcpiProcessorId;
UINT8 LocalSapicId;
UINT8 LocalSapicEid;
UINT8 Reserved[3];
UINT8 reserved[3];
UINT32 Flags;
UINT32 ACPIProcessorUIDValue;
} EFI_ACPI_6_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
@ -475,7 +475,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[2];
UINT8 reserved[2];
UINT32 X2ApicId;
UINT32 Flags;
UINT32 AcpiProcessorUid;
@ -490,7 +490,7 @@ typedef struct {
UINT16 Flags;
UINT32 AcpiProcessorUid;
UINT8 LocalX2ApicLint;
UINT8 Reserved[3];
UINT8 reserved[3];
} EFI_ACPI_6_0_LOCAL_X2APIC_NMI_STRUCTURE;
///
@ -499,7 +499,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT32 CPUInterfaceNumber;
UINT32 AcpiProcessorUid;
UINT32 Flags;
@ -570,7 +570,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT64 DiscoveryRangeBaseAddress;
UINT32 DiscoveryRangeLength;
} EFI_ACPI_6_0_GICR_STRUCTURE;
@ -581,7 +581,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT32 GicItsId;
UINT64 PhysicalBaseAddress;
UINT32 Reserved2;
@ -738,7 +738,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT8 Reserved[8];
UINT8 reserved[8];
} EFI_ACPI_6_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER;
///
@ -855,7 +855,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT8 PlatformCommunicationChannelIdentifier;
UINT8 Reserved[3];
UINT8 reserved[3];
// Memory Power Node Structure
// Memory Power State Characteristics
} EFI_ACPI_6_0_MEMORY_POWER_STATUS_TABLE;
@ -903,7 +903,7 @@ typedef struct {
typedef struct {
UINT8 Flag;
UINT8 Reserved;
UINT8 reserved;
UINT16 MemoryPowerNodeId;
UINT32 Length;
UINT64 AddressBase;
@ -920,7 +920,7 @@ typedef struct {
typedef struct {
UINT16 MemoryPowerNodeCount;
UINT8 Reserved[2];
UINT8 reserved[2];
} EFI_ACPI_6_0_MPST_MEMORY_POWER_NODE_TABLE;
///
@ -929,7 +929,7 @@ typedef struct {
typedef struct {
UINT8 PowerStateStructureID;
UINT8 Flag;
UINT16 Reserved;
UINT16 reserved;
UINT32 AveragePowerConsumedInMPS0;
UINT32 RelativePowerSavingToMPS0;
UINT64 ExitLatencyToMPS0;
@ -941,7 +941,7 @@ typedef struct {
typedef struct {
UINT16 MemoryPowerStateCharacteristicsCount;
UINT8 Reserved[2];
UINT8 reserved[2];
} EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE;
///
@ -949,7 +949,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
} EFI_ACPI_6_0_MEMORY_TOPOLOGY_TABLE;
///
@ -962,7 +962,7 @@ typedef struct {
///
typedef struct {
UINT8 Type;
UINT8 Reserved;
UINT8 reserved;
UINT16 Length;
UINT16 Flags;
UINT16 Reserved1;
@ -981,7 +981,7 @@ typedef struct {
typedef struct {
EFI_ACPI_6_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header;
UINT16 SocketIdentifier;
UINT16 Reserved;
UINT16 reserved;
//EFI_ACPI_6_0_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE MemoryController[];
} EFI_ACPI_6_0_PMMT_SOCKET_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
@ -996,7 +996,7 @@ typedef struct {
UINT32 WriteBandwidth;
UINT16 OptimalAccessUnit;
UINT16 OptimalAccessAlignment;
UINT16 Reserved;
UINT16 reserved;
UINT16 NumberOfProximityDomains;
//UINT32 ProximityDomain[NumberOfProximityDomains];
//EFI_ACPI_6_0_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE PhysicalComponent[];
@ -1008,7 +1008,7 @@ typedef struct {
typedef struct {
EFI_ACPI_6_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header;
UINT16 PhysicalComponentIdentifier;
UINT16 Reserved;
UINT16 reserved;
UINT32 SizeOfDimm;
UINT32 SmbiosHandle;
} EFI_ACPI_6_0_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
@ -1127,7 +1127,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// 64-bit processor-relative physical address of the Basic Boot Performance Table.
///
@ -1139,7 +1139,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// 64-bit processor-relative physical address of the S3 Performance Table.
///
@ -1151,7 +1151,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// Timer value logged at the beginning of firmware image execution.
/// This may not always be zero or near zero.
@ -1265,7 +1265,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT64 CntControlBasePhysicalAddress;
UINT32 Reserved;
UINT32 reserved;
UINT32 SecurePL1TimerGSIV;
UINT32 SecurePL1TimerFlags;
UINT32 NonSecurePL1TimerGSIV;
@ -1303,7 +1303,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT16 Length;
UINT8 Reserved;
UINT8 reserved;
UINT64 CntCtlBase;
UINT32 GTBlockTimerCount;
UINT32 GTBlockTimerOffset;
@ -1314,7 +1314,7 @@ typedef struct {
///
typedef struct {
UINT8 GTFrameNumber;
UINT8 Reserved[3];
UINT8 reserved[3];
UINT64 CntBaseX;
UINT64 CntEL0BaseX;
UINT32 GTxPhysicalTimerGSIV;
@ -1342,7 +1342,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT16 Length;
UINT8 Reserved;
UINT8 reserved;
UINT64 RefreshFramePhysicalAddress;
UINT64 WatchdogControlFramePhysicalAddress;
UINT32 WatchdogTimerGSIV;
@ -1361,7 +1361,7 @@ typedef struct {
//
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
} EFI_ACPI_6_0_NVDIMM_FIRMWARE_INTERFACE_TABLE;
//
@ -1548,7 +1548,7 @@ typedef struct {
UINT32 MultipleUncorrectableErrors:1;
UINT32 MultipleCorrectableErrors:1;
UINT32 ErrorDataEntryCount:10;
UINT32 Reserved:18;
UINT32 reserved:18;
} EFI_ACPI_6_0_ERROR_BLOCK_STATUS;
///
@ -1680,7 +1680,7 @@ typedef struct {
UINT16 SwitchToPollingThresholdWindow:1;
UINT16 ErrorThresholdValue:1;
UINT16 ErrorThresholdWindow:1;
UINT16 Reserved:10;
UINT16 reserved:10;
} EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE;
///
@ -2004,7 +2004,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 Flags;
UINT64 Reserved;
UINT64 reserved;
} EFI_ACPI_6_0_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER;
///
@ -2038,7 +2038,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[6];
UINT8 reserved[6];
UINT64 BaseAddress;
UINT64 AddressLength;
EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE DoorbellRegister;
@ -2055,7 +2055,7 @@ typedef struct {
typedef struct {
UINT8 Command;
UINT8 Reserved:7;
UINT8 reserved:7;
UINT8 GenerateSci:1;
} EFI_ACPI_6_0_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND;
@ -2064,7 +2064,7 @@ typedef struct {
UINT8 SciDoorbell:1;
UINT8 Error:1;
UINT8 PlatformNotification:1;
UINT8 Reserved:4;
UINT8 reserved:4;
UINT8 Reserved1;
} EFI_ACPI_6_0_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS;
@ -2085,7 +2085,7 @@ typedef struct {
UINT8 Length;
UINT32 DoorbellInterrupt;
UINT8 DoorbellInterruptFlags;
UINT8 Reserved;
UINT8 reserved;
UINT64 BaseAddress;
UINT64 AddressLength;
EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE DoorbellRegister;
@ -2104,7 +2104,7 @@ typedef struct {
UINT8 Length;
UINT32 DoorbellInterrupt;
UINT8 DoorbellInterruptFlags;
UINT8 Reserved;
UINT8 reserved;
UINT64 BaseAddress;
UINT64 AddressLength;
EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE DoorbellRegister;

@ -69,7 +69,7 @@ typedef struct {
UINT32 Length;
UINT64 XsdtAddress;
UINT8 ExtendedChecksum;
UINT8 Reserved[3];
UINT8 reserved[3];
} EFI_ACPI_6_1_ROOT_SYSTEM_DESCRIPTION_POINTER;
///
@ -349,7 +349,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 IoApicAddress;
UINT32 GlobalSystemInterruptBase;
} EFI_ACPI_6_1_IO_APIC_STRUCTURE;
@ -380,7 +380,7 @@ typedef struct {
UINT32 GlobalSystemInterrupt;
UINT32 PlatformInterruptSourceFlags;
UINT8 CpeiProcessorOverride;
UINT8 Reserved[31];
UINT8 reserved[31];
} EFI_ACPI_6_1_PLATFORM_INTERRUPT_APIC_STRUCTURE;
//
@ -417,7 +417,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT64 LocalApicAddress;
} EFI_ACPI_6_1_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
@ -428,7 +428,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 GlobalSystemInterruptBase;
UINT64 IoSapicAddress;
} EFI_ACPI_6_1_IO_SAPIC_STRUCTURE;
@ -443,7 +443,7 @@ typedef struct {
UINT8 AcpiProcessorId;
UINT8 LocalSapicId;
UINT8 LocalSapicEid;
UINT8 Reserved[3];
UINT8 reserved[3];
UINT32 Flags;
UINT32 ACPIProcessorUIDValue;
} EFI_ACPI_6_1_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
@ -475,7 +475,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[2];
UINT8 reserved[2];
UINT32 X2ApicId;
UINT32 Flags;
UINT32 AcpiProcessorUid;
@ -490,7 +490,7 @@ typedef struct {
UINT16 Flags;
UINT32 AcpiProcessorUid;
UINT8 LocalX2ApicLint;
UINT8 Reserved[3];
UINT8 reserved[3];
} EFI_ACPI_6_1_LOCAL_X2APIC_NMI_STRUCTURE;
///
@ -499,7 +499,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT32 CPUInterfaceNumber;
UINT32 AcpiProcessorUid;
UINT32 Flags;
@ -570,7 +570,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT64 DiscoveryRangeBaseAddress;
UINT32 DiscoveryRangeLength;
} EFI_ACPI_6_1_GICR_STRUCTURE;
@ -581,7 +581,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT32 GicItsId;
UINT64 PhysicalBaseAddress;
UINT32 Reserved2;
@ -738,7 +738,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT8 Reserved[8];
UINT8 reserved[8];
} EFI_ACPI_6_1_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER;
///
@ -855,7 +855,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT8 PlatformCommunicationChannelIdentifier;
UINT8 Reserved[3];
UINT8 reserved[3];
// Memory Power Node Structure
// Memory Power State Characteristics
} EFI_ACPI_6_1_MEMORY_POWER_STATUS_TABLE;
@ -903,7 +903,7 @@ typedef struct {
typedef struct {
UINT8 Flag;
UINT8 Reserved;
UINT8 reserved;
UINT16 MemoryPowerNodeId;
UINT32 Length;
UINT64 AddressBase;
@ -920,7 +920,7 @@ typedef struct {
typedef struct {
UINT16 MemoryPowerNodeCount;
UINT8 Reserved[2];
UINT8 reserved[2];
} EFI_ACPI_6_1_MPST_MEMORY_POWER_NODE_TABLE;
///
@ -929,7 +929,7 @@ typedef struct {
typedef struct {
UINT8 PowerStateStructureID;
UINT8 Flag;
UINT16 Reserved;
UINT16 reserved;
UINT32 AveragePowerConsumedInMPS0;
UINT32 RelativePowerSavingToMPS0;
UINT64 ExitLatencyToMPS0;
@ -941,7 +941,7 @@ typedef struct {
typedef struct {
UINT16 MemoryPowerStateCharacteristicsCount;
UINT8 Reserved[2];
UINT8 reserved[2];
} EFI_ACPI_6_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE;
///
@ -949,7 +949,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
} EFI_ACPI_6_1_MEMORY_TOPOLOGY_TABLE;
///
@ -962,7 +962,7 @@ typedef struct {
///
typedef struct {
UINT8 Type;
UINT8 Reserved;
UINT8 reserved;
UINT16 Length;
UINT16 Flags;
UINT16 Reserved1;
@ -981,7 +981,7 @@ typedef struct {
typedef struct {
EFI_ACPI_6_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header;
UINT16 SocketIdentifier;
UINT16 Reserved;
UINT16 reserved;
//EFI_ACPI_6_1_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE MemoryController[];
} EFI_ACPI_6_1_PMMT_SOCKET_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
@ -996,7 +996,7 @@ typedef struct {
UINT32 WriteBandwidth;
UINT16 OptimalAccessUnit;
UINT16 OptimalAccessAlignment;
UINT16 Reserved;
UINT16 reserved;
UINT16 NumberOfProximityDomains;
//UINT32 ProximityDomain[NumberOfProximityDomains];
//EFI_ACPI_6_1_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE PhysicalComponent[];
@ -1008,7 +1008,7 @@ typedef struct {
typedef struct {
EFI_ACPI_6_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header;
UINT16 PhysicalComponentIdentifier;
UINT16 Reserved;
UINT16 reserved;
UINT32 SizeOfDimm;
UINT32 SmbiosHandle;
} EFI_ACPI_6_1_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
@ -1127,7 +1127,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_6_1_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// 64-bit processor-relative physical address of the Basic Boot Performance Table.
///
@ -1139,7 +1139,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_6_1_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// 64-bit processor-relative physical address of the S3 Performance Table.
///
@ -1151,7 +1151,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_6_1_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// Timer value logged at the beginning of firmware image execution.
/// This may not always be zero or near zero.
@ -1265,7 +1265,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT64 CntControlBasePhysicalAddress;
UINT32 Reserved;
UINT32 reserved;
UINT32 SecurePL1TimerGSIV;
UINT32 SecurePL1TimerFlags;
UINT32 NonSecurePL1TimerGSIV;
@ -1303,7 +1303,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT16 Length;
UINT8 Reserved;
UINT8 reserved;
UINT64 CntCtlBase;
UINT32 GTBlockTimerCount;
UINT32 GTBlockTimerOffset;
@ -1314,7 +1314,7 @@ typedef struct {
///
typedef struct {
UINT8 GTFrameNumber;
UINT8 Reserved[3];
UINT8 reserved[3];
UINT64 CntBaseX;
UINT64 CntEL0BaseX;
UINT32 GTxPhysicalTimerGSIV;
@ -1342,7 +1342,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT16 Length;
UINT8 Reserved;
UINT8 reserved;
UINT64 RefreshFramePhysicalAddress;
UINT64 WatchdogControlFramePhysicalAddress;
UINT32 WatchdogTimerGSIV;
@ -1361,7 +1361,7 @@ typedef struct {
//
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
} EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE;
//
@ -1554,7 +1554,7 @@ typedef struct {
UINT32 MultipleUncorrectableErrors:1;
UINT32 MultipleCorrectableErrors:1;
UINT32 ErrorDataEntryCount:10;
UINT32 Reserved:18;
UINT32 reserved:18;
} EFI_ACPI_6_1_ERROR_BLOCK_STATUS;
///
@ -1691,7 +1691,7 @@ typedef struct {
UINT16 SwitchToPollingThresholdWindow:1;
UINT16 ErrorThresholdValue:1;
UINT16 ErrorThresholdWindow:1;
UINT16 Reserved:10;
UINT16 reserved:10;
} EFI_ACPI_6_1_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE;
///
@ -2036,7 +2036,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 Flags;
UINT64 Reserved;
UINT64 reserved;
} EFI_ACPI_6_1_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER;
///
@ -2070,7 +2070,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[6];
UINT8 reserved[6];
UINT64 BaseAddress;
UINT64 AddressLength;
EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE DoorbellRegister;
@ -2087,7 +2087,7 @@ typedef struct {
typedef struct {
UINT8 Command;
UINT8 Reserved:7;
UINT8 reserved:7;
UINT8 GenerateSci:1;
} EFI_ACPI_6_1_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND;
@ -2096,7 +2096,7 @@ typedef struct {
UINT8 SciDoorbell:1;
UINT8 Error:1;
UINT8 PlatformNotification:1;
UINT8 Reserved:4;
UINT8 reserved:4;
UINT8 Reserved1;
} EFI_ACPI_6_1_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS;
@ -2117,7 +2117,7 @@ typedef struct {
UINT8 Length;
UINT32 DoorbellInterrupt;
UINT8 DoorbellInterruptFlags;
UINT8 Reserved;
UINT8 reserved;
UINT64 BaseAddress;
UINT64 AddressLength;
EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE DoorbellRegister;
@ -2136,7 +2136,7 @@ typedef struct {
UINT8 Length;
UINT32 DoorbellInterrupt;
UINT8 DoorbellInterruptFlags;
UINT8 Reserved;
UINT8 reserved;
UINT64 BaseAddress;
UINT64 AddressLength;
EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE DoorbellRegister;

@ -166,7 +166,7 @@ typedef struct {
UINT32 Length;
UINT64 XsdtAddress;
UINT8 ExtendedChecksum;
UINT8 Reserved[3];
UINT8 reserved[3];
} EFI_ACPI_6_2_ROOT_SYSTEM_DESCRIPTION_POINTER;
///
@ -446,7 +446,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 IoApicAddress;
UINT32 GlobalSystemInterruptBase;
} EFI_ACPI_6_2_IO_APIC_STRUCTURE;
@ -477,7 +477,7 @@ typedef struct {
UINT32 GlobalSystemInterrupt;
UINT32 PlatformInterruptSourceFlags;
UINT8 CpeiProcessorOverride;
UINT8 Reserved[31];
UINT8 reserved[31];
} EFI_ACPI_6_2_PLATFORM_INTERRUPT_APIC_STRUCTURE;
//
@ -514,7 +514,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT64 LocalApicAddress;
} EFI_ACPI_6_2_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
@ -525,7 +525,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 IoApicId;
UINT8 Reserved;
UINT8 reserved;
UINT32 GlobalSystemInterruptBase;
UINT64 IoSapicAddress;
} EFI_ACPI_6_2_IO_SAPIC_STRUCTURE;
@ -540,7 +540,7 @@ typedef struct {
UINT8 AcpiProcessorId;
UINT8 LocalSapicId;
UINT8 LocalSapicEid;
UINT8 Reserved[3];
UINT8 reserved[3];
UINT32 Flags;
UINT32 ACPIProcessorUIDValue;
} EFI_ACPI_6_2_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
@ -572,7 +572,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[2];
UINT8 reserved[2];
UINT32 X2ApicId;
UINT32 Flags;
UINT32 AcpiProcessorUid;
@ -587,7 +587,7 @@ typedef struct {
UINT16 Flags;
UINT32 AcpiProcessorUid;
UINT8 LocalX2ApicLint;
UINT8 Reserved[3];
UINT8 reserved[3];
} EFI_ACPI_6_2_LOCAL_X2APIC_NMI_STRUCTURE;
///
@ -596,7 +596,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT32 CPUInterfaceNumber;
UINT32 AcpiProcessorUid;
UINT32 Flags;
@ -667,7 +667,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT64 DiscoveryRangeBaseAddress;
UINT32 DiscoveryRangeLength;
} EFI_ACPI_6_2_GICR_STRUCTURE;
@ -678,7 +678,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Reserved;
UINT16 reserved;
UINT32 GicItsId;
UINT64 PhysicalBaseAddress;
UINT32 Reserved2;
@ -824,7 +824,7 @@ typedef struct {
UINT8 Type;
UINT8 Length;
UINT32 ProximityDomain;
UINT8 Reserved[2];
UINT8 reserved[2];
UINT32 ItsId;
} EFI_ACPI_6_2_GIC_ITS_AFFINITY_STRUCTURE;
@ -847,7 +847,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT8 Reserved[8];
UINT8 reserved[8];
} EFI_ACPI_6_2_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER;
///
@ -967,7 +967,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT8 PlatformCommunicationChannelIdentifier;
UINT8 Reserved[3];
UINT8 reserved[3];
// Memory Power Node Structure
// Memory Power State Characteristics
} EFI_ACPI_6_2_MEMORY_POWER_STATUS_TABLE;
@ -1015,7 +1015,7 @@ typedef struct {
typedef struct {
UINT8 Flag;
UINT8 Reserved;
UINT8 reserved;
UINT16 MemoryPowerNodeId;
UINT32 Length;
UINT64 AddressBase;
@ -1032,7 +1032,7 @@ typedef struct {
typedef struct {
UINT16 MemoryPowerNodeCount;
UINT8 Reserved[2];
UINT8 reserved[2];
} EFI_ACPI_6_2_MPST_MEMORY_POWER_NODE_TABLE;
///
@ -1041,7 +1041,7 @@ typedef struct {
typedef struct {
UINT8 PowerStateStructureID;
UINT8 Flag;
UINT16 Reserved;
UINT16 reserved;
UINT32 AveragePowerConsumedInMPS0;
UINT32 RelativePowerSavingToMPS0;
UINT64 ExitLatencyToMPS0;
@ -1053,7 +1053,7 @@ typedef struct {
typedef struct {
UINT16 MemoryPowerStateCharacteristicsCount;
UINT8 Reserved[2];
UINT8 reserved[2];
} EFI_ACPI_6_2_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE;
///
@ -1061,7 +1061,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
} EFI_ACPI_6_2_MEMORY_TOPOLOGY_TABLE;
///
@ -1074,7 +1074,7 @@ typedef struct {
///
typedef struct {
UINT8 Type;
UINT8 Reserved;
UINT8 reserved;
UINT16 Length;
UINT16 Flags;
UINT16 Reserved1;
@ -1093,7 +1093,7 @@ typedef struct {
typedef struct {
EFI_ACPI_6_2_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header;
UINT16 SocketIdentifier;
UINT16 Reserved;
UINT16 reserved;
//EFI_ACPI_6_2_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE MemoryController[];
} EFI_ACPI_6_2_PMMT_SOCKET_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
@ -1108,7 +1108,7 @@ typedef struct {
UINT32 WriteBandwidth;
UINT16 OptimalAccessUnit;
UINT16 OptimalAccessAlignment;
UINT16 Reserved;
UINT16 reserved;
UINT16 NumberOfProximityDomains;
//UINT32 ProximityDomain[NumberOfProximityDomains];
//EFI_ACPI_6_2_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE PhysicalComponent[];
@ -1120,7 +1120,7 @@ typedef struct {
typedef struct {
EFI_ACPI_6_2_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE Header;
UINT16 PhysicalComponentIdentifier;
UINT16 Reserved;
UINT16 reserved;
UINT32 SizeOfDimm;
UINT32 SmbiosHandle;
} EFI_ACPI_6_2_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
@ -1239,7 +1239,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_6_2_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// 64-bit processor-relative physical address of the Basic Boot Performance Table.
///
@ -1251,7 +1251,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_6_2_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// 64-bit processor-relative physical address of the S3 Performance Table.
///
@ -1263,7 +1263,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_6_2_FPDT_PERFORMANCE_RECORD_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
///
/// Timer value logged at the beginning of firmware image execution.
/// This may not always be zero or near zero.
@ -1377,7 +1377,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT64 CntControlBasePhysicalAddress;
UINT32 Reserved;
UINT32 reserved;
UINT32 SecurePL1TimerGSIV;
UINT32 SecurePL1TimerFlags;
UINT32 NonSecurePL1TimerGSIV;
@ -1415,7 +1415,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT16 Length;
UINT8 Reserved;
UINT8 reserved;
UINT64 CntCtlBase;
UINT32 GTBlockTimerCount;
UINT32 GTBlockTimerOffset;
@ -1426,7 +1426,7 @@ typedef struct {
///
typedef struct {
UINT8 GTFrameNumber;
UINT8 Reserved[3];
UINT8 reserved[3];
UINT64 CntBaseX;
UINT64 CntEL0BaseX;
UINT32 GTxPhysicalTimerGSIV;
@ -1454,7 +1454,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT16 Length;
UINT8 Reserved;
UINT8 reserved;
UINT64 RefreshFramePhysicalAddress;
UINT64 WatchdogControlFramePhysicalAddress;
UINT32 WatchdogTimerGSIV;
@ -1473,7 +1473,7 @@ typedef struct {
//
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 Reserved;
UINT32 reserved;
} EFI_ACPI_6_2_NVDIMM_FIRMWARE_INTERFACE_TABLE;
//
@ -1726,7 +1726,7 @@ typedef struct {
UINT32 MultipleUncorrectableErrors:1;
UINT32 MultipleCorrectableErrors:1;
UINT32 ErrorDataEntryCount:10;
UINT32 Reserved:18;
UINT32 reserved:18;
} EFI_ACPI_6_2_ERROR_BLOCK_STATUS;
///
@ -1866,7 +1866,7 @@ typedef struct {
UINT16 SwitchToPollingThresholdWindow:1;
UINT16 ErrorThresholdValue:1;
UINT16 ErrorThresholdWindow:1;
UINT16 Reserved:10;
UINT16 reserved:10;
} EFI_ACPI_6_2_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE;
///
@ -2051,7 +2051,7 @@ typedef struct {
///
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT8 Reserved[4];
UINT8 reserved[4];
} EFI_ACPI_6_2_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER;
///
@ -2071,7 +2071,7 @@ typedef struct {
///
typedef struct {
UINT16 Type;
UINT8 Reserved[2];
UINT8 reserved[2];
UINT32 Length;
} EFI_ACPI_6_2_HMAT_STRUCTURE_HEADER;
@ -2082,7 +2082,7 @@ typedef struct {
UINT16 ProcessorProximityDomainValid:1;
UINT16 MemoryProximityDomainValid:1;
UINT16 ReservationHint:1;
UINT16 Reserved:13;
UINT16 reserved:13;
} EFI_ACPI_6_2_HMAT_STRUCTURE_MEMORY_SUBSYSTEM_ADDRESS_RANGE_FLAGS;
///
@ -2090,7 +2090,7 @@ typedef struct {
///
typedef struct {
UINT16 Type;
UINT8 Reserved[2];
UINT8 reserved[2];
UINT32 Length;
EFI_ACPI_6_2_HMAT_STRUCTURE_MEMORY_SUBSYSTEM_ADDRESS_RANGE_FLAGS Flags;
UINT8 Reserved1[2];
@ -2106,7 +2106,7 @@ typedef struct {
///
typedef struct {
UINT8 MemoryHierarchy:5;
UINT8 Reserved:3;
UINT8 reserved:3;
} EFI_ACPI_6_2_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO_FLAGS;
///
@ -2114,7 +2114,7 @@ typedef struct {
///
typedef struct {
UINT16 Type;
UINT8 Reserved[2];
UINT8 reserved[2];
UINT32 Length;
EFI_ACPI_6_2_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO_FLAGS Flags;
UINT8 DataType;
@ -2141,7 +2141,7 @@ typedef struct {
///
typedef struct {
UINT16 Type;
UINT8 Reserved[2];
UINT8 reserved[2];
UINT32 Length;
UINT32 MemoryProximityDomain;
UINT8 Reserved1[4];
@ -2332,7 +2332,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 Flags;
UINT64 Reserved;
UINT64 reserved;
} EFI_ACPI_6_2_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER;
///
@ -2368,7 +2368,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[6];
UINT8 reserved[6];
UINT64 BaseAddress;
UINT64 AddressLength;
EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE DoorbellRegister;
@ -2385,7 +2385,7 @@ typedef struct {
typedef struct {
UINT8 Command;
UINT8 Reserved:7;
UINT8 reserved:7;
UINT8 NotifyOnCompletion:1;
} EFI_ACPI_6_2_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND;
@ -2394,7 +2394,7 @@ typedef struct {
UINT8 PlatformInterrupt:1;
UINT8 Error:1;
UINT8 PlatformNotification:1;
UINT8 Reserved:4;
UINT8 reserved:4;
UINT8 Reserved1;
} EFI_ACPI_6_2_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS;
@ -2415,7 +2415,7 @@ typedef struct {
UINT8 Length;
UINT32 PlatformInterrupt;
UINT8 PlatformInterruptFlags;
UINT8 Reserved;
UINT8 reserved;
UINT64 BaseAddress;
UINT64 AddressLength;
EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE DoorbellRegister;
@ -2434,7 +2434,7 @@ typedef struct {
UINT8 Length;
UINT32 PlatformInterrupt;
UINT8 PlatformInterruptFlags;
UINT8 Reserved;
UINT8 reserved;
UINT64 BaseAddress;
UINT64 AddressLength;
EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE DoorbellRegister;
@ -2456,7 +2456,7 @@ typedef struct {
UINT8 Length;
UINT32 PlatformInterrupt;
UINT8 PlatformInterruptFlags;
UINT8 Reserved;
UINT8 reserved;
UINT64 BaseAddress;
UINT32 AddressLength;
EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE DoorbellRegister;
@ -2498,7 +2498,7 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT8 TriggerCount;
UINT8 Reserved[3];
UINT8 reserved[3];
UINT32 TriggerIdentifierArrayOffset;
} EFI_ACPI_6_2_PLATFORM_DEBUG_TRIGGER_TABLE_HEADER;
@ -2514,7 +2514,7 @@ typedef struct {
UINT16 SubChannelIdentifer:8;
UINT16 Runtime:1;
UINT16 WaitForCompletion:1;
UINT16 Reserved:6;
UINT16 reserved:6;
} EFI_ACPI_6_2_PDTT_PCC_IDENTIFIER;
///
@ -2553,7 +2553,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[2];
UINT8 reserved[2];
} EFI_ACPI_6_2_PPTT_STRUCTURE_HEADER;
///
@ -2568,7 +2568,7 @@ typedef struct {
typedef struct {
UINT32 PhysicalPackage:1;
UINT32 AcpiProcessorIdValid:1;
UINT32 Reserved:30;
UINT32 reserved:30;
} EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR_FLAGS;
///
@ -2577,7 +2577,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[2];
UINT8 reserved[2];
EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR_FLAGS Flags;
UINT32 Parent;
UINT32 AcpiProcessorId;
@ -2595,7 +2595,7 @@ typedef struct {
UINT32 CacheTypeValid:1;
UINT32 WritePolicyValid:1;
UINT32 LineSizeValid:1;
UINT32 Reserved:25;
UINT32 reserved:25;
} EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_FLAGS;
///
@ -2617,7 +2617,7 @@ typedef struct {
UINT8 AllocationType:2;
UINT8 CacheType:2;
UINT8 WritePolicy:1;
UINT8 Reserved:3;
UINT8 reserved:3;
} EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES;
///
@ -2626,7 +2626,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[2];
UINT8 reserved[2];
EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_FLAGS Flags;
UINT32 NextLevelOfCache;
UINT32 Size;
@ -2642,7 +2642,7 @@ typedef struct {
typedef struct {
UINT8 Type;
UINT8 Length;
UINT8 Reserved[2];
UINT8 reserved[2];
UINT32 VendorId;
UINT64 Level1Id;
UINT64 Level2Id;

@ -709,7 +709,7 @@ typedef struct {
UINT32 OffsetToData;
UINT32 Size;
UINT32 CodePage;
UINT32 Reserved;
UINT32 reserved;
} EFI_IMAGE_RESOURCE_DATA_ENTRY;
///

@ -357,7 +357,7 @@ typedef struct {
///
/// Reserved for the future.
///
UINT32 Reserved;
UINT32 reserved;
///
/// Fibre Channel World Wide Number.
///
@ -377,7 +377,7 @@ typedef struct {
///
/// Reserved for the future.
///
UINT32 Reserved;
UINT32 reserved;
///
/// 8 byte array containing Fibre Channel End Device Port Name.
///
@ -397,7 +397,7 @@ typedef struct {
///
/// Reserved for the future.
///
UINT32 Reserved;
UINT32 reserved;
///
/// 1394 Global Unique ID (GUID).
///
@ -687,7 +687,7 @@ typedef struct {
///
/// Reserved.
///
UINT32 Reserved;
UINT32 reserved;
///
/// The baud rate setting for the UART style device. A value of 0
/// means that the device's default baud rate will be used.
@ -764,7 +764,7 @@ typedef struct {
///
/// Reserved for future use.
///
UINT32 Reserved;
UINT32 reserved;
///
/// SAS Address for Serial Attached SCSI Target.
///
@ -1126,7 +1126,7 @@ typedef struct {
///
typedef struct {
EFI_DEVICE_PATH_PROTOCOL Header;
UINT32 Reserved;
UINT32 reserved;
UINT64 StartingOffset;
UINT64 EndingOffset;
} MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH;

@ -138,7 +138,7 @@ typedef struct {
UINT8 Blue;
UINT8 Green;
UINT8 Red;
UINT8 Reserved;
UINT8 reserved;
} EFI_GRAPHICS_OUTPUT_BLT_PIXEL;
typedef union {

@ -59,7 +59,7 @@ typedef struct {
EFI_HANDLE DeviceHandle; ///< The device handle that the EFI Image was loaded from.
EFI_DEVICE_PATH_PROTOCOL *FilePath; ///< A pointer to the file path portion specific to DeviceHandle
///< that the EFI Image was loaded from.
VOID *Reserved; ///< Reserved. DO NOT USE.
VOID *reserved; ///< Reserved. DO NOT USE.
//
// Images load options

@ -174,7 +174,7 @@ typedef struct {
///
/// Reserved field that must be set to 0.
///
UINT32 Reserved;
UINT32 reserved;
} EFI_TABLE_HEADER;
///

@ -1885,7 +1885,7 @@ typedef struct {
EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface;
EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface;
EFI_HANDLE_PROTOCOL HandleProtocol;
VOID *Reserved;
VOID *reserved;
EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify;
EFI_LOCATE_HANDLE LocateHandle;
EFI_LOCATE_DEVICE_PATH LocateDevicePath;
@ -2139,7 +2139,7 @@ typedef union {
/// The SysReq key must be pressed (1) or must not be pressed (0).
///
UINT32 SysReqPressed : 1;
UINT32 Reserved : 16;
UINT32 reserved : 16;
///
/// Specifies the actual number of entries in EFI_KEY_OPTION.Keys, from 0-3. If
/// zero, then only the shift state is considered. If more than one, then the boot option will

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{1770c4fb-345f-40dd-b4a2-2a5dc8a50866}</ProjectGuid>
<RootNamespace>example</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</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)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libvoyager.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="vdm_ctx\vdm_ctx.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="libvoyager.hpp" />
<ClInclude Include="util\nt.hpp" />
<ClInclude Include="util\util.hpp" />
<ClInclude Include="vdm_ctx\vdm_ctx.hpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -0,0 +1,38 @@
<?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>
<Filter Include="Header Files\util">
<UniqueIdentifier>{a575c9e1-1d0c-410a-8456-2743e2f93f86}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="vdm_ctx\vdm_ctx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="libvoyager.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="util\nt.hpp">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="util\util.hpp">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="vdm_ctx\vdm_ctx.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

@ -0,0 +1,151 @@
#pragma once
#include <intrin.h>
#include <type_traits>
#define VMEXIT_KEY 0xDEADBEEFDEADBEEF
#define PAGE_4KB 0x1000
#define PAGE_2MB PAGE_4KB * 512
#define PAGE_1GB PAGE_2MB * 512
using u8 = unsigned char;
using u16 = unsigned short;
using u32 = unsigned int;
using u64 = unsigned long long;
namespace voyager
{
// code comments itself...
using guest_virt_t = u64;
using guest_phys_t = u64;
using host_virt_t = u64;
using host_phys_t = u64;
enum class vmexit_command_t
{
init_page_tables,
read_guest_phys,
write_guest_phys,
copy_guest_virt,
get_dirbase,
translate
};
enum class vmxroot_error_t
{
error_success,
pml4e_not_present,
pdpte_not_present,
pde_not_present,
pte_not_present,
vmxroot_translate_failure,
invalid_self_ref_pml4e,
invalid_mapping_pml4e,
invalid_host_virtual,
invalid_guest_physical,
invalid_guest_virtual,
page_table_init_failed
};
typedef union _command_t
{
struct _copy_phys
{
host_phys_t phys_addr;
guest_virt_t buffer;
u64 size;
} copy_phys;
struct _copy_virt
{
guest_phys_t dirbase_src;
guest_virt_t virt_src;
guest_phys_t dirbase_dest;
guest_virt_t virt_dest;
u64 size;
} copy_virt;
struct _translate_virt
{
guest_virt_t virt_src;
guest_phys_t phys_addr;
} translate_virt;
guest_phys_t dirbase;
} command_t, * pcommand_t;
/// <summary>
/// this function is used to cause a vmexit as though its calling a function...
/// </summary>
extern "C" auto hypercall(u64 key, vmexit_command_t, pcommand_t command)->vmxroot_error_t;
/// <summary>
/// gets the current cores CR3 value (current address space pml4)...
/// </summary>
/// <returns>returns the guest cr3 value...</returns>
auto current_dirbase()->guest_phys_t;
/// <summary>
/// initalizies page tables for all cores...
/// </summary>
/// <returns>status of the initalization...</returns>
auto init()->vmxroot_error_t;
/// <summary>
/// translate a linear virtual address of the current address space
/// to a linear physical address...
/// </summary>
/// <param name="virt_addr">virtual address in the vmexiting core's address space...</param>
/// <returns>guest physical address...</returns>
auto translate(guest_virt_t virt_addr)->guest_phys_t;
/// <summary>
/// reads guest physical memory...
/// </summary>
/// <param name="phys_addr">physical address to read...</param>
/// <param name="buffer">buffer (guest virtual address) to read into...</param>
/// <param name="size">number of bytes to read (can only be 0x1000 or less)...</param>
/// <returns>STATUS_SUCCESS if the read was successful...</returns>
auto read_phys(guest_phys_t phys_addr, guest_virt_t buffer, u64 size)->vmxroot_error_t;
/// <summary>
/// write guest physical memory...
/// </summary>
/// <param name="phys_addr">physical address to read</param>
/// <param name="buffer">guest virtual address to write from...</param>
/// <param name="size">number of bytes to write</param>
/// <returns></returns>
auto write_phys(guest_phys_t phys_addr, guest_virt_t buffer, u64 size)->vmxroot_error_t;
/// <summary>
/// copy guest virtual memory between virtual address spaces...
/// </summary>
/// <param name="dirbase_src">dirbase of the source address space</param>
/// <param name="virt_src">virtual address in the source address space</param>
/// <param name="dirbase_dest">dirbase of the destination address space</param>
/// <param name="virt_dest">virtual address of the destination address</param>
/// <param name="size">size to copy between address spaces</param>
/// <returns>returns error_success on successful copy and invalid_guest_virt when an address is invalid...</returns>
auto copy_virt(guest_phys_t dirbase_src, guest_virt_t virt_src, guest_phys_t dirbase_dest,
guest_virt_t virt_dest, u64 size)->vmxroot_error_t;
template <class T>
auto rpm(guest_phys_t dirbase, guest_virt_t virt_addr) -> T
{
T buffer;
auto result = copy_virt(dirbase, virt_addr,
current_dirbase(), (guest_virt_t)&buffer, sizeof T);
if (result != vmxroot_error_t::error_success)
return {};
return buffer;
}
template <class T>
auto wpm(guest_phys_t dirbase, guest_virt_t virt_addr, const T& data) -> void
{
copy_virt(dirbase, (guest_virt_t)&data,
dirbase, virt_addr, sizeof T);
}
}

Binary file not shown.

@ -0,0 +1,81 @@
#include <iostream>
#include "libvoyager.hpp"
#include "util/util.hpp"
#include "vdm_ctx/vdm_ctx.hpp"
int __cdecl main(int argc, char** argv)
{
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;
};
std::printf("[+] voyager init result -> 0x%x (0x0 == success)\n", voyager::init());
std::printf("[+] current dirbase -> 0x%p\n", voyager::current_dirbase());
std::printf("[+] please wait... this may take up to 30 seconds...\n");
const auto nt_shutdown_system =
util::get_kmodule_export(
"ntoskrnl.exe", vdm::syscall_hook.first);
const auto nt_shutdown_phys =
voyager::translate(reinterpret_cast<
voyager::guest_virt_t>(nt_shutdown_system));
std::printf("NtShutdownSystem -> 0x%p\n", nt_shutdown_system);
std::printf("NtShutdownSystem (phys) -> 0x%p\n", nt_shutdown_phys);
vdm::syscall_address.store(reinterpret_cast<void*>(nt_shutdown_phys));
vdm::vdm_ctx vdm(_read_phys, _write_phys);
const auto ntoskrnl_base =
reinterpret_cast<void*>(
util::get_kmodule_base("ntoskrnl.exe"));
const auto ntoskrnl_memcpy =
util::get_kmodule_export("ntoskrnl.exe", "memcpy");
std::printf("[+] %s physical address -> 0x%p\n", vdm::syscall_hook.first, vdm::syscall_address.load());
std::printf("[+] %s page offset -> 0x%x\n", vdm::syscall_hook.first, vdm::nt_page_offset);
std::printf("[+] ntoskrnl base address -> 0x%p\n", ntoskrnl_base);
std::printf("[+] ntoskrnl memcpy address -> 0x%p\n", ntoskrnl_memcpy);
short mz_bytes = 0;
vdm.syscall<decltype(&memcpy)>(
ntoskrnl_memcpy,
&mz_bytes,
ntoskrnl_base,
sizeof mz_bytes
);
std::printf("[+] ntoskrnl MZ -> 0x%x\n", mz_bytes);
const auto explorer_dirbase =
vdm.get_dirbase(util::get_pid("explorer.exe"));
const auto ntdll_base =
reinterpret_cast<std::uintptr_t>(
GetModuleHandleA("ntdll.dll"));
std::printf("explorer.exe dirbase -> 0x%p\n", explorer_dirbase);
std::printf("current process dirbase -> %p\n", voyager::current_dirbase());
std::printf("ntdll.dll base -> 0x%p\n", ntdll_base);
std::printf("ntdll.dll MZ in explorer.exe -> 0x%x\n",
voyager::rpm<short>(explorer_dirbase, ntdll_base));
std::printf("[+] press any key to close...\n");
std::getchar();
}

@ -0,0 +1,89 @@
#pragma once
#include <Windows.h>
#include <winternl.h>
#pragma comment(lib, "ntdll.lib")
#define PAGE_4KB 0x1000
constexpr auto SystemModuleInformation = 11;
typedef struct _RTL_PROCESS_MODULE_INFORMATION
{
HANDLE Section;
PVOID MappedBase;
PVOID ImageBase;
ULONG ImageSize;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT OffsetToFileName;
UCHAR FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION;
typedef struct _RTL_PROCESS_MODULES
{
ULONG NumberOfModules;
RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES;
typedef LARGE_INTEGER PHYSICAL_ADDRESS, * PPHYSICAL_ADDRESS;
using PEPROCESS = PVOID;
using PsLookupProcessByProcessId = NTSTATUS(__fastcall*)(
HANDLE ProcessId,
PEPROCESS* Process
);
typedef union
{
std::uint64_t flags;
struct
{
std::uint64_t reserved1 : 3;
/**
* @brief Page-level Write-Through
*
* [Bit 3] Controls the memory type used to access the first paging structure of the current paging-structure hierarchy.
* This bit is not used if paging is disabled, with PAE paging, or with 4-level paging if CR4.PCIDE=1.
*
* @see Vol3A[4.9(PAGING AND MEMORY TYPING)]
*/
std::uint64_t page_level_write_through : 1;
#define CR3_PAGE_LEVEL_WRITE_THROUGH_BIT 3
#define CR3_PAGE_LEVEL_WRITE_THROUGH_FLAG 0x08
#define CR3_PAGE_LEVEL_WRITE_THROUGH_MASK 0x01
#define CR3_PAGE_LEVEL_WRITE_THROUGH(_) (((_) >> 3) & 0x01)
/**
* @brief Page-level Cache Disable
*
* [Bit 4] Controls the memory type used to access the first paging structure of the current paging-structure hierarchy.
* This bit is not used if paging is disabled, with PAE paging, or with 4-level paging2 if CR4.PCIDE=1.
*
* @see Vol3A[4.9(PAGING AND MEMORY TYPING)]
*/
std::uint64_t page_level_cache_disable : 1;
#define CR3_PAGE_LEVEL_CACHE_DISABLE_BIT 4
#define CR3_PAGE_LEVEL_CACHE_DISABLE_FLAG 0x10
#define CR3_PAGE_LEVEL_CACHE_DISABLE_MASK 0x01
#define CR3_PAGE_LEVEL_CACHE_DISABLE(_) (((_) >> 4) & 0x01)
std::uint64_t reserved2 : 7;
/**
* @brief Address of page directory
*
* [Bits 47:12] Physical address of the 4-KByte aligned page directory (32-bit paging) or PML4 table (64-bit paging) used
* for linear-address translation.
*
* @see Vol3A[4.3(32-BIT PAGING)]
* @see Vol3A[4.5(4-LEVEL PAGING)]
*/
std::uint64_t pml4_pfn : 36;
#define CR3_ADDRESS_OF_PAGE_DIRECTORY_BIT 12
#define CR3_ADDRESS_OF_PAGE_DIRECTORY_FLAG 0xFFFFFFFFF000
#define CR3_ADDRESS_OF_PAGE_DIRECTORY_MASK 0xFFFFFFFFF
#define CR3_ADDRESS_OF_PAGE_DIRECTORY(_) (((_) >> 12) & 0xFFFFFFFFF)
std::uint64_t reserved3 : 16;
};
} cr3;

@ -0,0 +1,264 @@
#pragma once
#include <Windows.h>
#include <ntstatus.h>
#include <cstdint>
#include <string_view>
#include <algorithm>
#include <string_view>
#include <tlhelp32.h>
#include <map>
#include "nt.hpp"
namespace util
{
inline std::map<std::uintptr_t, std::size_t> pmem_ranges{};
__forceinline auto is_valid(std::uintptr_t addr) -> bool
{
for (auto range : pmem_ranges)
if (addr >= range.first && addr <= range.first + range.second)
return true;
return false;
}
#pragma pack (push, 1)
struct PhysicalMemoryPage//CM_PARTIAL_RESOURCE_DESCRIPTOR
{
uint8_t type;
uint8_t shareDisposition;
uint16_t flags;
uint64_t pBegin;
uint32_t sizeButNotExactly;
uint32_t pad;
static constexpr uint16_t cm_resource_memory_large_40{ 0x200 };
static constexpr uint16_t cm_resource_memory_large_48{ 0x400 };
static constexpr uint16_t cm_resource_memory_large_64{ 0x800 };
uint64_t size()const noexcept
{
if (flags & cm_resource_memory_large_40)
return uint64_t{ sizeButNotExactly } << 8;
else if (flags & cm_resource_memory_large_48)
return uint64_t{ sizeButNotExactly } << 16;
else if (flags & cm_resource_memory_large_64)
return uint64_t{ sizeButNotExactly } << 32;
else
return uint64_t{ sizeButNotExactly };
}
};
static_assert(sizeof(PhysicalMemoryPage) == 20);
#pragma pack (pop)
inline const auto init_ranges = ([&]() -> bool
{
HKEY h_key;
DWORD type, size;
LPBYTE data;
RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\RESOURCEMAP\\System Resources\\Physical Memory", 0, KEY_READ, &h_key);
RegQueryValueEx(h_key, ".Translated", NULL, &type, NULL, &size); //get size
data = new BYTE[size];
RegQueryValueEx(h_key, ".Translated", NULL, &type, data, &size);
DWORD count = *(DWORD*)(data + 16);
auto pmi = data + 24;
for (int dwIndex = 0; dwIndex < count; dwIndex++)
{
#if 0
pmem_ranges.emplace(*(uint64_t*)(pmi + 0), *(uint64_t*)(pmi + 8));
#else
const PhysicalMemoryPage& page{ *(PhysicalMemoryPage*)(pmi - 4) };
pmem_ranges.emplace(page.pBegin, page.size());
#endif
pmi += 20;
}
delete[] data;
RegCloseKey(h_key);
return true;
})();
__forceinline auto get_file_header(void* base_addr) -> PIMAGE_FILE_HEADER
{
PIMAGE_DOS_HEADER dos_headers =
reinterpret_cast<PIMAGE_DOS_HEADER>(base_addr);
PIMAGE_NT_HEADERS nt_headers =
reinterpret_cast<PIMAGE_NT_HEADERS>(
reinterpret_cast<DWORD_PTR>(base_addr) + dos_headers->e_lfanew);
return &nt_headers->FileHeader;
}
__forceinline auto get_kmodule_base(const char* module_name) -> std::uintptr_t
{
void* buffer = nullptr;
DWORD buffer_size = NULL;
auto status = NtQuerySystemInformation(
static_cast<SYSTEM_INFORMATION_CLASS>(SystemModuleInformation),
buffer, buffer_size, &buffer_size);
while (status == STATUS_INFO_LENGTH_MISMATCH)
{
VirtualFree(buffer, NULL, MEM_RELEASE);
buffer = VirtualAlloc(nullptr, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
status = NtQuerySystemInformation(
static_cast<SYSTEM_INFORMATION_CLASS>(SystemModuleInformation),
buffer, buffer_size, &buffer_size);
}
if (!NT_SUCCESS(status))
{
VirtualFree(buffer, NULL, MEM_RELEASE);
return NULL;
}
const auto modules = static_cast<PRTL_PROCESS_MODULES>(buffer);
for (auto idx = 0u; idx < modules->NumberOfModules; ++idx)
{
const std::string current_module_name = std::string(reinterpret_cast<char*>(modules->Modules[idx].FullPathName) + modules->Modules[idx].OffsetToFileName);
if (!_stricmp(current_module_name.c_str(), module_name))
{
const uint64_t result = reinterpret_cast<uint64_t>(modules->Modules[idx].ImageBase);
VirtualFree(buffer, NULL, MEM_RELEASE);
return result;
}
}
VirtualFree(buffer, NULL, MEM_RELEASE);
return NULL;
}
__forceinline auto get_kmodule_export(const char* module_name, const char* export_name, bool rva = false) -> void*
{
void* buffer = nullptr;
DWORD buffer_size = NULL;
NTSTATUS status = NtQuerySystemInformation(
static_cast<SYSTEM_INFORMATION_CLASS>(SystemModuleInformation),
buffer,
buffer_size,
&buffer_size
);
while (status == STATUS_INFO_LENGTH_MISMATCH)
{
VirtualFree(buffer, 0, MEM_RELEASE);
buffer = VirtualAlloc(nullptr, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
status = NtQuerySystemInformation(
static_cast<SYSTEM_INFORMATION_CLASS>(SystemModuleInformation),
buffer,
buffer_size,
&buffer_size
);
}
if (!NT_SUCCESS(status))
{
VirtualFree(buffer, 0, MEM_RELEASE);
return nullptr;
}
const auto modules = static_cast<PRTL_PROCESS_MODULES>(buffer);
for (auto idx = 0u; idx < modules->NumberOfModules; ++idx)
{
// find module and then load library it
const std::string current_module_name =
std::string(reinterpret_cast<char*>(
modules->Modules[idx].FullPathName) +
modules->Modules[idx].OffsetToFileName
);
if (!_stricmp(current_module_name.c_str(), module_name))
{
std::string full_path = reinterpret_cast<char*>(modules->Modules[idx].FullPathName);
full_path.replace(full_path.find("\\SystemRoot\\"),
sizeof("\\SystemRoot\\") - 1, std::string(getenv("SYSTEMROOT")).append("\\"));
const auto module_base =
LoadLibraryEx(
full_path.c_str(),
NULL,
DONT_RESOLVE_DLL_REFERENCES
);
PIMAGE_DOS_HEADER p_idh;
PIMAGE_NT_HEADERS p_inh;
PIMAGE_EXPORT_DIRECTORY p_ied;
PDWORD addr, name;
PWORD ordinal;
p_idh = (PIMAGE_DOS_HEADER)module_base;
if (p_idh->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
p_inh = (PIMAGE_NT_HEADERS)((LPBYTE)module_base + p_idh->e_lfanew);
if (p_inh->Signature != IMAGE_NT_SIGNATURE)
return NULL;
if (p_inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == 0)
return NULL;
p_ied = (PIMAGE_EXPORT_DIRECTORY)((LPBYTE)module_base +
p_inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
addr = (PDWORD)((LPBYTE)module_base + p_ied->AddressOfFunctions);
name = (PDWORD)((LPBYTE)module_base + p_ied->AddressOfNames);
ordinal = (PWORD)((LPBYTE)module_base + p_ied->AddressOfNameOrdinals);
// find exported function
for (auto i = 0; i < p_ied->AddressOfFunctions; i++)
{
if (!strcmp(export_name, (char*)module_base + name[i]))
{
if (!rva)
{
auto result = (void*)((std::uintptr_t)modules->Modules[idx].ImageBase + addr[ordinal[i]]);
VirtualFree(buffer, NULL, MEM_RELEASE);
return result;
}
else
{
auto result = (void*)addr[ordinal[i]];
VirtualFree(buffer, NULL, MEM_RELEASE);
return result;
}
}
}
}
}
VirtualFree(buffer, NULL, MEM_RELEASE);
return nullptr;
}
__forceinline auto get_pid(const char* proc_name) -> std::uint32_t
{
PROCESSENTRY32 proc_info;
proc_info.dwSize = sizeof(proc_info);
HANDLE proc_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (proc_snapshot == INVALID_HANDLE_VALUE)
return NULL;
Process32First(proc_snapshot, &proc_info);
if (!strcmp(proc_info.szExeFile, proc_name))
{
CloseHandle(proc_snapshot);
return proc_info.th32ProcessID;
}
while (Process32Next(proc_snapshot, &proc_info))
{
if (!strcmp(proc_info.szExeFile, proc_name))
{
CloseHandle(proc_snapshot);
return proc_info.th32ProcessID;
}
}
CloseHandle(proc_snapshot);
return NULL;
}
}

@ -0,0 +1,124 @@
#include "vdm_ctx.hpp"
namespace vdm
{
vdm_ctx::vdm_ctx(read_phys_t& read_func, write_phys_t& write_func)
:
read_phys(read_func),
write_phys(write_func)
{
// already found the syscall's physical page...
if (vdm::syscall_address.load())
return;
vdm::ntoskrnl = reinterpret_cast<std::uint8_t*>(
LoadLibraryExA("ntoskrnl.exe", NULL,
DONT_RESOLVE_DLL_REFERENCES));
nt_rva = reinterpret_cast<std::uint32_t>(
util::get_kmodule_export(
"ntoskrnl.exe",
syscall_hook.first,
true
));
vdm::nt_page_offset = nt_rva % PAGE_4KB;
std::vector<std::thread> search_threads;
for (auto ranges : util::pmem_ranges)
search_threads.emplace_back(std::thread(
&vdm_ctx::locate_syscall,
this,
ranges.first,
ranges.second
));
for (std::thread& search_thread : search_threads)
search_thread.join();
}
void vdm_ctx::set_read(read_phys_t& read_func)
{
this->read_phys = read_func;
}
void vdm_ctx::set_write(write_phys_t& write_func)
{
this->write_phys = write_func;
}
void vdm_ctx::rkm(void* dst, void* src, std::size_t size)
{
static const auto ntoskrnl_memcpy =
util::get_kmodule_export("ntoskrnl.exe", "memcpy");
this->syscall<decltype(&memcpy)>(
ntoskrnl_memcpy, dst, src, size);
}
void vdm_ctx::wkm(void* dst, void* src, std::size_t size)
{
static const auto ntoskrnl_memcpy =
util::get_kmodule_export("ntoskrnl.exe", "memcpy");
this->syscall<decltype(&memcpy)>(
ntoskrnl_memcpy, dst, src, size);
}
void vdm_ctx::locate_syscall(std::uintptr_t address, std::uintptr_t length) const
{
const auto page_data =
reinterpret_cast<std::uint8_t*>(
VirtualAlloc(
nullptr,
PAGE_4KB, MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE
));
// accesses the page in order to make PTE...
memset(page_data, NULL, PAGE_4KB);
for (auto page = 0u; page < length; page += PAGE_4KB)
{
if (vdm::syscall_address.load())
break;
if (!read_phys(reinterpret_cast<void*>(address + page), page_data, PAGE_4KB))
continue;
// check the first 32 bytes of the syscall, if its the same, test that its the correct
// occurrence of these bytes (since dxgkrnl is loaded into physical memory at least 2 times now)...
if (!memcmp(page_data + nt_page_offset, ntoskrnl + nt_rva, 32))
if (valid_syscall(reinterpret_cast<void*>(address + page + nt_page_offset)))
syscall_address.store(
reinterpret_cast<void*>(
address + page + nt_page_offset));
}
VirtualFree(page_data, PAGE_4KB, MEM_DECOMMIT);
}
bool vdm_ctx::valid_syscall(void* syscall_addr) const
{
static std::mutex syscall_mutex;
syscall_mutex.lock();
static const auto proc =
GetProcAddress(
LoadLibraryA(syscall_hook.second),
syscall_hook.first
);
// 0: 48 31 c0 xor rax, rax
// 3 : c3 ret
std::uint8_t shellcode[] = { 0x48, 0x31, 0xC0, 0xC3 };
std::uint8_t orig_bytes[sizeof shellcode];
// save original bytes and install shellcode...
read_phys(syscall_addr, orig_bytes, sizeof orig_bytes);
write_phys(syscall_addr, shellcode, sizeof shellcode);
auto result = reinterpret_cast<NTSTATUS(__fastcall*)(void)>(proc)();
write_phys(syscall_addr, orig_bytes, sizeof orig_bytes);
syscall_mutex.unlock();
return result == STATUS_SUCCESS;
}
}

@ -0,0 +1,125 @@
#pragma once
#include <windows.h>
#include <string_view>
#include <vector>
#include <thread>
#include <atomic>
#include <mutex>
#include <functional>
#include "../util/util.hpp"
namespace vdm
{
// change this to whatever you want :^)
constexpr std::pair<const char*, const char*> syscall_hook = { "NtShutdownSystem", "ntdll.dll" };
inline std::atomic<bool> is_page_found = false;
inline std::atomic<void*> syscall_address = nullptr;
inline std::uint16_t nt_page_offset;
inline std::uint32_t nt_rva;
inline std::uint8_t* ntoskrnl;
using read_phys_t = std::function<bool(void*, void*, std::size_t)>;
using write_phys_t = std::function<bool(void*, void*, std::size_t)>;
class vdm_ctx
{
public:
explicit vdm_ctx(read_phys_t& read_func, write_phys_t& write_func);
void set_read(read_phys_t& read_func);
void set_write(write_phys_t& write_func);
void rkm(void* dst, void* src, std::size_t size);
void wkm(void* dst, void* src, std::size_t size);
template <class T, class ... Ts>
__forceinline std::invoke_result_t<T, Ts...> syscall(void* addr, Ts ... args) const
{
static const auto proc =
GetProcAddress(
LoadLibraryA(syscall_hook.second),
syscall_hook.first
);
static std::mutex syscall_mutex;
syscall_mutex.lock();
// jmp [rip+0x0]
std::uint8_t jmp_code[] =
{
0xff, 0x25, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00
};
std::uint8_t orig_bytes[sizeof jmp_code];
*reinterpret_cast<void**>(jmp_code + 6) = addr;
read_phys(vdm::syscall_address.load(), orig_bytes, sizeof orig_bytes);
// execute hook...
write_phys(vdm::syscall_address.load(), jmp_code, sizeof jmp_code);
auto result = reinterpret_cast<T>(proc)(args ...);
write_phys(vdm::syscall_address.load(), orig_bytes, sizeof orig_bytes);
syscall_mutex.unlock();
return result;
}
template <class T>
__forceinline auto rkm(std::uintptr_t addr) -> T
{
T buffer;
rkm((void*)&buffer, (void*)addr, sizeof T);
return buffer;
}
template <class T>
__forceinline void wkm(std::uintptr_t addr, const T& value)
{
wkm((void*)addr, (void*)&value, sizeof T);
}
__forceinline auto get_peprocess(std::uint32_t pid) -> PEPROCESS
{
static const auto ps_lookup_peproc =
util::get_kmodule_export(
"ntoskrnl.exe",
"PsLookupProcessByProcessId");
PEPROCESS peproc = nullptr;
this->syscall<PsLookupProcessByProcessId>(
ps_lookup_peproc,
(HANDLE)pid,
&peproc
);
return peproc;
}
__forceinline auto get_dirbase(std::uint32_t pid) -> std::uintptr_t
{
const auto peproc = get_peprocess(pid);
if (!peproc)
return {};
return rkm<cr3>(
reinterpret_cast<std::uintptr_t>(peproc) + 0x28).pml4_pfn << 12;
}
__forceinline auto get_peb(std::uint32_t pid) -> PPEB
{
static const auto get_peb =
util::get_kmodule_export(
"ntoskrnl.exe", "PsGetProcessPeb");
return this->syscall<PPEB(*)(PEPROCESS)>(
get_peb, get_peprocess(pid));
}
private:
void locate_syscall(std::uintptr_t begin, std::uintptr_t end) const;
bool valid_syscall(void* syscall_addr) const;
read_phys_t read_phys;
write_phys_t write_phys;
};
}

@ -0,0 +1,81 @@
#include "libvoyager.hpp"
#include <Windows.h>
#include <iostream>
// taken from hvpp (wbenny). this code runs specific code on each logical processor...
// this is required since hyper-v has its own PML4 for each core...
// https://github.com/wbenny/hvpp/blob/master/src/hvppctrl/lib/mp.cpp#L4
auto voyager::init() -> vmxroot_error_t
{
GROUP_AFFINITY orig_group_affinity;
GetThreadGroupAffinity(GetCurrentThread(), &orig_group_affinity);
const auto group_count = GetActiveProcessorGroupCount();
// each core we are going to vmexit on and ask the payload
// to setup the mapping pml4e. for some reason each core on
// hyper-v has its own pml4... Not sure why? just is...
for (auto group_number = 0u; group_number < group_count; ++group_number)
{
const auto processor_count = GetActiveProcessorCount(group_number);
for (auto processor_number = 0u; processor_number < processor_count; ++processor_number)
{
GROUP_AFFINITY group_affinity = { 0 };
group_affinity.Mask = (KAFFINITY)(1) << processor_number;
group_affinity.Group = group_number;
SetThreadGroupAffinity(GetCurrentThread(), &group_affinity, NULL);
auto result = hypercall(VMEXIT_KEY, vmexit_command_t::init_page_tables, nullptr);
if (result != vmxroot_error_t::error_success)
return result;
}
}
SetThreadGroupAffinity(GetCurrentThread(), &orig_group_affinity, NULL);
return vmxroot_error_t::error_success;
}
auto voyager::current_dirbase()->guest_phys_t
{
command_t command;
auto result = hypercall(VMEXIT_KEY, vmexit_command_t::get_dirbase, &command);
if (result != vmxroot_error_t::error_success)
return {};
return command.dirbase;
}
auto voyager::translate(guest_virt_t virt_addr) -> guest_phys_t
{
command_t command;
command.translate_virt.virt_src = virt_addr;
const auto result = hypercall(VMEXIT_KEY, vmexit_command_t::translate, &command);
if (result != vmxroot_error_t::error_success)
return {};
return command.translate_virt.phys_addr;
}
auto voyager::read_phys(guest_phys_t phys_addr, guest_virt_t buffer, u64 size) -> vmxroot_error_t
{
command_t command;
command.copy_phys = { phys_addr, buffer, size };
return hypercall(VMEXIT_KEY, vmexit_command_t::read_guest_phys, &command);
}
auto voyager::write_phys(guest_phys_t phys_addr, guest_virt_t buffer, u64 size) -> vmxroot_error_t
{
command_t command;
command.copy_phys = { phys_addr, buffer, size };
return hypercall(VMEXIT_KEY, vmexit_command_t::write_guest_phys, &command);
}
auto voyager::copy_virt(guest_phys_t dirbase_src, guest_virt_t virt_src, guest_phys_t dirbase_dest,
guest_virt_t virt_dest, u64 size) -> vmxroot_error_t
{
command_t command;
command.copy_virt = { dirbase_src, virt_src, dirbase_dest, virt_dest, size };
return hypercall(VMEXIT_KEY, vmexit_command_t::copy_guest_virt, &command);
}

@ -0,0 +1,151 @@
#pragma once
#include <intrin.h>
#include <type_traits>
#define VMEXIT_KEY 0xDEADBEEFDEADBEEF
#define PAGE_4KB 0x1000
#define PAGE_2MB PAGE_4KB * 512
#define PAGE_1GB PAGE_2MB * 512
using u8 = unsigned char;
using u16 = unsigned short;
using u32 = unsigned int;
using u64 = unsigned long long;
namespace voyager
{
// code comments itself...
using guest_virt_t = u64;
using guest_phys_t = u64;
using host_virt_t = u64;
using host_phys_t = u64;
enum class vmexit_command_t
{
init_page_tables,
read_guest_phys,
write_guest_phys,
copy_guest_virt,
get_dirbase,
translate
};
enum class vmxroot_error_t
{
error_success,
pml4e_not_present,
pdpte_not_present,
pde_not_present,
pte_not_present,
vmxroot_translate_failure,
invalid_self_ref_pml4e,
invalid_mapping_pml4e,
invalid_host_virtual,
invalid_guest_physical,
invalid_guest_virtual,
page_table_init_failed
};
typedef union _command_t
{
struct _copy_phys
{
host_phys_t phys_addr;
guest_virt_t buffer;
u64 size;
} copy_phys;
struct _copy_virt
{
guest_phys_t dirbase_src;
guest_virt_t virt_src;
guest_phys_t dirbase_dest;
guest_virt_t virt_dest;
u64 size;
} copy_virt;
struct _translate_virt
{
guest_virt_t virt_src;
guest_phys_t phys_addr;
} translate_virt;
guest_phys_t dirbase;
} command_t, * pcommand_t;
/// <summary>
/// this function is used to cause a vmexit as though its calling a function...
/// </summary>
extern "C" auto hypercall(u64 key, vmexit_command_t, pcommand_t command)->vmxroot_error_t;
/// <summary>
/// gets the current cores CR3 value (current address space pml4)...
/// </summary>
/// <returns>returns the guest cr3 value...</returns>
auto current_dirbase()->guest_phys_t;
/// <summary>
/// initalizies page tables for all cores...
/// </summary>
/// <returns>status of the initalization...</returns>
auto init()->vmxroot_error_t;
/// <summary>
/// translate a linear virtual address of the current address space
/// to a linear physical address...
/// </summary>
/// <param name="virt_addr">virtual address in the vmexiting core's address space...</param>
/// <returns>guest physical address...</returns>
auto translate(guest_virt_t virt_addr)->guest_phys_t;
/// <summary>
/// reads guest physical memory...
/// </summary>
/// <param name="phys_addr">physical address to read...</param>
/// <param name="buffer">buffer (guest virtual address) to read into...</param>
/// <param name="size">number of bytes to read (can only be 0x1000 or less)...</param>
/// <returns>STATUS_SUCCESS if the read was successful...</returns>
auto read_phys(guest_phys_t phys_addr, guest_virt_t buffer, u64 size)->vmxroot_error_t;
/// <summary>
/// write guest physical memory...
/// </summary>
/// <param name="phys_addr">physical address to read</param>
/// <param name="buffer">guest virtual address to write from...</param>
/// <param name="size">number of bytes to write</param>
/// <returns></returns>
auto write_phys(guest_phys_t phys_addr, guest_virt_t buffer, u64 size)->vmxroot_error_t;
/// <summary>
/// copy guest virtual memory between virtual address spaces...
/// </summary>
/// <param name="dirbase_src">dirbase of the source address space</param>
/// <param name="virt_src">virtual address in the source address space</param>
/// <param name="dirbase_dest">dirbase of the destination address space</param>
/// <param name="virt_dest">virtual address of the destination address</param>
/// <param name="size">size to copy between address spaces</param>
/// <returns>returns error_success on successful copy and invalid_guest_virt when an address is invalid...</returns>
auto copy_virt(guest_phys_t dirbase_src, guest_virt_t virt_src, guest_phys_t dirbase_dest,
guest_virt_t virt_dest, u64 size)->vmxroot_error_t;
template <class T>
auto rpm(guest_phys_t dirbase, guest_virt_t virt_addr) -> T
{
T buffer;
auto result = copy_virt(dirbase, virt_addr,
current_dirbase(), (guest_virt_t)&buffer, sizeof T);
if (result != vmxroot_error_t::error_success)
return {};
return buffer;
}
template <class T>
auto wpm(guest_phys_t dirbase, guest_virt_t virt_addr, const T& data) -> void
{
copy_virt(dirbase, (guest_virt_t)&data,
dirbase, virt_addr, sizeof T);
}
}

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30621.155
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libvoyager", "libvoyager\libvoyager.vcxproj", "{F468E79E-CC93-4A7F-844E-984117B5B08B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", "example\example.vcxproj", "{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F468E79E-CC93-4A7F-844E-984117B5B08B}.Debug|x64.ActiveCfg = Debug|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.Debug|x64.Build.0 = Debug|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.Release|x64.ActiveCfg = Release|x64
{F468E79E-CC93-4A7F-844E-984117B5B08B}.Release|x64.Build.0 = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.Debug|x64.ActiveCfg = Debug|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.Debug|x64.Build.0 = Debug|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.Release|x64.ActiveCfg = Release|x64
{1770C4FB-345F-40DD-B4A2-2A5DC8A50866}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BA7C21A6-0410-4D98-92D4-1F66944EAC47}
EndGlobalSection
EndGlobal

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="libvoyager.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="libvoyager.hpp" />
</ItemGroup>
<ItemGroup>
<MASM Include="com.asm">
<FileType>Document</FileType>
</MASM>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{f468e79e-cc93-4a7f-844e-984117b5b08b}</ProjectGuid>
<RootNamespace>libvoyager</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</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)'=='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)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<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>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>

@ -11,12 +11,12 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<ClCompile Include="libvoyager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="com.h">
<ClInclude Include="libvoyager.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Loading…
Cancel
Save