Update documents
This commit is contained in:
@@ -273,7 +273,7 @@ It is recommended to configure all of them for debugging the UEFI driver.
|
|||||||

|

|
||||||
|
|
||||||
Here is an example output, showing that triple fault occurred.
|
Here is an example output, showing that triple fault occurred.
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
UEFI: Viewing Serial Output From the Virtual Machine
|
UEFI: Viewing Serial Output From the Virtual Machine
|
||||||
@@ -356,7 +356,7 @@ VMware Workstation is the only supported virtualization platform. However, one c
|
|||||||
|
|
||||||
Not usable due to lack of nested virtualization support.
|
Not usable due to lack of nested virtualization support.
|
||||||
|
|
||||||
- Boches
|
- Bochs
|
||||||
|
|
||||||
Not usable due to lack of UEFI support.
|
Not usable due to lack of UEFI support.
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 581 KiB After Width: | Height: | Size: 286 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 348 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 965 KiB |
BIN
Docs/Resources/Readme_Showcase1.jpg
Normal file
BIN
Docs/Resources/Readme_Showcase1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 358 KiB |
BIN
Docs/Resources/Readme_Showcase2.jpg
Normal file
BIN
Docs/Resources/Readme_Showcase2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 115 KiB |
24
README.md
24
README.md
@@ -1,5 +1,5 @@
|
|||||||
What's This
|
MiniVisor
|
||||||
============
|
==========
|
||||||
|
|
||||||
This is a research hypervisor written as a UEFI and Windows driver for the educational purpose for Intel processors.
|
This is a research hypervisor written as a UEFI and Windows driver for the educational purpose for Intel processors.
|
||||||
|
|
||||||
@@ -9,7 +9,11 @@ This MiniVisor, as a UEFI driver, provides the ability to inspect system activit
|
|||||||
Showcase
|
Showcase
|
||||||
---------
|
---------
|
||||||
|
|
||||||
TBD.
|
* Loading the hypervisor from the UEFI shell.
|
||||||
|

|
||||||
|
|
||||||
|
* Logging boot activities and interacting with the guest.
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
Motivation
|
Motivation
|
||||||
@@ -17,7 +21,7 @@ Motivation
|
|||||||
|
|
||||||
The goal of this project is to share an additional learning resource for writing UEFI hypervisors with the community and researchers.
|
The goal of this project is to share an additional learning resource for writing UEFI hypervisors with the community and researchers.
|
||||||
|
|
||||||
There are numerous open source hypervisors that can relatively easily study their implementations, but those that support booting operating systems as UEFI drivers are still not many.
|
There are numerous open source hypervisors with small and easy-to-study implementations, but those that support booting operating systems as UEFI drivers are still not many.
|
||||||
|
|
||||||
Given the universality of UEFI systems on the AMD64 ecosystem and the unique ability to monitor, attack and protect the system throughout operating system startup on bare-metal systems, the authors believe that having the understanding and being able to author this type of hypervisors are valuable for research.
|
Given the universality of UEFI systems on the AMD64 ecosystem and the unique ability to monitor, attack and protect the system throughout operating system startup on bare-metal systems, the authors believe that having the understanding and being able to author this type of hypervisors are valuable for research.
|
||||||
|
|
||||||
@@ -47,6 +51,18 @@ Requirements for the Windows driver:
|
|||||||
See [Building and Debugging](Docs/Building_and_Debugging.md) for testing.
|
See [Building and Debugging](Docs/Building_and_Debugging.md) for testing.
|
||||||
|
|
||||||
|
|
||||||
|
Advantages and Use Cases
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
While this project does not implement any immediately useful features, UEFI-based hypervisors have multiple advantages over Windows driver-based ones and can implement unique features.
|
||||||
|
|
||||||
|
* No need of disabling Hyper-V (Virtualization Based Security) to run the custom hypervisor
|
||||||
|
* No need of enabling the test-signing mode
|
||||||
|
* Zero direct indicator of existence of the hypervisor from Windows perspective
|
||||||
|
* Installing hooks during the early boot phase and letting PatchGuard to protect them
|
||||||
|
* Detecting bootkit and early system modification
|
||||||
|
|
||||||
|
|
||||||
Limitations
|
Limitations
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
|||||||
@@ -331,6 +331,13 @@ HandleCrAccess (
|
|||||||
if (currentCr0.PagingEnable != newCr0.PagingEnable)
|
if (currentCr0.PagingEnable != newCr0.PagingEnable)
|
||||||
{
|
{
|
||||||
SwitchGuestPagingMode(newCr0);
|
SwitchGuestPagingMode(newCr0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// For demonstration with VMware. On bare-metal, delay because of
|
||||||
|
// this logging may lead to failure of AP start up.
|
||||||
|
//
|
||||||
|
//LOG_INFO("Processor #%d switching to the long mode",
|
||||||
|
// GuestContext->Contexts->ProcessorNumber);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VMX_EXIT_QUALIFICATION_REGISTER_CR4:
|
case VMX_EXIT_QUALIFICATION_REGISTER_CR4:
|
||||||
@@ -452,7 +459,20 @@ HandleExceptionOrNmi (
|
|||||||
((UINT32)GuestContext->StackBasedRegisters->Rdx == (UINT32)0xffffffff) &&
|
((UINT32)GuestContext->StackBasedRegisters->Rdx == (UINT32)0xffffffff) &&
|
||||||
((UINT32)GuestContext->StackBasedRegisters->R8 == (UINT32)-1))
|
((UINT32)GuestContext->StackBasedRegisters->R8 == (UINT32)-1))
|
||||||
{
|
{
|
||||||
LOG_DEBUG("KeInitAmd64SpecificState triggered #DE. Ignoring it.");
|
UINT64 ntoskrnlBase;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Just as an example of how to access the guest virtual address, search
|
||||||
|
// the base address of the NT kernel and print it out.
|
||||||
|
//
|
||||||
|
ntoskrnlBase = FindImageBase(GuestContext, GuestContext->VmcsBasedRegisters.Rip);
|
||||||
|
if (ntoskrnlBase != 0)
|
||||||
|
{
|
||||||
|
LOG_INFO("Found ntoskrnl.exe at %016llx", ntoskrnlBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO("KeInitAmd64SpecificState triggered #DE");
|
||||||
|
LOG_INFO("Skipping main PatchGuard initialization.");
|
||||||
isKeInitAmd64SpecificStateCalled = TRUE;
|
isKeInitAmd64SpecificStateCalled = TRUE;
|
||||||
AdvanceGuestInstructionPointer(GuestContext);
|
AdvanceGuestInstructionPointer(GuestContext);
|
||||||
goto Exit;
|
goto Exit;
|
||||||
@@ -480,6 +500,12 @@ HandleInitSignal (
|
|||||||
{
|
{
|
||||||
UNREFERENCED_PARAMETER(GuestContext);
|
UNREFERENCED_PARAMETER(GuestContext);
|
||||||
|
|
||||||
|
//
|
||||||
|
// For demonstration with VMware. On bare-metal, delay because of this logging
|
||||||
|
// may lead to failure of AP start up.
|
||||||
|
//
|
||||||
|
//LOG_INFO("Starting up processor #%d", GuestContext->Contexts->ProcessorNumber);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Simply put the processor into the "wait-for-SIPI" state.
|
// Simply put the processor into the "wait-for-SIPI" state.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "ExtendedPageTables.h"
|
#include "ExtendedPageTables.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
#include "MemoryAccess.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief Dumps the segment access rights value.
|
@brief Dumps the segment access rights value.
|
||||||
@@ -413,3 +414,40 @@ AdjustGuestCr4 (
|
|||||||
{
|
{
|
||||||
return AdjustCr4(Cr4);
|
return AdjustCr4(Cr4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_Use_decl_annotations_
|
||||||
|
UINT64
|
||||||
|
FindImageBase (
|
||||||
|
GUEST_CONTEXT* GuestContext,
|
||||||
|
UINT64 GuestVirtualAddress
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Starting with the 1MB aligned address, and search up IMAGE_DOS_SIGNATURE
|
||||||
|
// every 1MB.
|
||||||
|
//
|
||||||
|
for (UINT64 imageBase = (GuestVirtualAddress & ~(0x10000 - 1));
|
||||||
|
/**/;
|
||||||
|
imageBase -= 0x10000)
|
||||||
|
{
|
||||||
|
BOOLEAN ok;
|
||||||
|
UINT16 contents;
|
||||||
|
MEMORY_ACCESS_ERROR_INFORMATION errorInfo;
|
||||||
|
|
||||||
|
ok = ReadGuestVirtualAddress(GuestContext->Contexts->MemoryAccessContext,
|
||||||
|
TRUE,
|
||||||
|
imageBase,
|
||||||
|
&contents,
|
||||||
|
sizeof(contents),
|
||||||
|
&errorInfo);
|
||||||
|
if (ok == FALSE)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contents == 0x5A4D)
|
||||||
|
{
|
||||||
|
return imageBase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -215,3 +215,20 @@ CR4
|
|||||||
AdjustGuestCr4 (
|
AdjustGuestCr4 (
|
||||||
_In_ CR4 Cr4
|
_In_ CR4 Cr4
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Find the base address of the image to which the specified address belongs.
|
||||||
|
|
||||||
|
@param[in] GuestContext - The pointer to the guest context.
|
||||||
|
|
||||||
|
@param[in] GuestVirtualAddress - The guest virtual address to find its image
|
||||||
|
base.
|
||||||
|
|
||||||
|
@return The base address of the image to which GuestVirtualAddress belongs, or
|
||||||
|
0 on error.
|
||||||
|
*/
|
||||||
|
UINT64
|
||||||
|
FindImageBase (
|
||||||
|
_In_ GUEST_CONTEXT* GuestContext,
|
||||||
|
_In_ UINT64 GuestVirtualAddress
|
||||||
|
);
|
||||||
|
|||||||
@@ -802,6 +802,11 @@ SetupVmcs (
|
|||||||
_sgdt(&gdtr);
|
_sgdt(&gdtr);
|
||||||
__sidt(&idtr);
|
__sidt(&idtr);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Intercept #DB. This is purely for demonstration and can be removed.
|
||||||
|
//
|
||||||
|
exceptionBitmap = (1 << DivideError);
|
||||||
|
|
||||||
//
|
//
|
||||||
// VM-entry and -exit controls define how processor should operate on
|
// VM-entry and -exit controls define how processor should operate on
|
||||||
// VM-entry and exit. The following configurations are to achieve that:
|
// VM-entry and exit. The following configurations are to achieve that:
|
||||||
@@ -845,7 +850,9 @@ SetupVmcs (
|
|||||||
// instructions. Those instructions are used in Windows 10. If those are
|
// instructions. Those instructions are used in Windows 10. If those are
|
||||||
// not set, attempt to execute them causes #UD, which results in a bug
|
// not set, attempt to execute them causes #UD, which results in a bug
|
||||||
// check. VPID is enabled, which could lead to better performance for free
|
// check. VPID is enabled, which could lead to better performance for free
|
||||||
// by not flushing all TLB on every VM-exit. Finally, to enable EPT as well.
|
// by not flushing all TLB on every VM-exit. Finally, to enable EPT and
|
||||||
|
// unrestricted guest which are required for the UEFI hypervisor to handle
|
||||||
|
// the real-mode guest.
|
||||||
//
|
//
|
||||||
primaryProcBasedControls.Flags = 0;
|
primaryProcBasedControls.Flags = 0;
|
||||||
primaryProcBasedControls.UseMsrBitmaps = TRUE;
|
primaryProcBasedControls.UseMsrBitmaps = TRUE;
|
||||||
@@ -915,7 +922,6 @@ SetupVmcs (
|
|||||||
VmxWrite(VMCS_CTRL_EPT_POINTER, VpContext->EptContext.EptPointer.Flags);
|
VmxWrite(VMCS_CTRL_EPT_POINTER, VpContext->EptContext.EptPointer.Flags);
|
||||||
|
|
||||||
/* 32-Bit Control Fields */
|
/* 32-Bit Control Fields */
|
||||||
exceptionBitmap = (1 << DivideError);
|
|
||||||
VmxWrite(VMCS_CTRL_EXCEPTION_BITMAP, exceptionBitmap);
|
VmxWrite(VMCS_CTRL_EXCEPTION_BITMAP, exceptionBitmap);
|
||||||
VmxWrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, pinBasedControls.Flags);
|
VmxWrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, pinBasedControls.Flags);
|
||||||
VmxWrite(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, primaryProcBasedControls.Flags);
|
VmxWrite(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, primaryProcBasedControls.Flags);
|
||||||
|
|||||||
@@ -56,9 +56,8 @@
|
|||||||
<IncludePath>$(SolutionDir)Include;$(Edk2Dir)MdePkg\Include;$(Edk2Dir)MdePkg\Include\X64</IncludePath>
|
<IncludePath>$(SolutionDir)Include;$(Edk2Dir)MdePkg\Include;$(Edk2Dir)MdePkg\Include\X64</IncludePath>
|
||||||
<LibraryPath>$(SolutionDir)Libs</LibraryPath>
|
<LibraryPath>$(SolutionDir)Libs</LibraryPath>
|
||||||
<TargetExt>.efi</TargetExt>
|
<TargetExt>.efi</TargetExt>
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)'=='UEFI'">
|
|
||||||
<TargetName>$(ProjectName)Dxe</TargetName>
|
<TargetName>$(ProjectName)Dxe</TargetName>
|
||||||
|
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
@@ -91,6 +90,7 @@
|
|||||||
</PreLinkEvent>
|
</PreLinkEvent>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command Condition="'$(Configuration)'=='UEFI'">copy /y $(OutDir)$(TargetName)$(TargetExt) D:\</Command>
|
<Command Condition="'$(Configuration)'=='UEFI'">copy /y $(OutDir)$(TargetName)$(TargetExt) D:\</Command>
|
||||||
|
<Message Condition="'$(Configuration)'=='UEFI'">Copy the build output to the USB drive. Useful for compile and test interation.</Message>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
@copyright Copyright (c) 2020 - , Satoshi Tanda. All rights reserved.
|
@copyright Copyright (c) 2020 - , Satoshi Tanda. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
#pragma once
|
||||||
#include "../../Logger.h"
|
#include "../../Logger.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
Reference in New Issue
Block a user