mirror of
https://github.com/momo5502/hypervisor.git
synced 2025-04-19 13:42:55 +00:00
More cleanup and hypervisor progress
This commit is contained in:
parent
6ce3597bd3
commit
8fcaaf5cbf
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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_{};
|
||||
};
|
||||
|
@ -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_;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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()
|
||||
{
|
||||
}
|
||||
|
@ -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();
|
||||
};
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
31
src/driver/stdint.hpp
Normal 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;
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
};
|
||||
}
|
||||
|
@ -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
101
src/driver/vmx.hpp
Normal 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{};
|
||||
};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user