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
${driver_sources}
${driver_header}
${driver_headers}
)
target_precompile_headers(driver
PRIVATE std_include.hpp

View File

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

View File

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

View File

@ -25,20 +25,20 @@ namespace std
Result operator()(Args ... a) const override
{
f_(std::forward<Args>(a)...);
return f_(std::forward<Args>(a)...);
}
F f_;
};
std::unique_ptr<fn_interface> fn{};
std::unique_ptr<fn_interface> fn_{};
public:
function() = default;
template <typename 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
{
return (*this->fn)(std::forward<Args>(args)...);
return (*this->fn_)(std::forward<Args>(args)...);
}
operator bool() const
{
return this->fn;
return this->fn_;
}
};
}

View File

@ -2,6 +2,8 @@
#include "hypervisor.hpp"
#include "exception.hpp"
#include "logging.hpp"
#include "finally.hpp"
#include "thread.hpp"
#define IA32_FEATURE_CONTROL_MSR 0x3A
#define IA32_FEATURE_CONTROL_MSR_LOCK 0x0001
@ -9,6 +11,8 @@
namespace
{
hypervisor* instance{nullptr};
bool is_vmx_supported()
{
int cpuid_data[4] = {0};
@ -33,22 +37,53 @@ namespace
hypervisor::hypervisor()
{
if (instance != nullptr)
{
throw std::runtime_error("Hypervisor already instantiated");
}
auto destructor = utils::finally([]()
{
instance = nullptr;
});
instance = this;
if (!is_virtualization_supported())
{
throw std::runtime_error("VMX not supported on this machine");
}
debug_log("VMX supported!\n");
this->enable();
destructor.cancel();
}
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
#include "vmx.hpp"
class hypervisor
{
public:
@ -12,8 +14,10 @@ public:
hypervisor(const hypervisor& obj) = delete;
hypervisor& operator=(const hypervisor& obj) = delete;
void on_sleep();
void on_wakeup();
void enable();
void disable();
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);
}
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);
}
void* __cdecl operator new(const size_t size)
void* operator new(const size_t size)
{
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);
}
// Placement new
inline void* operator new(size_t, void* where)
void* operator new(size_t, void* where)
{
return where;
}
void __cdecl operator delete(void* ptr, size_t)
void operator delete(void* ptr, size_t)
{
ExFreePool(ptr);
}
void __cdecl operator delete(void* ptr)
void operator delete(void* ptr)
{
ExFreePool(ptr);
}
void __cdecl operator delete[](void* ptr, size_t)
void operator delete[](void* ptr, size_t)
{
ExFreePool(ptr);
}
void __cdecl operator delete[](void* ptr)
void operator delete[](void* ptr)
{
ExFreePool(ptr);
}
extern "C" void __cdecl __std_terminate()
extern "C" void __std_terminate()
{
KeBugCheckEx(DRIVER_VIOLATION, 14, 0, 0, 0);
}

View File

@ -1,13 +1,13 @@
#pragma once
void* __cdecl 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* __cdecl operator new(size_t size);
void* __cdecl operator new[](size_t size);
void* 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* operator new(size_t size);
void* operator new[](size_t size);
inline void* operator new(size_t, void* where);
void __cdecl operator delete(void *ptr, size_t);
void __cdecl operator delete(void *ptr);
void __cdecl operator delete[](void *ptr, size_t);
void __cdecl operator delete[](void *ptr);
void operator delete(void* ptr, size_t);
void operator delete(void* ptr);
void operator delete[](void* ptr, size_t);
void operator delete[](void* ptr);

View File

@ -2,5 +2,7 @@
#include <ntddk.h>
#include <intrin.h>
#include "stdint.hpp"
#include "nt_ext.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
using uint32_t = int;
namespace thread
{
uint32_t get_processor_count();
uint32_t get_processor_index();
_IRQL_requires_min_(PASSIVE_LEVEL)
_IRQL_requires_max_(APC_LEVEL)
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);
_IRQL_requires_max_(APC_LEVEL)
_IRQL_requires_min_(PASSIVE_LEVEL)
_IRQL_requires_same_
template <typename F>
void dispatch_on_all_cores(F&& callback)
{
dispatch_on_all_cores([](void* data)
{
(*reinterpret_cast<F*>(data))();
(*static_cast<F*>(data))();
}, &callback);
}
}

View File

@ -2,6 +2,8 @@
namespace std
{
using size_t = ::size_t;
// TEMPLATE CLASS remove_reference
template <class _Ty>
struct remove_reference
@ -52,14 +54,84 @@ namespace std
return (static_cast<_Ty&&>(_Arg));
}
template< class T > struct remove_cv { typedef T type; };
template< class T > struct remove_cv<const T> { typedef T type; };
template< class T > 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_cv
{
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_cv<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>
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_)
{
delete this->pointer_;
delete_pointer();
this->pointer_ = nullptr;
}
}
@ -70,6 +70,19 @@ namespace std
}
private:
static constexpr auto is_array_type = is_array<T>::value;
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{};
};
}