From 2c48c4b595629352de8c50fb8d2e658e316434ef Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 27 Mar 2022 12:31:13 +0200 Subject: [PATCH] Add win7 compatibility --- CMakeLists.txt | 4 --- src/driver/hypervisor.cpp | 33 ++++++++++++++++++++++--- src/driver/hypervisor.hpp | 3 ++- src/driver/irp.cpp | 12 +++------ src/driver/memory.cpp | 52 +++++++++++++++++++++++++++++++-------- src/driver/memory.hpp | 3 +++ src/driver/nt_ext.hpp | 15 +++++++++++ src/driver/string.cpp | 14 +++++++++++ src/driver/string.hpp | 7 ++++++ 9 files changed, 116 insertions(+), 27 deletions(-) create mode 100644 src/driver/string.cpp create mode 100644 src/driver/string.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 339049b..e37013d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,10 +14,6 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON) ########################################## -set(WDK_WINVER "0x0602" CACHE STRING "Default WINVER for WDK targets") - -########################################## - set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>) if(MSVC) diff --git a/src/driver/hypervisor.cpp b/src/driver/hypervisor.cpp index e70f96b..97b9387 100644 --- a/src/driver/hypervisor.cpp +++ b/src/driver/hypervisor.cpp @@ -80,15 +80,42 @@ void hypervisor::enable() { this->allocate_vm_states(); - thread::dispatch_on_all_cores([this]() + const auto cr3 = __readcr3(); + + bool success = true; + thread::dispatch_on_all_cores([&]() { - this->enable_core(); + success &= this->try_enable_core(cr3); }); + + if (!success) + { + this->disable(); + } } -void hypervisor::enable_core() +bool hypervisor::try_enable_core(const uint64_t cr3) +{ + try + { + this->enable_core(cr3); + return true; + } + catch (std::exception& e) + { + debug_log("Failed to enable hypervisor on core %d: %s\n", thread::get_processor_index(), e.what()); + return false; + }catch (...) + { + debug_log("Failed to enable hypervisor on core %d.\n", thread::get_processor_index()); + return false; + } +} + +void hypervisor::enable_core(uint64_t /*cr3*/) { auto* vm_state = this->get_current_vm_state(); + throw std::runtime_error("Not implemented!"); } void hypervisor::disable_core() diff --git a/src/driver/hypervisor.hpp b/src/driver/hypervisor.hpp index be5388a..43c47dd 100644 --- a/src/driver/hypervisor.hpp +++ b/src/driver/hypervisor.hpp @@ -20,7 +20,8 @@ public: private: vmx::vm_state* vm_states_{nullptr}; - void enable_core(); + void enable_core(uint64_t cr3); + bool try_enable_core(uint64_t cr3); void disable_core(); void allocate_vm_states(); diff --git a/src/driver/irp.cpp b/src/driver/irp.cpp index 0bbec9b..b51e868 100644 --- a/src/driver/irp.cpp +++ b/src/driver/irp.cpp @@ -2,18 +2,12 @@ #include "finally.hpp" #include "logging.hpp" #include "exception.hpp" +#include "string.hpp" #define HELLO_DRV_IOCTL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS) namespace { - UNICODE_STRING get_unicode_string(const wchar_t* string) - { - UNICODE_STRING unicode_string{}; - RtlInitUnicodeString(&unicode_string, string); - return unicode_string; - } - _Function_class_(DRIVER_DISPATCH) NTSTATUS not_supported_handler(PDEVICE_OBJECT /*device_object*/, const PIRP irp) { PAGED_CODE() @@ -74,8 +68,8 @@ irp::irp(const PDRIVER_OBJECT driver_object, const wchar_t* device_name, const w { PAGED_CODE() - this->device_name_ = get_unicode_string(device_name); - this->dos_device_name_ = get_unicode_string(dos_device_name); + this->device_name_ = string::get_unicode_string(device_name); + this->dos_device_name_ = string::get_unicode_string(dos_device_name); auto destructor = utils::finally([this]() { diff --git a/src/driver/memory.cpp b/src/driver/memory.cpp index b8bc8f6..82a9a17 100644 --- a/src/driver/memory.cpp +++ b/src/driver/memory.cpp @@ -1,26 +1,46 @@ #include "std_include.hpp" #include "memory.hpp" +#include "string.hpp" namespace memory { namespace { + using mm_allocate_contiguous_node_memory = decltype(MmAllocateContiguousNodeMemory)*; + + mm_allocate_contiguous_node_memory get_mm_allocate_contiguous_node_memory() + { + static bool fetched{false}; + static mm_allocate_contiguous_node_memory address{nullptr}; + + if (!fetched) + { + fetched = true; + auto function_name = string::get_unicode_string(L"MmAllocateContiguousNodeMemory"); + address = static_cast(MmGetSystemRoutineAddress(&function_name)); + } + + return address; + } + void* allocate_aligned_memory_internal(const size_t size) { PHYSICAL_ADDRESS lowest{}, highest{}; lowest.QuadPart = 0; highest.QuadPart = lowest.QuadPart - 1; -#if (NTDDI_VERSION >= NTDDI_VISTA) - return MmAllocateContiguousNodeMemory(size, - lowest, - highest, - lowest, - PAGE_READWRITE, - KeGetCurrentNodeNumber()); -#else - return MmAllocateContiguousMemory(size, highest); -#endif + const auto allocate_node_mem = get_mm_allocate_contiguous_node_memory(); + if (allocate_node_mem) + { + return allocate_node_mem(size, + lowest, + highest, + lowest, + PAGE_READWRITE, + KeGetCurrentNodeNumber()); + } + + return MmAllocateContiguousMemory(size, highest); } } @@ -48,6 +68,18 @@ namespace memory return memory; } + void* get_physical_address(void* address) + { + return reinterpret_cast(MmGetPhysicalAddress(address).QuadPart); + } + + void* get_virtual_address(void* address) + { + PHYSICAL_ADDRESS physical_address{}; + physical_address.QuadPart = reinterpret_cast(address); + return MmGetVirtualForPhysical(physical_address); + } + _Must_inspect_result_ _IRQL_requires_max_(DISPATCH_LEVEL) diff --git a/src/driver/memory.hpp b/src/driver/memory.hpp index dda4acd..0d28a27 100644 --- a/src/driver/memory.hpp +++ b/src/driver/memory.hpp @@ -9,6 +9,9 @@ namespace memory _IRQL_requires_max_(DISPATCH_LEVEL) void* allocate_aligned_memory(size_t size); + void* get_physical_address(void* address); + void* get_virtual_address(void* address); + _Must_inspect_result_ _IRQL_requires_max_(DISPATCH_LEVEL) void* allocate_non_paged_memory(size_t size); diff --git a/src/driver/nt_ext.hpp b/src/driver/nt_ext.hpp index 355eac5..1f01899 100644 --- a/src/driver/nt_ext.hpp +++ b/src/driver/nt_ext.hpp @@ -31,6 +31,21 @@ KeSignalCallDpcSynchronize( _In_ PVOID SystemArgument2 ); +#if (NTDDI_VERSION < NTDDI_WIN8) +_Must_inspect_result_ +_IRQL_requires_max_(DISPATCH_LEVEL) +NTKERNELAPI +_When_ (return != NULL, _Post_writable_byte_size_ (NumberOfBytes)) PVOID +MmAllocateContiguousNodeMemory ( + _In_ SIZE_T NumberOfBytes, + _In_ PHYSICAL_ADDRESS LowestAcceptableAddress, + _In_ PHYSICAL_ADDRESS HighestAcceptableAddress, + _In_opt_ PHYSICAL_ADDRESS BoundaryAddressMultiple, + _In_ ULONG Protect, + _In_ NODE_REQUIREMENT PreferredNode + ); +#endif + #ifdef __cplusplus } #endif diff --git a/src/driver/string.cpp b/src/driver/string.cpp new file mode 100644 index 0000000..de1d59e --- /dev/null +++ b/src/driver/string.cpp @@ -0,0 +1,14 @@ +#include "std_include.hpp" +#include "string.hpp" + +namespace string +{ + _IRQL_requires_max_(DISPATCH_LEVEL) + + UNICODE_STRING get_unicode_string(const wchar_t* string) + { + UNICODE_STRING unicode_string{}; + RtlInitUnicodeString(&unicode_string, string); + return unicode_string; + } +} diff --git a/src/driver/string.hpp b/src/driver/string.hpp new file mode 100644 index 0000000..985c768 --- /dev/null +++ b/src/driver/string.hpp @@ -0,0 +1,7 @@ +#pragma once + +namespace string +{ + _IRQL_requires_max_(DISPATCH_LEVEL) + UNICODE_STRING get_unicode_string(const wchar_t* string); +}