More cleanup and hypervisor progress

This commit is contained in:
momo5502 2022-03-27 10:48:24 +02:00
parent 6ce3597bd3
commit 8fcaaf5cbf
22 changed files with 324 additions and 60 deletions

View File

@ -5,7 +5,7 @@ file(GLOB driver_headers ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp)
wdk_add_driver(driver wdk_add_driver(driver
${driver_sources} ${driver_sources}
${driver_header} ${driver_headers}
) )
target_precompile_headers(driver target_precompile_headers(driver
PRIVATE std_include.hpp PRIVATE std_include.hpp

View File

@ -46,13 +46,13 @@ private:
if (type == sleep_callback::type::sleep) if (type == sleep_callback::type::sleep)
{ {
debug_log("Going to sleep!"); debug_log("Going to sleep!");
this->hypervisor_.on_sleep(); this->hypervisor_.disable();
} }
if (type == sleep_callback::type::wakeup) if (type == sleep_callback::type::wakeup)
{ {
debug_log("Waking up!"); debug_log("Waking up!");
this->hypervisor_.on_wakeup(); this->hypervisor_.enable();
} }
} }
}; };

View File

@ -1,5 +1,4 @@
#pragma once #pragma once
#include "type_traits.hpp"
namespace std namespace std
{ {
@ -19,7 +18,6 @@ namespace std
runtime_error(const char* message) runtime_error(const char* message)
: message_(message) : message_(message)
{ {
} }
runtime_error(const runtime_error& obj) noexcept = default; runtime_error(const runtime_error& obj) noexcept = default;
@ -32,6 +30,7 @@ namespace std
{ {
return message_; return message_;
} }
private: private:
const char* message_{}; const char* message_{};
}; };

View File

@ -25,20 +25,20 @@ namespace std
Result operator()(Args ... a) const override Result operator()(Args ... a) const override
{ {
f_(std::forward<Args>(a)...); return f_(std::forward<Args>(a)...);
} }
F f_; F f_;
}; };
std::unique_ptr<fn_interface> fn{}; std::unique_ptr<fn_interface> fn_{};
public: public:
function() = default; function() = default;
template <typename T> template <typename T>
function(T&& t) function(T&& t)
: fn(new fn_implementation<T>(std::forward<T>(t))) : fn_(new fn_implementation<T>(std::forward<T>(t)))
{ {
} }
@ -51,12 +51,12 @@ namespace std
Result operator()(Args ... args) const Result operator()(Args ... args) const
{ {
return (*this->fn)(std::forward<Args>(args)...); return (*this->fn_)(std::forward<Args>(args)...);
} }
operator bool() const operator bool() const
{ {
return this->fn; return this->fn_;
} }
}; };
} }

View File

@ -2,6 +2,8 @@
#include "hypervisor.hpp" #include "hypervisor.hpp"
#include "exception.hpp" #include "exception.hpp"
#include "logging.hpp" #include "logging.hpp"
#include "finally.hpp"
#include "thread.hpp"
#define IA32_FEATURE_CONTROL_MSR 0x3A #define IA32_FEATURE_CONTROL_MSR 0x3A
#define IA32_FEATURE_CONTROL_MSR_LOCK 0x0001 #define IA32_FEATURE_CONTROL_MSR_LOCK 0x0001
@ -9,6 +11,8 @@
namespace namespace
{ {
hypervisor* instance{nullptr};
bool is_vmx_supported() bool is_vmx_supported()
{ {
int cpuid_data[4] = {0}; int cpuid_data[4] = {0};
@ -33,22 +37,53 @@ namespace
hypervisor::hypervisor() hypervisor::hypervisor()
{ {
if (instance != nullptr)
{
throw std::runtime_error("Hypervisor already instantiated");
}
auto destructor = utils::finally([]()
{
instance = nullptr;
});
instance = this;
if (!is_virtualization_supported()) if (!is_virtualization_supported())
{ {
throw std::runtime_error("VMX not supported on this machine"); throw std::runtime_error("VMX not supported on this machine");
} }
debug_log("VMX supported!\n"); debug_log("VMX supported!\n");
this->enable();
destructor.cancel();
} }
hypervisor::~hypervisor() hypervisor::~hypervisor()
{ {
this->disable();
instance = nullptr;
} }
void hypervisor::on_sleep() void hypervisor::disable()
{
thread::dispatch_on_all_cores([this]()
{
this->disable_core();
});
}
void hypervisor::enable()
{
thread::dispatch_on_all_cores([this]()
{
this->enable_core();
});
}
void hypervisor::enable_core()
{ {
} }
void hypervisor::on_wakeup() void hypervisor::disable_core()
{ {
} }

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "vmx.hpp"
class hypervisor class hypervisor
{ {
public: public:
@ -12,8 +14,10 @@ public:
hypervisor(const hypervisor& obj) = delete; hypervisor(const hypervisor& obj) = delete;
hypervisor& operator=(const hypervisor& obj) = delete; hypervisor& operator=(const hypervisor& obj) = delete;
void on_sleep(); void enable();
void on_wakeup(); void disable();
private: private:
void enable_core();
void disable_core();
}; };

View File

@ -16,53 +16,53 @@ namespace
} }
} }
void* __cdecl operator new(const size_t size, const POOL_TYPE pool, const unsigned long tag) void* operator new(const size_t size, const POOL_TYPE pool, const unsigned long tag)
{ {
return perform_allocation(size, pool, tag); return perform_allocation(size, pool, tag);
} }
void* __cdecl operator new[](const size_t size, const POOL_TYPE pool, const unsigned long tag) void* operator new[](const size_t size, const POOL_TYPE pool, const unsigned long tag)
{ {
return perform_allocation(size, pool, tag); return perform_allocation(size, pool, tag);
} }
void* __cdecl operator new(const size_t size) void* operator new(const size_t size)
{ {
return operator new(size, NonPagedPool); return operator new(size, NonPagedPool);
} }
void* __cdecl operator new[](const size_t size) void* operator new[](const size_t size)
{ {
return operator new[](size, NonPagedPool); return operator new[](size, NonPagedPool);
} }
// Placement new // Placement new
inline void* operator new(size_t, void* where) void* operator new(size_t, void* where)
{ {
return where; return where;
} }
void __cdecl operator delete(void* ptr, size_t) void operator delete(void* ptr, size_t)
{ {
ExFreePool(ptr); ExFreePool(ptr);
} }
void __cdecl operator delete(void* ptr) void operator delete(void* ptr)
{ {
ExFreePool(ptr); ExFreePool(ptr);
} }
void __cdecl operator delete[](void* ptr, size_t) void operator delete[](void* ptr, size_t)
{ {
ExFreePool(ptr); ExFreePool(ptr);
} }
void __cdecl operator delete[](void* ptr) void operator delete[](void* ptr)
{ {
ExFreePool(ptr); ExFreePool(ptr);
} }
extern "C" void __cdecl __std_terminate() extern "C" void __std_terminate()
{ {
KeBugCheckEx(DRIVER_VIOLATION, 14, 0, 0, 0); KeBugCheckEx(DRIVER_VIOLATION, 14, 0, 0, 0);
} }

View File

@ -1,13 +1,13 @@
#pragma once #pragma once
void* __cdecl operator new(size_t size, POOL_TYPE pool, unsigned long tag = 'momo'); void* operator new(size_t size, POOL_TYPE pool, unsigned long tag = 'momo');
void* __cdecl operator new[](size_t size, POOL_TYPE pool, unsigned long tag = 'momo'); void* operator new[](size_t size, POOL_TYPE pool, unsigned long tag = 'momo');
void* __cdecl operator new(size_t size); void* operator new(size_t size);
void* __cdecl operator new[](size_t size); void* operator new[](size_t size);
inline void* operator new(size_t, void* where); inline void* operator new(size_t, void* where);
void __cdecl operator delete(void *ptr, size_t); void operator delete(void* ptr, size_t);
void __cdecl operator delete(void *ptr); void operator delete(void* ptr);
void __cdecl operator delete[](void *ptr, size_t); void operator delete[](void* ptr, size_t);
void __cdecl operator delete[](void *ptr); void operator delete[](void* ptr);

View File

@ -2,5 +2,7 @@
#include <ntddk.h> #include <ntddk.h>
#include <intrin.h> #include <intrin.h>
#include "stdint.hpp"
#include "nt_ext.hpp" #include "nt_ext.hpp"
#include "new.hpp" #include "new.hpp"

31
src/driver/stdint.hpp Normal file
View File

@ -0,0 +1,31 @@
#pragma once
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef signed char int_least8_t;
typedef short int_least16_t;
typedef int int_least32_t;
typedef long long int_least64_t;
typedef unsigned char uint_least8_t;
typedef unsigned short uint_least16_t;
typedef unsigned int uint_least32_t;
typedef unsigned long long uint_least64_t;
typedef signed char int_fast8_t;
typedef int int_fast16_t;
typedef int int_fast32_t;
typedef long long int_fast64_t;
typedef unsigned char uint_fast8_t;
typedef unsigned int uint_fast16_t;
typedef unsigned int uint_fast32_t;
typedef unsigned long long uint_fast64_t;
typedef long long intmax_t;
typedef unsigned long long uintmax_t;

View File

@ -1,22 +1,29 @@
#pragma once #pragma once
using uint32_t = int;
namespace thread namespace thread
{ {
uint32_t get_processor_count(); uint32_t get_processor_count();
uint32_t get_processor_index(); uint32_t get_processor_index();
_IRQL_requires_min_(PASSIVE_LEVEL)
_IRQL_requires_max_(APC_LEVEL)
bool sleep(uint32_t milliseconds); bool sleep(uint32_t milliseconds);
_IRQL_requires_max_(APC_LEVEL)
_IRQL_requires_min_(PASSIVE_LEVEL)
_IRQL_requires_same_
void dispatch_on_all_cores(void (*callback)(void*), void* data); void dispatch_on_all_cores(void (*callback)(void*), void* data);
_IRQL_requires_max_(APC_LEVEL)
_IRQL_requires_min_(PASSIVE_LEVEL)
_IRQL_requires_same_
template <typename F> template <typename F>
void dispatch_on_all_cores(F&& callback) void dispatch_on_all_cores(F&& callback)
{ {
dispatch_on_all_cores([](void* data) dispatch_on_all_cores([](void* data)
{ {
(*reinterpret_cast<F*>(data))(); (*static_cast<F*>(data))();
}, &callback); }, &callback);
} }
} }

View File

@ -2,6 +2,8 @@
namespace std namespace std
{ {
using size_t = ::size_t;
// TEMPLATE CLASS remove_reference // TEMPLATE CLASS remove_reference
template <class _Ty> template <class _Ty>
struct remove_reference struct remove_reference
@ -52,14 +54,84 @@ namespace std
return (static_cast<_Ty&&>(_Arg)); return (static_cast<_Ty&&>(_Arg));
} }
template< class T > struct remove_cv { typedef T type; }; template <class T>
template< class T > struct remove_cv<const T> { typedef T type; }; struct remove_cv
template< class T > struct remove_cv<volatile T> { typedef T type; }; {
template< class T > struct remove_cv<const volatile T> { typedef T type; }; typedef T type;
};
template< class T > struct remove_const { typedef T type; }; template <class T>
template< class T > struct remove_const<const T> { typedef T type; }; struct remove_cv<const T>
{
typedef T type;
};
template< class T > struct remove_volatile { typedef T type; }; template <class T>
template< class T > struct remove_volatile<volatile T> { typedef T type; }; struct remove_cv<volatile T>
{
typedef T type;
};
template <class T>
struct remove_cv<const volatile T>
{
typedef T type;
};
template <class T>
struct remove_const
{
typedef T type;
};
template <class T>
struct remove_const<const T>
{
typedef T type;
};
template <class T>
struct remove_volatile
{
typedef T type;
};
template <class T>
struct remove_volatile<volatile T>
{
typedef T type;
};
template <class T, T v>
struct integral_constant
{
static constexpr T value = v;
using value_type = T;
using type = integral_constant;
constexpr operator value_type() const noexcept { return value; }
constexpr value_type operator()() const noexcept { return value; }
};
// ALIAS TEMPLATE bool_constant
template <bool _Val>
using bool_constant = integral_constant<bool, _Val>;
using true_type = bool_constant<true>;
using false_type = bool_constant<false>;
template <class T>
struct is_array : std::false_type
{
};
template <class T>
struct is_array<T[]> : std::true_type
{
};
template <class T, std::size_t N>
struct is_array<T[N]> : std::true_type
{
};
} }

View File

@ -18,7 +18,7 @@ namespace std
{ {
if (this->pointer_) if (this->pointer_)
{ {
delete this->pointer_; delete_pointer();
this->pointer_ = nullptr; this->pointer_ = nullptr;
} }
} }
@ -70,6 +70,19 @@ namespace std
} }
private: private:
static constexpr auto is_array_type = is_array<T>::value;
T* pointer_{nullptr}; T* pointer_{nullptr};
void delete_pointer()
{
if(is_array_type)
{
delete[] this->pointer_;
}
else
{
delete this->pointer_;
}
}
}; };
} }

101
src/driver/vmx.hpp Normal file
View File

@ -0,0 +1,101 @@
#pragma once
#define PML4E_ENTRY_COUNT 512
#define PDPTE_ENTRY_COUNT 512
#define PDE_ENTRY_COUNT 512
namespace vmx
{
struct vmcs
{
uint32_t revision_id;
uint32_t abort_indicator;
uint8_t data[PAGE_SIZE - 8];
};
struct epml4e
{
union
{
struct
{
uint64_t read : 1;
uint64_t write : 1;
uint64_t execute : 1;
uint64_t reserved : 5;
uint64_t accessed : 1;
uint64_t software_use : 1;
uint64_t user_mode_execute : 1;
uint64_t software_use2 : 1;
uint64_t page_frame_number : 36;
uint64_t reserved_high : 4;
uint64_t software_use_high : 12;
};
uint64_t full;
};
};
struct pdpte
{
union
{
struct
{
uint64_t read : 1;
uint64_t write : 1;
uint64_t execute : 1;
uint64_t reserved : 5;
uint64_t accessed : 1;
uint64_t software_use : 1;
uint64_t user_mode_execute : 1;
uint64_t software_use2 : 1;
uint64_t page_frame_number : 36;
uint64_t reserved_high : 4;
uint64_t software_use_high : 12;
};
uint64_t full;
};
};
struct large_pde
{
union
{
struct
{
uint64_t read : 1;
uint64_t write : 1;
uint64_t execute : 1;
uint64_t type : 3;
uint64_t ignore_pat : 1;
uint64_t large : 1;
uint64_t accessed : 1;
uint64_t dirty : 1;
uint64_t user_mode_execute : 1;
uint64_t software_use : 1;
uint64_t reserved : 9;
uint64_t page_frame_number : 27;
uint64_t reserved_high : 4;
uint64_t software_use_high : 11;
uint64_t suppress_vme : 1;
};
uint64_t full;
};
};
struct vm_state
{
DECLSPEC_ALIGN(PAGE_SIZE) uint8_t stack_buffer[KERNEL_STACK_SIZE]{};
DECLSPEC_ALIGN(PAGE_SIZE) uint8_t msr_bitmap[PAGE_SIZE]{};
DECLSPEC_ALIGN(PAGE_SIZE) epml4e epml4[PML4E_ENTRY_COUNT]{};
DECLSPEC_ALIGN(PAGE_SIZE) pdpte epdpt[PDPTE_ENTRY_COUNT]{};
DECLSPEC_ALIGN(PAGE_SIZE) large_pde epde[PDPTE_ENTRY_COUNT][PDE_ENTRY_COUNT]{};
DECLSPEC_ALIGN(PAGE_SIZE) vmcs vmx_on{};
DECLSPEC_ALIGN(PAGE_SIZE) vmcs vmcs{};
};
}