From 97d6ccc0120d6f73511dbfb02a4cb5e8bce0ca39 Mon Sep 17 00:00:00 2001 From: Satoshi Tanda Date: Sat, 31 Mar 2018 19:01:48 -0700 Subject: [PATCH] Fix #52; use kernel-mode CR3 --- HyperPlatform/log.cpp | 2 +- HyperPlatform/vmm.cpp | 30 ++++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/HyperPlatform/log.cpp b/HyperPlatform/log.cpp index 276d05e..8613664 100644 --- a/HyperPlatform/log.cpp +++ b/HyperPlatform/log.cpp @@ -317,7 +317,7 @@ _Use_decl_annotations_ VOID static LogpReinitializationRoutine( UNREFERENCED_PARAMETER(driver_object); UNREFERENCED_PARAMETER(count); NT_ASSERT(context); - __analysis_assume(context); + _Analysis_assume_(context); auto info = reinterpret_cast(context); auto status = LogpInitializeLogFile(info); diff --git a/HyperPlatform/vmm.cpp b/HyperPlatform/vmm.cpp index a69ca64..6a8f1cd 100644 --- a/HyperPlatform/vmm.cpp +++ b/HyperPlatform/vmm.cpp @@ -158,6 +158,8 @@ static void VmmpInjectInterruption(_In_ InterruptionType interruption_type, _In_ bool deliver_error_code, _In_ ULONG32 error_code); +static ULONG_PTR VmmpGetKernelCr3(); + //////////////////////////////////////////////////////////////////////////////// // // variables @@ -617,7 +619,7 @@ _Use_decl_annotations_ static void VmmpHandleGdtrOrIdtrAccess( // Update CR3 with that of the guest since below code is going to access // memory. - const auto guest_cr3 = UtilVmRead(VmcsField::kGuestCr3); + const auto guest_cr3 = VmmpGetKernelCr3(); const auto vmm_cr3 = __readcr3(); __writecr3(guest_cr3); @@ -720,7 +722,7 @@ _Use_decl_annotations_ static void VmmpHandleLdtrOrTrAccess( // Update CR3 with that of the guest since below code is going to access // memory. - const auto guest_cr3 = UtilVmRead(VmcsField::kGuestCr3); + const auto guest_cr3 = VmmpGetKernelCr3(); const auto vmm_cr3 = __readcr3(); __writecr3(guest_cr3); @@ -746,7 +748,7 @@ _Use_decl_annotations_ static void VmmpHandleLdtrOrTrAccess( const auto sd = reinterpret_cast( UtilVmRead(VmcsField::kGuestGdtrBase) + ss.fields.index * sizeof(SegmentDescriptor)); - sd->fields.type |= 2; // Set the Busy bit + sd->fields.type |= 2; // Set the Busy bit break; } } @@ -879,7 +881,7 @@ _Use_decl_annotations_ static void VmmpIoWrapper(bool to_memory, bool is_string, // Update CR3 with that of the guest since below code is going to access // memory. - const auto guest_cr3 = UtilVmRead(VmcsField::kGuestCr3); + const auto guest_cr3 = VmmpGetKernelCr3(); const auto vmm_cr3 = __readcr3(); __writecr3(guest_cr3); @@ -1340,4 +1342,24 @@ _Use_decl_annotations_ static void VmmpInjectInterruption( } } +// Returns a kernel CR3 value of the current process; +/*_Use_decl_annotations_*/ static ULONG_PTR VmmpGetKernelCr3() { + auto guest_cr3 = UtilVmRead(VmcsField::kGuestCr3); + // Assume it is an user-mode CR3 when the lowest bit is set. If so, get CR3 + // from _KPROCESS::DirectoryTableBase. + if (guest_cr3 & 1) { + static const long kDirectoryTableBaseOffsetX64 = 0x28; + static const long kDirectoryTableBaseOffsetX86 = 0x18; + auto process = reinterpret_cast(PsGetCurrentProcess()); + if (IsX64()) { + guest_cr3 = + *reinterpret_cast(process + kDirectoryTableBaseOffsetX64); + } else { + guest_cr3 = + *reinterpret_cast(process + kDirectoryTableBaseOffsetX86); + } + } + return guest_cr3; +} + } // extern "C"