diff --git a/src/driver/driver_main.cpp b/src/driver/driver_main.cpp index f45766f..f5c944d 100644 --- a/src/driver/driver_main.cpp +++ b/src/driver/driver_main.cpp @@ -24,7 +24,6 @@ public: ~global_driver() { debug_log("Unloading driver\n"); - this->hypervisor_.disable_all_ept_hooks(); } global_driver(global_driver&&) noexcept = delete; @@ -70,7 +69,10 @@ _Function_class_(DRIVER_UNLOAD) void unload(const PDRIVER_OBJECT driver_object) { global_driver_instance->pre_destroy(driver_object); delete global_driver_instance; + global_driver_instance = nullptr; } + + globals::run_destructors(); } catch (std::exception& e) { @@ -87,6 +89,7 @@ extern "C" NTSTATUS DriverEntry(const PDRIVER_OBJECT driver_object, PUNICODE_STR try { driver_object->DriverUnload = unload; + globals::run_constructors(); global_driver_instance = new global_driver(driver_object); } catch (std::exception& e) diff --git a/src/driver/globals.cpp b/src/driver/globals.cpp new file mode 100644 index 0000000..bfccd3b --- /dev/null +++ b/src/driver/globals.cpp @@ -0,0 +1,126 @@ +#include "std_include.hpp" +#include "list.hpp" +#include "globals.hpp" + +#include "logging.hpp" + +#define _CRTALLOC(x) __declspec(allocate(x)) + +typedef void (__cdecl* _PVFV)(void); +typedef int (__cdecl* _PIFV)(void); + +#pragma section(".CRT$XIA", long, read) // First C Initializer +#pragma section(".CRT$XIZ", long, read) // Last C Initializer + +#pragma section(".CRT$XTA", long, read) // First Terminator +#pragma section(".CRT$XTZ", long, read) // Last Terminator + +#pragma section(".CRT$XCA", long, read) // First C++ Initializer +#pragma section(".CRT$XCZ", long, read) // Last C++ Initializer + +#pragma section(".CRT$XPA", long, read) // First Pre-Terminator +#pragma section(".CRT$XPZ", long, read) // Last Pre-Terminator + +extern "C" _CRTALLOC(".CRT$XIA") _PIFV __xi_a[] = {nullptr}; // C initializers (first) +extern "C" _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[] = {nullptr}; // C initializers (last) +extern "C" _CRTALLOC(".CRT$XCA") _PVFV __xc_a[] = {nullptr}; // C++ initializers (first) +extern "C" _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[] = {nullptr}; // C++ initializers (last) +extern "C" _CRTALLOC(".CRT$XPA") _PVFV __xp_a[] = {nullptr}; // C pre-terminators (first) +extern "C" _CRTALLOC(".CRT$XPZ") _PVFV __xp_z[] = {nullptr}; // C pre-terminators (last) +extern "C" _CRTALLOC(".CRT$XTA") _PVFV __xt_a[] = {nullptr}; // C terminators (first) +extern "C" _CRTALLOC(".CRT$XTZ") _PVFV __xt_z[] = {nullptr}; // C terminators (last) + +namespace globals +{ + namespace + { + using destructor = void(*)(); + using destructor_list = utils::list; + + destructor_list* destructors = nullptr; + + int run_callbacks(_PIFV* begin, const _PIFV* end) + { + int ret = 0; + + while (begin < end && ret == 0) + { + if (*begin) + { + ret = (**begin)(); + } + ++begin; + } + + return ret; + } + + void run_callbacks(_PVFV* begin, const _PVFV* end) + { + while (begin < end) + { + if (*begin) + { + (**begin)(); + } + ++begin; + } + } + } + + void run_constructors() + { + if (!destructors) + { + destructors = new destructor_list(); + } + + run_callbacks(__xp_a, __xp_z); + run_callbacks(__xc_a, __xc_z); + } + + void run_destructors() + { + if (!destructors) + { + return; + } + + run_callbacks(__xi_a, __xi_z); + run_callbacks(__xt_a, __xt_z); + + for (auto* destructor : *destructors) + { + try + { + destructor(); + } + catch (const std::exception& e) + { + debug_log("Running destructor failed: %s\n", e.what()); + } + } + + delete destructors; + destructors = nullptr; + } +} + +int atexit(const globals::destructor destructor) +{ + if (!globals::destructors) + { + return 1; + } + + try + { + globals::destructors->push_back(destructor); + } + catch (const std::exception& e) + { + debug_log("Registering destructor failed: %s\n", e.what()); + } + + return 0; +} diff --git a/src/driver/globals.hpp b/src/driver/globals.hpp new file mode 100644 index 0000000..8273ab8 --- /dev/null +++ b/src/driver/globals.hpp @@ -0,0 +1,7 @@ +#pragma once + +namespace globals +{ + void run_constructors(); + void run_destructors(); +} diff --git a/src/driver/hypervisor.cpp b/src/driver/hypervisor.cpp index 88318df..23ce220 100644 --- a/src/driver/hypervisor.cpp +++ b/src/driver/hypervisor.cpp @@ -142,6 +142,7 @@ hypervisor::hypervisor() hypervisor::~hypervisor() { + this->disable_all_ept_hooks(); this->disable(); this->free_vm_states(); instance = nullptr;