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

|
||||

|
||||
|
||||
|
||||
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.
|
||||
|
||||
- Boches
|
||||
- Bochs
|
||||
|
||||
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.
|
||||
|
||||
@@ -9,7 +9,11 @@ This MiniVisor, as a UEFI driver, provides the ability to inspect system activit
|
||||
Showcase
|
||||
---------
|
||||
|
||||
TBD.
|
||||
* Loading the hypervisor from the UEFI shell.
|
||||

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

|
||||
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -47,6 +51,18 @@ Requirements for the Windows driver:
|
||||
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
|
||||
------------
|
||||
|
||||
|
||||
@@ -331,6 +331,13 @@ HandleCrAccess (
|
||||
if (currentCr0.PagingEnable != newCr0.PagingEnable)
|
||||
{
|
||||
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;
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_CR4:
|
||||
@@ -452,7 +459,20 @@ HandleExceptionOrNmi (
|
||||
((UINT32)GuestContext->StackBasedRegisters->Rdx == (UINT32)0xffffffff) &&
|
||||
((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;
|
||||
AdvanceGuestInstructionPointer(GuestContext);
|
||||
goto Exit;
|
||||
@@ -480,6 +500,12 @@ HandleInitSignal (
|
||||
{
|
||||
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.
|
||||
//
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "Logger.h"
|
||||
#include "ExtendedPageTables.h"
|
||||
#include "Utils.h"
|
||||
#include "MemoryAccess.h"
|
||||
|
||||
/*!
|
||||
@brief Dumps the segment access rights value.
|
||||
@@ -413,3 +414,40 @@ AdjustGuestCr4 (
|
||||
{
|
||||
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 (
|
||||
_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);
|
||||
__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. The following configurations are to achieve that:
|
||||
@@ -845,7 +850,9 @@ SetupVmcs (
|
||||
// instructions. Those instructions are used in Windows 10. If those are
|
||||
// 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
|
||||
// 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.UseMsrBitmaps = TRUE;
|
||||
@@ -915,7 +922,6 @@ SetupVmcs (
|
||||
VmxWrite(VMCS_CTRL_EPT_POINTER, VpContext->EptContext.EptPointer.Flags);
|
||||
|
||||
/* 32-Bit Control Fields */
|
||||
exceptionBitmap = (1 << DivideError);
|
||||
VmxWrite(VMCS_CTRL_EXCEPTION_BITMAP, exceptionBitmap);
|
||||
VmxWrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, pinBasedControls.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>
|
||||
<LibraryPath>$(SolutionDir)Libs</LibraryPath>
|
||||
<TargetExt>.efi</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='UEFI'">
|
||||
<TargetName>$(ProjectName)Dxe</TargetName>
|
||||
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
@@ -91,6 +90,7 @@
|
||||
</PreLinkEvent>
|
||||
<PostBuildEvent>
|
||||
<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>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
@copyright Copyright (c) 2020 - , Satoshi Tanda. All rights reserved.
|
||||
*/
|
||||
#pragma once
|
||||
#include "../../Logger.h"
|
||||
|
||||
/*!
|
||||
|
||||
Reference in New Issue
Block a user