mirror of
https://github.com/momo5502/hypervisor.git
synced 2025-04-19 13:42:55 +00:00
Experimental hypervisor-wide ept hooking
This commit is contained in:
parent
76fcdd0d8e
commit
ffb7fc4a69
@ -84,7 +84,7 @@ namespace
|
|||||||
|
|
||||||
uintptr_t read_vmx(const uint32_t vmcs_field_id)
|
uintptr_t read_vmx(const uint32_t vmcs_field_id)
|
||||||
{
|
{
|
||||||
size_t data{};
|
uintptr_t data{};
|
||||||
__vmx_vmread(vmcs_field_id, &data);
|
__vmx_vmread(vmcs_field_id, &data);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -165,6 +165,21 @@ bool hypervisor::is_enabled() const
|
|||||||
bool hypervisor::install_ept_hook(const void* destination, const void* source, const size_t length,
|
bool hypervisor::install_ept_hook(const void* destination, const void* source, const size_t length,
|
||||||
vmx::ept_translation_hint* translation_hint)
|
vmx::ept_translation_hint* translation_hint)
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this->ept_->install_hook(destination, source, length, translation_hint);
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
debug_log("Failed to install ept hook on core %d: %s\n", thread::get_processor_index(), e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
debug_log("Failed to install ept hook on core %d.\n", thread::get_processor_index());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
volatile long failures = 0;
|
volatile long failures = 0;
|
||||||
thread::dispatch_on_all_cores([&]
|
thread::dispatch_on_all_cores([&]
|
||||||
{
|
{
|
||||||
@ -179,6 +194,8 @@ bool hypervisor::install_ept_hook(const void* destination, const void* source, c
|
|||||||
|
|
||||||
void hypervisor::disable_all_ept_hooks() const
|
void hypervisor::disable_all_ept_hooks() const
|
||||||
{
|
{
|
||||||
|
this->ept_->disable_all_hooks();
|
||||||
|
|
||||||
thread::dispatch_on_all_cores([&]
|
thread::dispatch_on_all_cores([&]
|
||||||
{
|
{
|
||||||
auto* vm_state = this->get_current_vm_state();
|
auto* vm_state = this->get_current_vm_state();
|
||||||
@ -187,11 +204,9 @@ void hypervisor::disable_all_ept_hooks() const
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vm_state->ept.disable_all_hooks();
|
|
||||||
|
|
||||||
if (this->is_enabled())
|
if (this->is_enabled())
|
||||||
{
|
{
|
||||||
vm_state->ept.invalidate();
|
vm_state->ept->invalidate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -205,6 +220,8 @@ void hypervisor::enable()
|
|||||||
{
|
{
|
||||||
const auto cr3 = __readcr3();
|
const auto cr3 = __readcr3();
|
||||||
|
|
||||||
|
this->ept_->initialize();
|
||||||
|
|
||||||
volatile long failures = 0;
|
volatile long failures = 0;
|
||||||
thread::dispatch_on_all_cores([&]
|
thread::dispatch_on_all_cores([&]
|
||||||
{
|
{
|
||||||
@ -449,10 +466,10 @@ void vmx_dispatch_vm_exit(vmx::guest_context& guest_context, const vmx::state& v
|
|||||||
vmx_handle_vmx(guest_context);
|
vmx_handle_vmx(guest_context);
|
||||||
break;
|
break;
|
||||||
case VMX_EXIT_REASON_EPT_VIOLATION:
|
case VMX_EXIT_REASON_EPT_VIOLATION:
|
||||||
vm_state.ept.handle_violation(guest_context);
|
vm_state.ept->handle_violation(guest_context);
|
||||||
break;
|
break;
|
||||||
case VMX_EXIT_REASON_EPT_MISCONFIGURATION:
|
case VMX_EXIT_REASON_EPT_MISCONFIGURATION:
|
||||||
vm_state.ept.handle_misconfiguration(guest_context);
|
vm_state.ept->handle_misconfiguration(guest_context);
|
||||||
break;
|
break;
|
||||||
//case VMX_EXIT_REASON_EXECUTE_RDTSC:
|
//case VMX_EXIT_REASON_EXECUTE_RDTSC:
|
||||||
// break;
|
// break;
|
||||||
@ -515,7 +532,7 @@ void setup_vmcs_for_cpu(vmx::state& vm_state)
|
|||||||
|
|
||||||
if (launch_context->ept_controls.flags != 0)
|
if (launch_context->ept_controls.flags != 0)
|
||||||
{
|
{
|
||||||
const auto vmx_eptp = vm_state.ept.get_ept_pointer();
|
const auto vmx_eptp = vm_state.ept->get_ept_pointer();
|
||||||
__vmx_vmwrite(VMCS_CTRL_EPT_POINTER, vmx_eptp.flags);
|
__vmx_vmwrite(VMCS_CTRL_EPT_POINTER, vmx_eptp.flags);
|
||||||
__vmx_vmwrite(VMCS_CTRL_VIRTUAL_PROCESSOR_IDENTIFIER, 1);
|
__vmx_vmwrite(VMCS_CTRL_VIRTUAL_PROCESSOR_IDENTIFIER, 1);
|
||||||
}
|
}
|
||||||
@ -655,7 +672,7 @@ void initialize_msrs(vmx::launch_context& launch_context)
|
|||||||
[[ noreturn ]] void launch_hypervisor(vmx::state& vm_state)
|
[[ noreturn ]] void launch_hypervisor(vmx::state& vm_state)
|
||||||
{
|
{
|
||||||
initialize_msrs(vm_state.launch_context);
|
initialize_msrs(vm_state.launch_context);
|
||||||
vm_state.ept.initialize();
|
//vm_state.ept->initialize();
|
||||||
|
|
||||||
enter_root_mode_on_cpu(vm_state);
|
enter_root_mode_on_cpu(vm_state);
|
||||||
setup_vmcs_for_cpu(vm_state);
|
setup_vmcs_for_cpu(vm_state);
|
||||||
@ -708,6 +725,15 @@ void hypervisor::disable_core()
|
|||||||
|
|
||||||
void hypervisor::allocate_vm_states()
|
void hypervisor::allocate_vm_states()
|
||||||
{
|
{
|
||||||
|
if (!this->ept_)
|
||||||
|
{
|
||||||
|
this->ept_ = memory::allocate_aligned_object<vmx::ept>();
|
||||||
|
if (!this->ept_)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to allocate ept object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this->vm_states_)
|
if (this->vm_states_)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("VM states are still in use");
|
throw std::runtime_error("VM states are still in use");
|
||||||
@ -725,16 +751,15 @@ void hypervisor::allocate_vm_states()
|
|||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to allocate VM state entries");
|
throw std::runtime_error("Failed to allocate VM state entries");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->vm_states_[i]->ept = this->ept_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hypervisor::free_vm_states()
|
void hypervisor::free_vm_states()
|
||||||
{
|
{
|
||||||
if (!this->vm_states_)
|
if (this->vm_states_)
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto i = 0u; i < this->vm_state_count_; ++i)
|
for (auto i = 0u; i < this->vm_state_count_; ++i)
|
||||||
{
|
{
|
||||||
memory::free_aligned_object(this->vm_states_[i]);
|
memory::free_aligned_object(this->vm_states_[i]);
|
||||||
@ -745,6 +770,13 @@ void hypervisor::free_vm_states()
|
|||||||
this->vm_state_count_ = 0;
|
this->vm_state_count_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->ept_)
|
||||||
|
{
|
||||||
|
memory::free_aligned_object(this->ept_);
|
||||||
|
this->ept_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool hypervisor::try_install_ept_hook_on_core(const void* destination, const void* source, const size_t length,
|
bool hypervisor::try_install_ept_hook_on_core(const void* destination, const void* source, const size_t length,
|
||||||
vmx::ept_translation_hint* translation_hint)
|
vmx::ept_translation_hint* translation_hint)
|
||||||
{
|
{
|
||||||
@ -774,11 +806,15 @@ void hypervisor::install_ept_hook_on_core(const void* destination, const void* s
|
|||||||
throw std::runtime_error("No vm state available");
|
throw std::runtime_error("No vm state available");
|
||||||
}
|
}
|
||||||
|
|
||||||
vm_state->ept.install_hook(destination, source, length, translation_hint);
|
(void)destination;
|
||||||
|
(void)source;
|
||||||
|
(void)length;
|
||||||
|
(void)translation_hint;
|
||||||
|
//vm_state->ept->install_hook(destination, source, length, translation_hint);
|
||||||
|
|
||||||
if (this->is_enabled())
|
if (this->is_enabled())
|
||||||
{
|
{
|
||||||
vm_state->ept.invalidate();
|
vm_state->ept->invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
uint32_t vm_state_count_{0};
|
uint32_t vm_state_count_{0};
|
||||||
vmx::state** vm_states_{nullptr};
|
vmx::state** vm_states_{nullptr};
|
||||||
|
vmx::ept* ept_{nullptr};
|
||||||
|
|
||||||
void enable_core(uint64_t system_directory_table_base);
|
void enable_core(uint64_t system_directory_table_base);
|
||||||
bool try_enable_core(uint64_t system_directory_table_base);
|
bool try_enable_core(uint64_t system_directory_table_base);
|
||||||
|
@ -53,7 +53,7 @@ namespace vmx
|
|||||||
DECLSPEC_PAGE_ALIGN vmcs vmx_on{};
|
DECLSPEC_PAGE_ALIGN vmcs vmx_on{};
|
||||||
DECLSPEC_PAGE_ALIGN vmcs vmcs{};
|
DECLSPEC_PAGE_ALIGN vmcs vmcs{};
|
||||||
|
|
||||||
DECLSPEC_PAGE_ALIGN ept ept{};
|
DECLSPEC_PAGE_ALIGN ept* ept{};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gdt_entry
|
struct gdt_entry
|
||||||
|
Loading…
x
Reference in New Issue
Block a user