diff --git a/Builds/Platform/EFI/locate_image_base.py b/Builds/Platform/EFI/locate_image_base.py index 5cdd2c9..82cc154 100644 --- a/Builds/Platform/EFI/locate_image_base.py +++ b/Builds/Platform/EFI/locate_image_base.py @@ -1,3 +1,9 @@ +#!/usr/bin/python +# +# Locates the image base from the current RIP value. This can be manually invoked +# from the IDA Pro during the GDB remote debug session to load symbols (a PDB file). +# +# Author: Satoshi Tanda current_page_base = idaapi.get_reg_val('rip') & (~0xfff) offset = 0 while idc.read_dbg_word(current_page_base - offset) != 0x5a4d: diff --git a/Builds/PreLinkEvent.py b/Builds/PreLinkEvent.py index 7552f20..ecd0aa7 100644 --- a/Builds/PreLinkEvent.py +++ b/Builds/PreLinkEvent.py @@ -1,3 +1,10 @@ +#!/usr/bin/python +# +# Copies the lib files created by the EDK2's build command to a single specified +# locations, so that Visual Studio can easily find and link them. Invoked as +# part of Pre-Link Event of the MiniVisor project. +# +# Author: Satoshi Tanda import os import sys import shutil diff --git a/Sources/Asm.asm b/Sources/Asm.asm index 7083f92..52966b4 100644 --- a/Sources/Asm.asm +++ b/Sources/Asm.asm @@ -23,17 +23,17 @@ extern HandleVmExit : proc extern HandleVmExitFailure : proc ; -; @brief An entry point for the hypervisor. +; @brief The entry point for the hypervisor. ; ; @details The easiest way to understand this code is to see this as an entry ; point of "VM-exit handler". ; ; Up on VM-exit, the processor starts executing this function as -; condifured in the VmcsHostRip field of VMCS. At this time, the processor -; is in the vmx-root mode, which allows the processor to execute any -; instructions without causing VM-exit, and the processor is not governed -; by EPT. The code executed from here emulates the instruction caused -; VM-exit by, most typically, executing the same instruction on behalf of +; configured in the Host RIP field of VMCS. When this function is executed, +; the processor is in the vmx-root mode, which allows the processor to +; execute any instructions without causing VM-exit, and the processor is +; not governed by EPT. The code executed from here most typically emulates +; the instruction caused VM-exit by executing the same instruction on behalf of ; the guest (see HandleCpuid for example), or changing relevant processor ; state and letting the guest retry, for example, handling EPT violation. ; @@ -41,6 +41,8 @@ extern HandleVmExitFailure : proc ; context. We also refer those code as a VM-exit handler. ; AsmHypervisorEntryPoint proc frame + ; + ; Windows-specific: ; ; Three not-well known techniques are used in this function in oder for ; Windbg to display the stack trace of the guest while the VM-exit @@ -177,9 +179,8 @@ ExitVm: VmxError: ; - ; Any of VMX instructions failed. Unrecoverble. The most useful thing - ; to do here is probably to call a C-function that does diagnostics - ; like dumping VMCS. + ; VMRESUME or VMXOFF instruction failed. Unrecoverble. The most useful + ; thing to do here is to call a C-function to diagnose the issue. ; pushf PUSHAQ @@ -190,11 +191,11 @@ VmxError: AsmHypervisorEntryPoint endp ; -; @brief Invalidate translations derived from EPT +; @brief Invalidates translations derived from EPT ; -; @param[in] RCX - A type of invalidation. +; @param[in] RCX - The type of invalidation. ; -; @param[in] RDX - A description of translations to invalidate. +; @param[in] RDX - The description of translations to invalidate. ; ; @return An appropriate VMX_RESULT value. ; @@ -221,11 +222,11 @@ ErrorWithoutCode: AsmInvept endp ; -; @brief Invalidate translations based on VPID +; @brief Invalidates translations based on VPID ; -; @param[in] RCX - A type of invalidation. +; @param[in] RCX - The type of invalidation. ; -; @param[in] RDX - A description of translations to invalidate. +; @param[in] RDX - The description of translations to invalidate. ; ; @return An appropriate VMX_RESULT value. ; @@ -287,9 +288,9 @@ AsmVmxCall proc AsmVmxCall endp ; -; @brief Returns the address of the return address from this function. +; @brief Returns the return address from this function. ; -; @return The address of the return address from this function. +; @return The return address from this function. ; AsmGetCurrentInstructionPointer proc mov rax, [rsp] diff --git a/Sources/Asm.h b/Sources/Asm.h index 5f4d394..9cd6ac3 100644 --- a/Sources/Asm.h +++ b/Sources/Asm.h @@ -10,28 +10,27 @@ #pragma once #include "Common.h" -#if defined(NTDDI_VERSION) +#if defined(MV_PLATFORM_WINDOWS) #include "Platform/Windows/WinAsm.h" #else #include "Platform/EFI/EfiAsm.h" #endif /*! - @brief An entry point for the hypervisor. + @brief The entry point for the hypervisor. - @details See x64.asm. + @details See Asm.asm. */ VOID AsmHypervisorEntryPoint ( - VOID ); /*! - @brief Invalidate translations derived from EPT. + @brief Invalidates translations derived from EPT. - @param[in] InvEptType - A type of invalidation. + @param[in] InvEptType - The type of invalidation. - @param[in] InvEptDescriptor - A description of translations to invalidate. + @param[in] InvEptDescriptor - The description of translations to invalidate. @return An appropriate VMX_RESULT value. */ @@ -42,11 +41,11 @@ AsmInvept ( ); /*! - @brief Invalidate translations based on VPID. + @brief Invalidates translations based on VPID. - @param[in] InvVpidType - A type of invalidation. + @param[in] InvVpidType - The type of invalidation. - @param[in] InvVpidDescriptor - A description of translations to invalidate. + @param[in] InvVpidDescriptor - The description of translations to invalidate. @return An appropriate VMX_RESULT value. */ @@ -56,7 +55,6 @@ AsmInvvpid ( _In_ CONST INVVPID_DESCRIPTOR* InvVpidDescriptor ); - /*! @brief Reads the access rights byte of the segment. @@ -93,13 +91,12 @@ AsmVmxCall ( ); /*! - @brief Returns the address of the return address from this function. + @brief Returns the return address from this function. - @return The address of the return address from this function. + @return The return address from this function. */ UINT64 AsmGetCurrentInstructionPointer ( - VOID ); /*! @@ -109,5 +106,4 @@ AsmGetCurrentInstructionPointer ( */ UINT64 AsmGetCurrentStackPointer ( - VOID ); diff --git a/Sources/Common.h b/Sources/Common.h index 4817615..24cd8b2 100644 --- a/Sources/Common.h +++ b/Sources/Common.h @@ -9,10 +9,17 @@ */ #pragma once #if defined(NTDDI_VERSION) +#define MV_PLATFORM_WINDOWS +#else +#define MV_PLATFORM_EFI +#endif + +#if defined(MV_PLATFORM_WINDOWS) #include "Platform/Windows/WinCommon.h" #else #include "Platform/EFI/EfiCommon.h" #endif + #include "Ia32.h" // diff --git a/Sources/ExtendedPageTables.c b/Sources/ExtendedPageTables.c index 7934a2e..35ffaa7 100644 --- a/Sources/ExtendedPageTables.c +++ b/Sources/ExtendedPageTables.c @@ -37,11 +37,11 @@ typedef struct _EPT_ENTRIES C_ASSERT(sizeof(EPT_ENTRIES) == sizeof(VOID*) * 4); /*! - @brief Cleans up all EPT entries and the table recursively. + @brief Cleans up all EPT entries and the tables recursively. - @param[in,out] EptTable - A pointer to the EPT table to clean up. + @param[in,out] EptTable - The pointer to the EPT table to clean up. - @param[in] PageMapLevel - A level of the table. + @param[in] PageMapLevel - The level of the table. */ static VOID diff --git a/Sources/ExtendedPageTables.h b/Sources/ExtendedPageTables.h index 01a902f..afd102b 100644 --- a/Sources/ExtendedPageTables.h +++ b/Sources/ExtendedPageTables.h @@ -63,9 +63,9 @@ typedef struct _EPT_CONTEXT } EPT_CONTEXT; /*! - @brief Initializes EPT with pass-through style configurations. + @brief Initializes identity-mapping EPTs. - @param[in,out] EptContext - A pointer to the EPT context to initialize. + @param[in,out] EptContext - The pointer to the EPT context to initialize. @return MV_STATUS_SUCCESS on success; otherwise, an appropriate error code. */ @@ -76,9 +76,9 @@ InitializeExtendedPageTables ( ); /*! - @brief Cleans up EPT context. + @brief Cleans up the EPT context. - @param[in,out] EptContext - A pointer to the EPT context to clean up. + @param[in,out] EptContext - The pointer to the EPT context to clean up. */ VOID CleanupExtendedPageTables ( @@ -110,7 +110,7 @@ UpdateExtendPageTables ( ); /*! - @brief Invalidate guest-physical and combined caches. + @brief Invalidates guest-physical and combined caches. @param[in] EptPointer - The EPT pointer to invalidate associated caches. If 0 is specified, caches associated with any EPT pointers are invalidated. @@ -121,10 +121,10 @@ InvalidateEptDerivedCache ( ); /*! - @brief Invalidate liner and combined caches. + @brief Invalidates liner and combined caches. @param[in] VirtualProcessorId - The VPID to invalidate associated caches. If - 0 is specified, caches associated with any VPID are invalidated. + 0 is specified, caches associated with any VPIDs are invalidated. */ VOID InvalidateVpidDerivedCache ( diff --git a/Sources/HostMain.c b/Sources/HostMain.c index b2790b2..4ee06c0 100644 --- a/Sources/HostMain.c +++ b/Sources/HostMain.c @@ -15,6 +15,8 @@ #include "HostVmcall.h" #include "HostNesting.h" +// +// Windows-specific: // // The trap frame structure for x64 systems. This is structure is used to help // Windbg to construct call stack while VM-exit handlers are being executed. @@ -53,7 +55,7 @@ typedef struct _INITIAL_HYPERVISOR_STACK can check the exception is #GP(0) caused by RDMSR or WRMSR, and if this is the case, inject it to the guest. - @param[in,out] GuestContext - A pointer to the guest context. + @param[in,out] GuestContext - The pointer to the guest context. @param[in] OperationType - The type of the operation. */ @@ -110,7 +112,7 @@ HandleMsrAccess ( /*! @brief Handles VM-exit due to execution of the RDMSR instruction. - @param[in,out] GuestContext - A pointer to the guest context. + @param[in,out] GuestContext - The pointer to the guest context. */ static VOID @@ -124,7 +126,7 @@ HandleMsrRead ( /*! @brief Handles VM-exit due to execution of the WRMSR instruction. - @param[in,out] GuestContext - A pointer to the guest context. + @param[in,out] GuestContext - The pointer to the guest context. */ static VOID @@ -138,7 +140,7 @@ HandleMsrWrite ( /*! @brief Handles VM-exit due to execution of the CPUID instruction. - @param[in,out] GuestContext - A pointer to the guest context. + @param[in,out] GuestContext - The pointer to the guest context. */ static VOID @@ -208,7 +210,7 @@ HandleCpuid ( /*! @brief Handles VM-exit due to execution of the VMCALL instruction. - @param[in,out] GuestContext - A pointer to the guest context. + @param[in,out] GuestContext - The pointer to the guest context. */ static VOID @@ -245,7 +247,7 @@ Exit: /*! @brief Handles VM-exit due to execution of the XSETBV instruction. - @param[in,out] GuestContext - A pointer to the guest context. + @param[in,out] GuestContext - The pointer to the guest context. */ static VOID @@ -275,7 +277,7 @@ HandleXsetbv ( @brief Returns the address of where the guest general purpose register that corresponds to the given index is stored. - @param[in,out] GuestContext - A pointer to the guest context. + @param[in,out] GuestContext - The pointer to the guest context. @param[in] RegisterIndex - The index provided by VMCS up on VM-exit. @@ -318,7 +320,7 @@ SelectEffectiveRegister ( /*! @brief Handles VM-exit due to execution of access to the control register. - @param[in,out] GuestContext - A pointer to the guest context. + @param[in,out] GuestContext - The pointer to the guest context. */ static VOID @@ -382,7 +384,7 @@ HandleCrAccess ( /*! @brief Handles VM-exit due to EPT violation. - @param[in,out] GuestContext - A pointer to the guest context. + @param[in,out] GuestContext - The pointer to the guest context. */ static VOID @@ -408,7 +410,7 @@ HandleEptViolation ( /*! @brief Handles VM-exit due to EPT misconfiguration. - @param[in,out] GuestContext - A pointer to the guest context. + @param[in,out] GuestContext - The pointer to the guest context. */ static VOID @@ -444,7 +446,12 @@ HandleEptMisconfig ( /*! @brief Handles VM-exit due to interrupt or exception. - @param[in,out] GuestContext - A pointer to the guest context. + @details Currently, this handler is specialized for skipping main initialization + of PatchGuard for the demo purpose. When #DE occurs with the guest state + that seems to be the trigger of PatchGuard initialization, suppress it. + Otherwise, just inject the exception (pass-through). + + @param[in,out] GuestContext - The pointer to the guest context. */ static VOID @@ -455,11 +462,6 @@ HandleExceptionOrNmi ( static BOOLEAN isKeInitAmd64SpecificStateCalled; VMEXIT_INTERRUPT_INFORMATION interruptInfo; - // - // This handler is specialized for skipping main initialization of PatchGuard. - // When #DE occurs with the guest state that seems to be during initialization - // of PatchGuard, suppress it. Otherwise, just inject the exception (pass-through). - // interruptInfo.Flags = (UINT32)VmxRead(VMCS_VMEXIT_INTERRUPTION_INFORMATION); MV_ASSERT(interruptInfo.InterruptionType == HardwareException); MV_ASSERT(interruptInfo.Vector == DivideError); @@ -513,7 +515,7 @@ Exit: /*! @brief Handles VM-exit due to the INIT signal. - @param[in,out] GuestContext - A pointer to the guest context. + @param[in,out] GuestContext - The pointer to the guest context. */ static VOID @@ -673,7 +675,7 @@ HandleInitSignal ( /*! @brief Handles VM-exit due to the Startup-IPI (SIPI) signal. - @param[in,out] GuestContext - A pointer to the guest context. + @param[in,out] GuestContext - The pointer to the guest context. */ static VOID @@ -738,12 +740,12 @@ HandleStartupIpi ( Any hypervisor code including this and the AsmHypervisorEntryPoint functions are executed while interrupt is disabled via RFLAGS.IF being 0 (See: 27.5.3 Loading Host RIP, RSP, and RFLAGS). This means IPI, if - requested, is never delivered and causes deadlock. This condition is - essentially equal to IRQL being HIGH_LEVEL (i.e., at a higher IRQL than - IPI_LEVEL), and so, it is unsafe to call any Windows provided API that - is not stated as callable at HIGH_LEVEL. + requested, is never delivered and causes deadlock. In the Windows + terminology, this condition is essentially equal to IRQL being HIGH_LEVEL + (i.e., at a higher IRQL than IPI_LEVEL), and so, it is unsafe to call any + Windows provided API that is not stated as callable at HIGH_LEVEL. - @param[in,out] Stack - A pointer to the hypervisor stack containing the + @param[in,out] Stack - The pointer to the hypervisor stack containing the guest register values. @return TRUE when virtualization should continue and the VMRESUME instruction @@ -785,6 +787,8 @@ HandleVmExit ( guestContext.VmcsBasedRegisters.Rsp = VmxRead(VMCS_GUEST_RSP); guestContext.VmcsBasedRegisters.Rip = VmxRead(VMCS_GUEST_RIP); + // + // Windows-specific: // // Update the _KTRAP_FRAME structure values in hypervisor stack, so that // Windbg can reconstruct call stack of the guest during debug session. @@ -903,7 +907,7 @@ typedef struct _EXCEPTION_STACK @details On Windows, this function is unused because the host uses the same IDT as that of the guest. All interrupts and exceptions are handled by - the NT kernel. + the NT kernel allowing Windbg to work as usual. @param[in] Stack - The pointer to the hypervisor stack containing the guest register values. diff --git a/Sources/HostUtils.c b/Sources/HostUtils.c index 37138fe..db0dfc6 100644 --- a/Sources/HostUtils.c +++ b/Sources/HostUtils.c @@ -308,7 +308,6 @@ AdvanceGuestInstructionPointer ( _Use_decl_annotations_ BOOLEAN IsGuestInKernelMode ( - VOID ) { VMX_SEGMENT_ACCESS_RIGHTS accessRight; diff --git a/Sources/HostUtils.h b/Sources/HostUtils.h index e6acba8..a766fce 100644 --- a/Sources/HostUtils.h +++ b/Sources/HostUtils.h @@ -107,9 +107,9 @@ DumpControl ( /*! @brief Writes the value to the VMCS. - @param[in] Field - A VMCS field to write the value to. + @param[in] Field - The VMCS field to write the value to. - @param[in] FieldValue - A value to write. + @param[in] FieldValue - The value to write. */ VOID VmxWrite ( @@ -120,7 +120,7 @@ VmxWrite ( /*! @brief Read a value from the VMCS. - @param[in] Field - A VMCS field to read a value from. + @param[in] Field - The VMCS field to read a value from. @return A value read from the VMCS. 0 is returned when a non-existent VMCS field is requested for read. @@ -134,7 +134,7 @@ VmxRead ( @brief Advances the guest's RIP to the address of the next instruction. This implies that the hypervisor completed emulation of the instruction. - @param[in,out] GuestContext - A pointer to the guest context. + @param[in,out] GuestContext - The pointer to the guest context. */ VOID AdvanceGuestInstructionPointer ( @@ -150,7 +150,6 @@ AdvanceGuestInstructionPointer ( _Must_inspect_result_ BOOLEAN IsGuestInKernelMode ( - VOID ); /*! @@ -160,16 +159,16 @@ IsGuestInKernelMode ( corresponding exception handler before executing the instruction pointed by Rip. - @param[in] InterruptionType - A type of interrupt to inject. + @param[in] InterruptionType - The type of interrupt to inject. - @param[in] Vector - A vector number of interrupt to inject. + @param[in] Vector - The vector number of interrupt to inject. @param[in] DeliverErrorCode - TRUE when the interrupt should have an error code. Whether the interrupt should have an error code is defined by the Intel SDM. See comments in the EXCEPTION_VECTOR definitions for a quick reference. - @param[in] ErrorCode - An error code. Not used when DeliverErrorCode is FALSE. + @param[in] ErrorCode - The error code. Not used when DeliverErrorCode is FALSE. */ VOID InjectInterruption ( @@ -217,7 +216,7 @@ AdjustGuestCr4 ( ); /*! - @brief Find the base address of the image to which the specified address belongs. + @brief Finds the base address of the image to which the specified address belongs. @param[in] GuestContext - The pointer to the guest context. diff --git a/Sources/HostVmcall.c b/Sources/HostVmcall.c index 2d8344f..9fd2eb1 100644 --- a/Sources/HostVmcall.c +++ b/Sources/HostVmcall.c @@ -36,7 +36,7 @@ HandleVmcallUninstall ( // from the guest state fields of the VMCS. However, it is not the case when // the VMRESUME is not called, like here. In such a case those values must // be restored with normal value manually, or PatchGuard will report - // integrity violation. + // integrity violation on Windows. // // "The GDTR and IDTR limits are each set to FFFFH." // See: 27.5.2 Loading Host Segment and Descriptor-Table Registers diff --git a/Sources/HostVmcall.h b/Sources/HostVmcall.h index f841a17..7a1987a 100644 --- a/Sources/HostVmcall.h +++ b/Sources/HostVmcall.h @@ -24,7 +24,7 @@ VMCALL_HANDLER ( /*! @brief Handles hypercall for uninstalling the hypervisor. - @param[in,out] GuestContext - A pointer to the guest context. + @param[in,out] GuestContext - The pointer to the guest context. */ VMCALL_HANDLER HandleVmcallUninstall; diff --git a/Sources/Logger.h b/Sources/Logger.h index d9d2654..f8ec233 100644 --- a/Sources/Logger.h +++ b/Sources/Logger.h @@ -19,7 +19,7 @@ // difference of the formatting functions. Use them like the standard's PRIx macro // family. // -#if defined(NTDDI_VERSION) +#if defined(MV_PLATFORM_WINDOWS) #define LOG_PRIANSI "s" #define LOG_PRIUNICODE "S" #else diff --git a/Sources/MemoryAccess.c b/Sources/MemoryAccess.c index 506722e..1e1fe46 100644 --- a/Sources/MemoryAccess.c +++ b/Sources/MemoryAccess.c @@ -14,9 +14,9 @@ #include "Logger.h" /*! - @brief Split a 2MB EPT PDE to 512 EPT PTEs. + @brief Splits a 2MB PDE to 512 PTEs. - @param[in,out] PdeLarge - The pointer to the 2MB EPT PDE to split. + @param[in,out] PdeLarge - The pointer to the 2MB PDE to split. @return MV_STATUS_SUCCESS on success; otherwise, an appropriate error code. */ @@ -499,11 +499,14 @@ GetPhysicalAddressForGuest ( Exit: // - // Return the collected permission bits on success. + // Return the collected permission bits if provided. // - if ((pa != MV_INVALID_PHYSICAL_ADDRESS) && - ARGUMENT_PRESENT(AggregatedPagePermissions)) + if (ARGUMENT_PRESENT(AggregatedPagePermissions)) { + if (pa == MV_INVALID_PHYSICAL_ADDRESS) + { + permission.Flags = 0; + } *AggregatedPagePermissions = permission; } return pa; diff --git a/Sources/MemoryAccess.h b/Sources/MemoryAccess.h index 8b828f4..bc4a4b7 100644 --- a/Sources/MemoryAccess.h +++ b/Sources/MemoryAccess.h @@ -85,9 +85,9 @@ CleanupMemoryAccess ( given virtual address and retrieves the guest physical address of it. This is equivalent to changing the current CR3 with the guest CR3 and calling GetPhysicalAddress(). This function, however, exists to avoid - problems associated with CR3 update, for example, updating the CR3 crashes - the system immediately if the KVA Shadow is enabled and the guest CR3 - contains the USER CR3, as it does not map our driver. + problems associated with CR3 update, for example, on Windows, updating + the CR3 crashes the system immediately if the KVA Shadow is enabled and + the guest CR3 contains the USER CR3, as it does not map our code. @param[in] Context - The pointer to the memory access context. @@ -174,7 +174,8 @@ WriteGuestVirtualAddress ( @param[in] Context - The pointer to the memory access context. - @param[in] GuestPageNumber - See ReadOrWriteGuestVirtualAddress(). + @param[in] GuestPageNumber - The guest page number (ie, the guest virtual + address without lower 12bits) to map to the host address space. @return The virtual address mapping the same physical page as specified as the page number, or NULL if the specified page number does not have diff --git a/Sources/MemoryManager.c b/Sources/MemoryManager.c index 2dee37c..e900fe6 100644 --- a/Sources/MemoryManager.c +++ b/Sources/MemoryManager.c @@ -10,7 +10,7 @@ #include "MemoryManager.h" #include "Platform.h" #include "Logger.h" -#if !defined(NTDDI_VERSION) +#if defined(MV_PLATFORM_EFI) #include "Platform/EFI/EfiBitmap.h" #endif @@ -78,7 +78,7 @@ MmInitializeMemoryManager ( UINT32 lengthMapPagesCount; MEMORY_MANAGER_CONTEXT* memoryManager; - PAGED_CODE() + PAGED_CODE(); memoryManager = &g_MemoryManager; lengthMapPagesCount = 0; @@ -174,7 +174,7 @@ MmCleanupMemoryManager ( UINT32 lengthMapPagesCount; MEMORY_MANAGER_CONTEXT* memoryManager; - PAGED_CODE() + PAGED_CODE(); memoryManager = &g_MemoryManager; diff --git a/Sources/MemoryManager.h b/Sources/MemoryManager.h index 9b1745b..6da7e03 100644 --- a/Sources/MemoryManager.h +++ b/Sources/MemoryManager.h @@ -3,6 +3,10 @@ @brief Functions for memory management. + @details All API in this file are prefixed with Mm because naive names + conflict with platform API, for example, AllocatePages and FreePages in + EDK2. + @author Satoshi Tanda @copyright Copyright (c) 2020 - , Satoshi Tanda. All rights reserved. diff --git a/Sources/MemoryType.h b/Sources/MemoryType.h index d8e5524..122e14e 100644 --- a/Sources/MemoryType.h +++ b/Sources/MemoryType.h @@ -9,7 +9,6 @@ */ #pragma once #include "Common.h" -#include "Ia32.h" /*! @brief Initializes the MTRR context. @@ -21,12 +20,12 @@ InitializeMemoryTypeMapping ( /*! @brief Returns a memory type for the given physical address range. - @param[in] PhysicalAddress - A physical address to retrieve its memory type. + @param[in] PhysicalAddress - The physical address to retrieve its memory type. @param[in] RangeSize - The size of the range to check. @return The memory type for the given physical address. If the range contains - more than one memory type, return MEMORY_TYPE_INVALID. + more than one memory type, MEMORY_TYPE_INVALID. */ IA32_MEMORY_TYPE GetMemoryTypeForRange ( diff --git a/Sources/MiniVisor.c b/Sources/MiniVisor.c index 14023c3..ef36ff2 100644 --- a/Sources/MiniVisor.c +++ b/Sources/MiniVisor.c @@ -164,10 +164,10 @@ typedef struct _SHARED_PROCESSOR_CONTEXT @brief Returns the VM control value that is adjusted in consideration with the VMX capability MSR. - @param[in] VmxCapabilityMsr - A VMX capability MSR to consult to adjust the + @param[in] VmxCapabilityMsr - The VMX capability MSR to consult to adjust the RequestedValue, - @param[in] RequestedValue - A VM control value that needs adjustment. + @param[in] RequestedValue - The VM control value that needs adjustment. @return The adjusted control value. */ @@ -220,7 +220,7 @@ AdjustControlValue ( @brief Adjusts a pin-based control value in consideration with the VMX capability MSR. - @param[in,out] PinBasedControls - A pointer to the pin-based control value + @param[in,out] PinBasedControls - The pointer to the pin-based control value to adjust. */ static @@ -233,9 +233,9 @@ AdjustPinBasedControls ( IA32_VMX_BASIC_REGISTER vmxBasicMsr; // - // This determine the right VMX capability MSR based on the value of + // This determines the right VMX capability MSR based on the value of // IA32_VMX_BASIC. With the right VMX capability MSR, the - // AdjustControlValue function implements the logic described under + // AdjustControlValue function implements the logic described as below. // "It is necessary for software to consult only one of the capability MSRs // to determine the allowed settings of the pin based VM-execution controls:" // See: A.3.1 Pin-Based VM-Execution Controls @@ -252,7 +252,7 @@ AdjustPinBasedControls ( @brief Adjusts a processor-based control value in consideration with the VMX capability MSR. - @param[in,out] PrimaryProcBasedControls - A pointer to the processor-based + @param[in,out] PrimaryProcBasedControls - The pointer to the processor-based control value to adjust. */ static @@ -280,7 +280,7 @@ AdjustProcessorBasedControls ( @brief Adjusts a VM-exit control value in consideration with the VMX capability MSR. - @param[in,out] VmExitControls - A pointer to the VM-exit control value to + @param[in,out] VmExitControls - The pointer to the VM-exit control value to adjust. */ static @@ -307,7 +307,7 @@ AdjustVmExitControls ( @brief Adjusts a VM-entry control value in consideration with the VMX capability MSR. - @param[in,out] VmEntryControls - A pointer to the VM-entry control value to + @param[in,out] VmEntryControls - The pointer to the VM-entry control value to adjust. */ static @@ -334,7 +334,7 @@ AdjustVmEntryControls ( @brief Adjusts a secondary processor-based control value in consideration with the VMX capability MSR. - @param[in,out] SecondaryProcBasedControls - A pointer to the secondary + @param[in,out] SecondaryProcBasedControls - The pointer to the secondary processor-based control value to adjust. */ static @@ -361,7 +361,6 @@ static _Must_inspect_result_ BOOLEAN IsMiniVisorInstalled ( - VOID ) { int registers[4]; // EAX, EBX, ECX, and EDX @@ -381,11 +380,12 @@ IsMiniVisorInstalled ( } /*! - @brief Disables hypervisor on the current processor. + @brief Disables the hypervisor on the current processor. - @param[in,out] Context - A pointer to the location to receive the address of + @param[in,out] Context - The pointer to the location to receive the address of the shared processor context. */ +MV_SECTION_PAGED static _IRQL_requires_max_(PASSIVE_LEVEL) VOID @@ -397,6 +397,8 @@ DisableHypervisor ( SHARED_PROCESSOR_CONTEXT** sharedProcessorContextsAddress; PER_PROCESSOR_CONTEXT* processorContext; + PAGED_CODE(); + if (IsMiniVisorInstalled() == FALSE) { goto Exit; @@ -404,8 +406,7 @@ DisableHypervisor ( // // Issues the hypercall to uninstall the hypervisor. This hypercall returns - // the address of the shared processor context on success. If the hypervisor - // is not installed, this (VMCALL instruction) raises #UD. + // the address of the shared processor context on success. // returnedAddress = (SHARED_PROCESSOR_CONTEXT*)AsmVmxCall(VmcallUninstall, 0, 0, 0); MV_ASSERT(returnedAddress != NULL); @@ -423,7 +424,7 @@ DisableHypervisor ( *sharedProcessorContextsAddress = returnedAddress; // - // Clean up the per-processor stuff, to be precise, EPT setup. + // Clean up the per-processor data structures. // processorContext = &(*sharedProcessorContextsAddress)->Contexts[GetCurrentProcessorNumber()]; CleanupExtendedPageTables(&processorContext->EptContext); @@ -435,19 +436,18 @@ Exit: } /*! - @brief Enables hypervisor on the all processors. + @brief Disables the hypervisor on the all processors. */ MV_SECTION_PAGED static _IRQL_requires_max_(PASSIVE_LEVEL) VOID DisableHypervisorOnAllProcessors ( - VOID ) { SHARED_PROCESSOR_CONTEXT* sharedProcessorContext; - PAGED_CODE() + PAGED_CODE(); sharedProcessorContext = NULL; RunOnAllProcessors(DisableHypervisor, &sharedProcessorContext); @@ -467,7 +467,6 @@ static _Must_inspect_result_ BOOLEAN IsVmxAvailable ( - VOID ) { BOOLEAN vmxAvailable; @@ -494,7 +493,7 @@ IsVmxAvailable ( // // Check the processor support the write-back type for VMCS. We do not // support the processor that does not support the write-back type for - // simplicity. It is not practically an issue since + // simplicity. It is practically not an issue since // "As of this writing, all processors that support VMX operation indicate // the write-back type." // @@ -529,19 +528,17 @@ IsVmxAvailable ( } // - // Check the followings to confirm availability of EPT related capabilities: - // - page walk length is 4 steps - // - extended page tables can be laid out in write-back memory - // - INVEPT instruction for global context is supported - // - INVVPID instruction for global context is supported + // Check the followings to confirm availability of EPT related capabilities. // eptVpidCapabilityMsr.Flags = __readmsr(IA32_VMX_EPT_VPID_CAP); if ((eptVpidCapabilityMsr.PageWalkLength4 == FALSE) || (eptVpidCapabilityMsr.MemoryTypeWriteBack == FALSE) || (eptVpidCapabilityMsr.Pde2MbPages == FALSE) || (eptVpidCapabilityMsr.Invept == FALSE) || + (eptVpidCapabilityMsr.InveptSingleContext == FALSE) || (eptVpidCapabilityMsr.InveptAllContexts == FALSE) || (eptVpidCapabilityMsr.Invvpid == FALSE) || + (eptVpidCapabilityMsr.InvvpidSingleContext == FALSE) || (eptVpidCapabilityMsr.InvvpidAllContexts == FALSE)) { LOG_ERROR("EPT is not supported."); @@ -562,10 +559,10 @@ Exit: See: 31.5 VMM SETUP & TEAR DOWN See: 31.6 PREPARATION AND LAUNCHING A VIRTUAL MACHINE - @param[in] SharedProcessorContext - A pointer to the shared processor context. + @param[in] SharedProcessorContext - The pointer to the shared processor context. - @param[in,out] ProcessorContext - A pointer to the per-processor context for this - processor. + @param[in,out] ProcessorContext - The pointer to the per-processor context + for this processor. @return MV_STATUS_SUCCESS on success, or an appropriate status code on error. */ @@ -618,7 +615,7 @@ SetupVmcs ( // // VMX requires TR to be configured properly (ie, non zero). This requirement - // is not already satisfied in case of EFI environment. Set it up by updating + // is not satisfied yet in case of EFI environment. Set it up by updating // GDT as necessary. // // "The selector fields for CS and TR cannot be 0000H." @@ -769,8 +766,7 @@ SetupVmcs ( // // - // Initialize EPT specific data structure, which we will referred to as the - // EPT-context. + // Initialize EPT specific data structures. // status = InitializeExtendedPageTables(&ProcessorContext->EptContext); if (MV_ERROR(status)) @@ -829,20 +825,20 @@ SetupVmcs ( // instructions. // // - MSR bitmaps are used; this is not to cause VM-exit as much as possible. - // We are setting the MSR bitmaps that are all cleared below (see code - // around the "64-Bit Control Fields" comment). This prevents VM-exits from - // occurring when 0x0 - 0x1fff and 0xc0000000 - 0xc0001fff are accessed. - // Note that VM-exit still occurs if outside the range is accessed, and it - // is not possible to prevent this. + // We are setting the MSR bitmaps that are mostly cleared below (see + // InitializeMsrBitmaps). This prevents VM-exits from occurring when + // 0x0 - 0x1fff and 0xc0000000 - 0xc0001fff are accessed. VM-exit still + // occurs if outside the range is accessed, and it is not possible to + // prevent this. // // - The secondary processor-based controls are used; this is to let the // guest (Windows) executes RDTSCP, INVPCID and the XSAVE/XRSTORS family // 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 and - // unrestricted guest which are required for the UEFI hypervisor to handle - // the real-mode guest. + // by not flushing all TLB on every VM-exit and VM-entry. Finally, enabling + // EPT and unrestricted guest which are required for the UEFI hypervisor to + // handle the real-mode guest. // primaryProcBasedControls.Flags = 0; primaryProcBasedControls.UseMsrBitmaps = TRUE; @@ -870,13 +866,20 @@ SetupVmcs ( // RPL (bits 1:0) and the TI flag (bit 2) must be 0" // See: 26.2.3 Checks on Host Segment and Descriptor-Table Registers // - VmxWrite(VMCS_HOST_ES_SELECTOR, AsmReadEs() & ~hostSegmentSelectorMask); - VmxWrite(VMCS_HOST_CS_SELECTOR, AsmReadCs() & ~hostSegmentSelectorMask); - VmxWrite(VMCS_HOST_SS_SELECTOR, AsmReadSs() & ~hostSegmentSelectorMask); - VmxWrite(VMCS_HOST_DS_SELECTOR, AsmReadDs() & ~hostSegmentSelectorMask); - VmxWrite(VMCS_HOST_FS_SELECTOR, AsmReadFs() & ~hostSegmentSelectorMask); - VmxWrite(VMCS_HOST_GS_SELECTOR, AsmReadGs() & ~hostSegmentSelectorMask); - VmxWrite(VMCS_HOST_TR_SELECTOR, AsmReadTr() & ~hostSegmentSelectorMask); + MV_ASSERT(FlagOn(AsmReadEs(), hostSegmentSelectorMask) == FALSE); + MV_ASSERT(FlagOn(AsmReadCs(), hostSegmentSelectorMask) == FALSE); + MV_ASSERT(FlagOn(AsmReadSs(), hostSegmentSelectorMask) == FALSE); + MV_ASSERT(FlagOn(AsmReadDs(), hostSegmentSelectorMask) == FALSE); + MV_ASSERT(FlagOn(AsmReadFs(), hostSegmentSelectorMask) == FALSE); + MV_ASSERT(FlagOn(AsmReadGs(), hostSegmentSelectorMask) == FALSE); + MV_ASSERT(FlagOn(AsmReadTr(), hostSegmentSelectorMask) == FALSE); + VmxWrite(VMCS_HOST_ES_SELECTOR, AsmReadEs()); + VmxWrite(VMCS_HOST_CS_SELECTOR, AsmReadCs()); + VmxWrite(VMCS_HOST_SS_SELECTOR, AsmReadSs()); + VmxWrite(VMCS_HOST_DS_SELECTOR, AsmReadDs()); + VmxWrite(VMCS_HOST_FS_SELECTOR, AsmReadFs()); + VmxWrite(VMCS_HOST_GS_SELECTOR, AsmReadGs()); + VmxWrite(VMCS_HOST_TR_SELECTOR, AsmReadTr()); /* 64-Bit Host-State Fields */ VmxWrite(VMCS_HOST_EFER, __readmsr(IA32_EFER)); @@ -1021,8 +1024,9 @@ Exit: /*! @brief Enables hypervisor on the current processor. - @param[in,out] Context - A pointer to the shared processor context. + @param[in,out] Context - The pointer to the shared processor context. */ +MV_SECTION_PAGED static _IRQL_requires_max_(PASSIVE_LEVEL) VOID @@ -1037,6 +1041,8 @@ EnableHypervisor ( UINT64 guestRip; BOOLEAN maCtxInitialized; + PAGED_CODE(); + maCtxInitialized = FALSE; sharedProcessorContext = Context; @@ -1049,7 +1055,7 @@ EnableHypervisor ( // host. // processorContext->Status = InitializeMemoryAccess(&processorContext->MemoryAccessContext, - GetHostCr3()); + GetHostCr3()); if (MV_ERROR(processorContext->Status)) { LOG_ERROR("InitializeMemoryAccess failed : %08x", processorContext->Status); @@ -1140,6 +1146,7 @@ EnableHypervisor ( vmxErrorStatus = (result == VmxResultErrorWithStatus) ? (VMX_ERROR_NUMBER)VmxRead(VMCS_VM_INSTRUCTION_ERROR) : 0; LOG_ERROR("__vmx_vmlaunch failed : %u", vmxErrorStatus); + processorContext->Status = MV_STATUS_HV_OPERATION_FAILED; CleanupExtendedPageTables(&processorContext->EptContext); __vmx_off(); @@ -1159,8 +1166,8 @@ Exit: @details This function clears the bitmaps to avoid VM-exits that do not require manual handling. The MSR that requires manual handling for MiniVisor is - IA32_BIOS_SIGN_ID to prevent the guest from attempting update BIOS - microcode. See HandleMsrAccess for more details. + IA32_BIOS_SIGN_ID for read to prevent the guest from attempting update + BIOS microcode which is not allowed. See HandleMsrAccess for more details. @param[out] Bitmaps - The pointer to the MSR bitmaps to initialize. */ @@ -1174,7 +1181,7 @@ InitializeMsrBitmaps ( static CONST UINT64 biosSignatureByteOffset = (IA32_BIOS_SIGN_ID / CHAR_BIT); static CONST UINT64 biosSignatureBitMask = (1ull << (IA32_BIOS_SIGN_ID % CHAR_BIT)); - PAGED_CODE() + PAGED_CODE(); RtlZeroMemory(Bitmaps, sizeof(*Bitmaps)); @@ -1182,7 +1189,7 @@ InitializeMsrBitmaps ( } /*! - @brief Enables hypervisor on the all processors. + @brief Enables the hypervisor on the all processors. @return MV_STATUS_SUCCESS on success; otherwise, an appropriate error code. */ @@ -1192,7 +1199,6 @@ _IRQL_requires_max_(PASSIVE_LEVEL) _Must_inspect_result_ MV_STATUS EnableHypervisorOnAllProcessors ( - VOID ) { MV_STATUS status; @@ -1201,7 +1207,7 @@ EnableHypervisorOnAllProcessors ( SHARED_PROCESSOR_CONTEXT* sharedProcessorContext; BOOLEAN virtualized; - PAGED_CODE() + PAGED_CODE(); virtualized = FALSE; @@ -1322,7 +1328,7 @@ InitializeMiniVisor ( // if (IsMiniVisorInstalled() != FALSE) { - LOG_ERROR("MiniVisor already installed"); + LOG_INFO("MiniVisor already installed"); status = MV_STATUS_HV_OPERATION_FAILED; goto Exit; } diff --git a/Sources/Platform.h b/Sources/Platform.h index 7daaa75..8783bbe 100644 --- a/Sources/Platform.h +++ b/Sources/Platform.h @@ -13,7 +13,7 @@ // // Spin lock type and state names. // -#if defined(NTDDI_VERSION) +#if defined(MV_PLATFORM_WINDOWS) typedef volatile LONG64 SPIN_LOCK; typedef enum _SPIN_LOCK_STATE { @@ -81,7 +81,7 @@ GetCurrentProcessorNumber ( /*! @brief Returns the physical address of the given virtual address. - @param[in] VirualAddress - A virtual address to retrieve its physical + @param[in] VirualAddress - The virtual address to retrieve its physical address for the current CR3. This must be non paged pool, otherwise the result is undefined. diff --git a/Sources/Platform/EFI/EfiAsm.asm b/Sources/Platform/EFI/EfiAsm.asm index c7110da..d0e3928 100644 --- a/Sources/Platform/EFI/EfiAsm.asm +++ b/Sources/Platform/EFI/EfiAsm.asm @@ -25,7 +25,10 @@ Index = 0 ; Index is incremented whenever this macro is used. ; INTERRUPT_HANDLER macro InterruptNumber - push 0 ; Push dummy error code for consistent stack layout. + ; + ; Push dummy error code for consistent stack layout. + ; + push 0 push InterruptNumber jmp AsmCommonExceptionHandler Index = Index + 1 @@ -38,7 +41,10 @@ endm ; Index is incremented whenever this macro is used. ; INTERRUPT_HANDLER_WITH_CODE macro InterruptNumber - nop ; Error code is expected to be pushed by the processor. + ; + ; Error code is expected to be pushed by the processor. + ; + nop nop push InterruptNumber jmp AsmCommonExceptionHandler @@ -53,26 +59,44 @@ endm ; works as a hendler of the corresponding interrupt/exception in the host. ; AsmDefaultExceptionHandlers proc - repeat 8 - INTERRUPT_HANDLER Index ; INT0-7 - endm + ; + ; INT0-7 + ; + repeat 8 + INTERRUPT_HANDLER Index + endm - INTERRUPT_HANDLER_WITH_CODE Index ; INT8 - INTERRUPT_HANDLER Index ; INT9 + ; + ; INT8, INT9 + ; + INTERRUPT_HANDLER_WITH_CODE Index + INTERRUPT_HANDLER Index - repeat 5 - INTERRUPT_HANDLER_WITH_CODE Index ; INT10-14 - endm + ; + ; INT10-14 + ; + repeat 5 + INTERRUPT_HANDLER_WITH_CODE Index + endm - repeat 2 - INTERRUPT_HANDLER Index ; INT15-16 - endm + ; + ; INT15-16 + ; + repeat 2 + INTERRUPT_HANDLER Index + endm - INTERRUPT_HANDLER_WITH_CODE Index ; INT17 + ; + ; INT17 + ; + INTERRUPT_HANDLER_WITH_CODE Index - repeat 238 - INTERRUPT_HANDLER Index ; INT18-255 - endm + ; + ; INT18-255 + ; + repeat 238 + INTERRUPT_HANDLER Index + endm AsmDefaultExceptionHandlers endp ; @@ -88,7 +112,11 @@ AsmCommonExceptionHandler proc call HandleHostException add rsp, 20h POPAQ - add rsp, 10h ; Remove the error code and interrupt number. + + ; + ; Remove the error code and interrupt number. + ; + add rsp, 10h iretq AsmCommonExceptionHandler endp diff --git a/Sources/Platform/EFI/EfiAsm.h b/Sources/Platform/EFI/EfiAsm.h index e650a9f..cfd9b65 100644 --- a/Sources/Platform/EFI/EfiAsm.h +++ b/Sources/Platform/EFI/EfiAsm.h @@ -15,7 +15,6 @@ */ VOID AsmDefaultExceptionHandlers ( - VOID ); /*! @@ -23,5 +22,4 @@ AsmDefaultExceptionHandlers ( */ VOID AsmNmiExceptionHandler ( - VOID ); diff --git a/Sources/Platform/EFI/EfiBitmap.c b/Sources/Platform/EFI/EfiBitmap.c index de89f54..6ffc4ba 100644 --- a/Sources/Platform/EFI/EfiBitmap.c +++ b/Sources/Platform/EFI/EfiBitmap.c @@ -8,9 +8,9 @@ reused once they are set, even after they are "cleared". For complete implementation, one can copy ReactOS's implementation if - licensing the project under GPL is acceptable. hvpp by wbenny has its own - implementation of bitmap but is actually influenced by ReactOS - implementation and such should be treated as GPL. + licensing the project under GPL is acceptable. hvpp by Petr Beneš has its + own implementation of bitmap but is actually influenced by ReactOS + implementation, and such, should be treated as GPL. @author Satoshi Tanda diff --git a/Sources/Platform/EFI/EfiCommon.h b/Sources/Platform/EFI/EfiCommon.h index 31e9861..47ece16 100644 --- a/Sources/Platform/EFI/EfiCommon.h +++ b/Sources/Platform/EFI/EfiCommon.h @@ -34,21 +34,21 @@ fault (null pointer access) when it fires in the host code. The author has not been able to find out the root cause and a fix. */ -#if !defined(MDEPKG_NDEBUG) +#if defined(MDEPKG_NDEBUG) +#define MV_ASSERT(x) +#else #define MV_ASSERT(x) \ if (!(x)) \ { \ LOG_ERROR("ASSERT %a(%d): %a", __FILE__, __LINE__, #x); \ MV_PANIC(); \ } (VOID*)NULL -#else -#define MV_ASSERT(x) #endif -#if !defined(MDEPKG_NDEBUG) -#define MV_VERIFY(x) MV_ASSERT(x) -#else +#if defined(MDEPKG_NDEBUG) #define MV_VERIFY(x) (x) +#else +#define MV_VERIFY(x) MV_ASSERT(x) #endif #define MV_MAX(x, y) MAX((x), (y)) diff --git a/Sources/Platform/Windows/WinAsm.asm b/Sources/Platform/Windows/WinAsm.asm index 6cbbd1a..5e4f3fd 100644 --- a/Sources/Platform/Windows/WinAsm.asm +++ b/Sources/Platform/Windows/WinAsm.asm @@ -10,7 +10,7 @@ .code ; -; @brief Read the value from LDTR. +; @brief Reads the value of LDTR. ; ; @return The value of LDTR. ; @@ -20,7 +20,7 @@ AsmReadLdtr proc AsmReadLdtr endp ; -; @brief Read the value from TR. +; @brief Reads the value of TR. ; ; @return The value of TR. ; @@ -30,7 +30,7 @@ AsmReadTr proc AsmReadTr endp ; -; @brief Read the value from ES. +; @brief Reads the value of ES. ; ; @return The value of ES. ; @@ -40,7 +40,7 @@ AsmReadEs proc AsmReadEs endp ; -; @brief Read the value from CS. +; @brief Reads the value of CS. ; ; @return The value of CS. ; @@ -50,7 +50,7 @@ AsmReadCs proc AsmReadCs endp ; -; @brief Read the value from SS. +; @brief Reads the value of SS. ; ; @return The value of SS. ; @@ -60,7 +60,7 @@ AsmReadSs proc AsmReadSs endp ; -; @brief Read the value from DS. +; @brief Reads the value of DS. ; ; @return The value of DS. ; @@ -70,7 +70,7 @@ AsmReadDs proc AsmReadDs endp ; -; @brief Read the value from FS. +; @brief Reads the value of FS. ; ; @return The value of FS. ; @@ -80,7 +80,7 @@ AsmReadFs proc AsmReadFs endp ; -; @brief Read the value from GS. +; @brief Reads the value of GS. ; ; @return The value of GS. ; @@ -90,7 +90,7 @@ AsmReadGs proc AsmReadGs endp ; -; @brief Write the value to TR. +; @brief Writes the value to TR. ; ; @param[in] RCX - The new TR value to write. ; diff --git a/Sources/Platform/Windows/WinAsm.h b/Sources/Platform/Windows/WinAsm.h index 5606eae..7ccd922 100644 --- a/Sources/Platform/Windows/WinAsm.h +++ b/Sources/Platform/Windows/WinAsm.h @@ -17,7 +17,6 @@ */ UINT16 AsmReadLdtr ( - VOID ); /*! @@ -27,7 +26,6 @@ AsmReadLdtr ( */ UINT16 AsmReadTr ( - VOID ); /*! @@ -37,7 +35,6 @@ AsmReadTr ( */ UINT16 AsmReadEs ( - VOID ); /*! @@ -47,7 +44,6 @@ AsmReadEs ( */ UINT16 AsmReadCs ( - VOID ); /*! @@ -57,7 +53,6 @@ AsmReadCs ( */ UINT16 AsmReadSs ( - VOID ); /*! @@ -67,7 +62,6 @@ AsmReadSs ( */ UINT16 AsmReadDs ( - VOID ); /*! @@ -77,7 +71,6 @@ AsmReadDs ( */ UINT16 AsmReadFs ( - VOID ); /*! @@ -87,7 +80,6 @@ AsmReadFs ( */ UINT16 AsmReadGs ( - VOID ); /*! diff --git a/Sources/Platform/Windows/WinLogger.c b/Sources/Platform/Windows/WinLogger.c index c91b047..2637e90 100644 --- a/Sources/Platform/Windows/WinLogger.c +++ b/Sources/Platform/Windows/WinLogger.c @@ -457,7 +457,7 @@ LogFlushThread ( LOGGER_CONTEXT* logger; LARGE_INTEGER interval; - PAGED_CODE() + PAGED_CODE(); logger = (LOGGER_CONTEXT*)StartContext; interval.QuadPart = -(10000ll * logger->FlushIntervalInMs); @@ -562,13 +562,6 @@ CleanupPairedLogBuffer ( ExFreePoolWithTag(PairedLogBuffer->InactiveLogBuffer->LogEntries, LOGGER_POOL_TAG); } -/*! - @brief Initializes the global logger. - - @param[in] Configuration - The configuration for initialization. - - @return STATUS_SUCCESS on success; otherwise, an appropriate error code. - */ LOGGER_INIT _Use_decl_annotations_ NTSTATUS @@ -581,7 +574,7 @@ InitializeLogger ( HANDLE fileHandle; HANDLE threadHandle; - PAGED_CODE() + PAGED_CODE(); MV_ASSERT(g_Logger == NULL); @@ -615,7 +608,7 @@ InitializeLogger ( &filePath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, - NULL) + NULL); status = ZwCreateFile(&fileHandle, FILE_APPEND_DATA | SYNCHRONIZE, &objectAttributes, @@ -709,7 +702,6 @@ InitializeLogger ( // g_Logger = logger; - Exit: if (NT_ERROR(status)) { @@ -729,9 +721,6 @@ Exit: return status; } -/*! - @brief Clean up the logger. - */ LOGGER_PAGED _Use_decl_annotations_ VOID @@ -742,7 +731,7 @@ CleanupLogger ( LOGGER_CONTEXT* logger; SIZE_T maxOverflowedLogSize; - PAGED_CODE() + PAGED_CODE(); MV_ASSERT(g_Logger != NULL); diff --git a/Sources/Platform/Windows/WinLogger.h b/Sources/Platform/Windows/WinLogger.h index bf936f3..a2df6b6 100644 --- a/Sources/Platform/Windows/WinLogger.h +++ b/Sources/Platform/Windows/WinLogger.h @@ -69,6 +69,13 @@ typedef struct _LOGGER_CONFIGURATION PCWSTR FilePath; } LOGGER_CONFIGURATION; +/*! + @brief Initializes the global logger. + + @param[in] Configuration - The configuration for initialization. + + @return STATUS_SUCCESS on success; otherwise, an appropriate error code. + */ _IRQL_requires_max_(PASSIVE_LEVEL) _Must_inspect_result_ NTSTATUS @@ -76,6 +83,9 @@ InitializeLogger ( _In_ CONST LOGGER_CONFIGURATION* Configuration ); +/*! + @brief Clean up the logger. + */ _IRQL_requires_max_(PASSIVE_LEVEL) VOID CleanupLogger ( diff --git a/Sources/Platform/Windows/WinPlatform.c b/Sources/Platform/Windows/WinPlatform.c index 4158aa7..173814e 100644 --- a/Sources/Platform/Windows/WinPlatform.c +++ b/Sources/Platform/Windows/WinPlatform.c @@ -97,7 +97,7 @@ ConvertNtToMvStatus ( @param[in] DriverObject - The driver's driver object. - @param[in] RegistryPath - A path to the driver's registry key. + @param[in] RegistryPath - The path to the driver's registry key. @return STATUS_SUCCESS on success; otherwise, an appropriate error code. */ @@ -148,7 +148,7 @@ DriverUnload ( { UNREFERENCED_PARAMETER(DriverObject); - PAGED_CODE() + PAGED_CODE(); // // Start cross-platform clean up. @@ -165,7 +165,7 @@ InitializePlatform ( NTSTATUS status; LOGGER_CONFIGURATION loggerConfig; - PAGED_CODE() + PAGED_CODE(); // // Initialize in-house logger. Enable all flags. @@ -192,7 +192,7 @@ VOID CleanupPlatform ( ) { - PAGED_CODE() + PAGED_CODE(); CleanupLogger(); } @@ -206,7 +206,7 @@ Sleep ( { LARGE_INTEGER interval; - PAGED_CODE() + PAGED_CODE(); interval.QuadPart = -(LONGLONG)(10000 * Milliseconds); (VOID)KeDelayExecutionThread(KernelMode, FALSE, &interval); @@ -296,7 +296,7 @@ ReserveVirtualAddress ( UINT64 PageCount ) { - PAGED_CODE() + PAGED_CODE(); return MmAllocateMappingAddress(PageCount * PAGE_SIZE, MV_POOL_TAG); } @@ -309,7 +309,7 @@ FreeReservedVirtualAddress ( UINT64 PageCount ) { - PAGED_CODE() + PAGED_CODE(); UNREFERENCED_PARAMETER(PageCount); @@ -326,7 +326,7 @@ RunOnAllProcessors ( { UINT32 numberOfProcessors; - PAGED_CODE() + PAGED_CODE(); numberOfProcessors = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); for (UINT32 index = 0; index < numberOfProcessors; ++index) diff --git a/Sources/Public.h b/Sources/Public.h index 6f1a1cc..c611b53 100644 --- a/Sources/Public.h +++ b/Sources/Public.h @@ -1,7 +1,7 @@ /*! @file Public.h - @brief Interfaces to communicate with our hypervisor. + @brief Interfaces to communicate with the hypervisor. @author Satoshi Tanda diff --git a/Sources/Utils.c b/Sources/Utils.c index 90cfdd9..43ebea2 100644 --- a/Sources/Utils.c +++ b/Sources/Utils.c @@ -1,8 +1,7 @@ /*! @file Utils.c - @brief Utility functions that could be used by both on root and non-root - operations. + @brief Utility functions that could be used by both the host and non-host. @author Satoshi Tanda @@ -75,10 +74,10 @@ Exit: /*! @brief Returns the segment descriptor corresponds to the SegmentSelector. - @param[in] DescriptorTableBase - An address of the base of the descriptor + @param[in] DescriptorTableBase - The address of the base of the descriptor table. - @param[in] SegmentSelector - A segment selector value. + @param[in] SegmentSelector - The segment selector value. @return The segment descriptor corresponds to the SegmentSelector. */ diff --git a/Sources/Utils.h b/Sources/Utils.h index 2700bd7..56709ed 100644 --- a/Sources/Utils.h +++ b/Sources/Utils.h @@ -1,8 +1,7 @@ /*! @file Utils.h - @brief Utility functions that could be used by both on root and non-root - operations. + @brief Utility functions that could be used by both the host and non-host. @author Satoshi Tanda @@ -36,7 +35,7 @@ ComputeAddressFromIndexes ( @brief Returns the access right of the segment specified by the SegmentSelector for VMX. - @param[in] SegmentSelector - A segment selector value. + @param[in] SegmentSelector - The segment selector value. @return The access right of the segment for VMX. */ @@ -48,7 +47,7 @@ GetSegmentAccessRight ( /*! @brief Returns the base address of the segment specified by SegmentSelector. - @param[in] DescriptorTableBase - An address of the base of the descriptor + @param[in] DescriptorTableBase - The address of the base of the descriptor table. @param[in] SegmentSelector - The segment selector which points to the