diff --git a/CMakeLists.txt b/CMakeLists.txt index e37013d..339049b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,10 @@ 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 44c49b2..0748654 100644 --- a/src/driver/hypervisor.cpp +++ b/src/driver/hypervisor.cpp @@ -1,5 +1,8 @@ #include "std_include.hpp" #include "hypervisor.hpp" + +#include + #include "exception.hpp" #include "logging.hpp" #include "finally.hpp" @@ -33,6 +36,34 @@ namespace { return is_vmx_supported() && is_vmx_available(); } + + _IRQL_requires_max_(DISPATCH_LEVEL) + + void free_aligned_memory(void* memory) + { + MmFreeContiguousMemory(memory); + } + + _Must_inspect_result_ + _IRQL_requires_max_(DISPATCH_LEVEL) + + void* allocate_aligned_memory(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 + } } hypervisor::hypervisor() @@ -70,10 +101,14 @@ void hypervisor::disable() { this->disable_core(); }); + + this->free_vm_states(); } void hypervisor::enable() { + this->allocate_vm_states(); + thread::dispatch_on_all_cores([this]() { this->enable_core(); @@ -82,8 +117,39 @@ void hypervisor::enable() void hypervisor::enable_core() { + auto* vm_state = this->get_current_vm_state(); } void hypervisor::disable_core() { + auto* vm_state = this->get_current_vm_state(); +} + +void hypervisor::allocate_vm_states() +{ + const auto core_count = thread::get_processor_count(); + const auto allocation_size = sizeof(vmx::vm_state) * core_count; + + this->vm_states_ = static_cast(allocate_aligned_memory(allocation_size)); + if(!this->vm_states_) + { + throw std::runtime_error("Failed to allocate vm states"); + } +} + +void hypervisor::free_vm_states() +{ + if(this->vm_states_) + { + free_aligned_memory(this->vm_states_); + this->vm_states_ = nullptr; + } +} + +vmx::vm_state* hypervisor::get_current_vm_state() const +{ + const auto current_core = thread::get_processor_index(); + + assert(this->vm_states_); + return &this->vm_states_[current_core]; } diff --git a/src/driver/hypervisor.hpp b/src/driver/hypervisor.hpp index 3c684ea..be5388a 100644 --- a/src/driver/hypervisor.hpp +++ b/src/driver/hypervisor.hpp @@ -18,6 +18,13 @@ public: void disable(); private: + vmx::vm_state* vm_states_{nullptr}; + void enable_core(); void disable_core(); + + void allocate_vm_states(); + void free_vm_states(); + + vmx::vm_state* get_current_vm_state() const; }; diff --git a/src/driver/thread.cpp b/src/driver/thread.cpp index a9e8492..0639d33 100644 --- a/src/driver/thread.cpp +++ b/src/driver/thread.cpp @@ -1,5 +1,7 @@ #include "thread.hpp" #include "std_include.hpp" +#include "logging.hpp" +#include "exception.hpp" namespace thread { @@ -19,8 +21,19 @@ namespace thread const PVOID arg1, const PVOID arg2) { - auto* const data = static_cast(param); - data->callback(data->data); + try + { + const auto* const data = static_cast(param); + data->callback(data->data); + } + catch (std::exception& e) + { + debug_log("Exception during dpc on core %d: %s\n", get_processor_index(), e.what()); + } + catch (...) + { + debug_log("Unknown exception during dpc on core %d\n", get_processor_index()); + } KeSignalCallDpcSynchronize(arg2); KeSignalCallDpcDone(arg1);