mirror of
https://github.com/momo5502/hypervisor.git
synced 2025-04-19 13:42:55 +00:00
Reflect memory writes to shadow page
This commit is contained in:
parent
489fba2b60
commit
76fcdd0d8e
@ -74,6 +74,44 @@ namespace vmx
|
||||
|
||||
return candidate_memory_type;
|
||||
}
|
||||
|
||||
void update_fake_page(ept_hook& hook)
|
||||
{
|
||||
if(!hook.mapped_virtual_address)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t page_copy[PAGE_SIZE];
|
||||
memcpy(page_copy, hook.mapped_virtual_address, PAGE_SIZE);
|
||||
|
||||
for(size_t i = 0; i < PAGE_SIZE; ++i)
|
||||
{
|
||||
if(hook.diff_page[i] != page_copy[i])
|
||||
{
|
||||
hook.diff_page[i] = page_copy[i];
|
||||
hook.fake_page[i] = page_copy[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ept_hook::ept_hook(const uint64_t physical_base)
|
||||
: physical_base_address(physical_base)
|
||||
, mapped_virtual_address(memory::map_physical_memory(physical_base_address, PAGE_SIZE))
|
||||
{
|
||||
if (!mapped_virtual_address)
|
||||
{
|
||||
throw std::runtime_error("Failed to map physical memory");
|
||||
}
|
||||
}
|
||||
|
||||
ept_hook::~ept_hook()
|
||||
{
|
||||
if (mapped_virtual_address)
|
||||
{
|
||||
memory::unmap_physical_memory(mapped_virtual_address, PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
ept::ept()
|
||||
@ -178,6 +216,7 @@ namespace vmx
|
||||
|
||||
if (!violation_qualification.ept_executable && violation_qualification.execute_access)
|
||||
{
|
||||
update_fake_page(*hook);
|
||||
hook->target_page->flags = hook->execute_entry.flags;
|
||||
guest_context.increment_rip = false;
|
||||
}
|
||||
@ -335,9 +374,9 @@ namespace vmx
|
||||
return split;
|
||||
}
|
||||
|
||||
ept_hook* ept::allocate_ept_hook()
|
||||
ept_hook* ept::allocate_ept_hook(const uint64_t physical_address)
|
||||
{
|
||||
auto* hook = memory::allocate_aligned_object<ept_hook>();
|
||||
auto* hook = memory::allocate_aligned_object<ept_hook>(physical_address);
|
||||
if (!hook)
|
||||
{
|
||||
throw std::runtime_error("Failed to allocate ept hook object");
|
||||
@ -400,7 +439,7 @@ namespace vmx
|
||||
return hook;
|
||||
}
|
||||
|
||||
hook = this->allocate_ept_hook();
|
||||
hook = this->allocate_ept_hook(physical_base_address);
|
||||
|
||||
if (!hook)
|
||||
{
|
||||
@ -411,6 +450,7 @@ namespace vmx
|
||||
|
||||
const auto* data_source = translation_hint ? &translation_hint->page[0] : virtual_target;
|
||||
memcpy(&hook->fake_page[0], data_source, PAGE_SIZE);
|
||||
memcpy(&hook->diff_page[0], data_source, PAGE_SIZE);
|
||||
hook->physical_base_address = physical_base_address;
|
||||
|
||||
hook->target_page = this->get_pml1_entry(physical_address);
|
||||
|
@ -26,9 +26,14 @@ namespace vmx
|
||||
|
||||
struct ept_hook
|
||||
{
|
||||
ept_hook(const uint64_t physical_base);
|
||||
~ept_hook();
|
||||
|
||||
DECLSPEC_PAGE_ALIGN uint8_t fake_page[PAGE_SIZE]{};
|
||||
DECLSPEC_PAGE_ALIGN uint8_t diff_page[PAGE_SIZE]{};
|
||||
|
||||
uint64_t physical_base_address{};
|
||||
void* mapped_virtual_address{};
|
||||
|
||||
pml1* target_page{};
|
||||
pml1 original_entry{};
|
||||
@ -89,7 +94,7 @@ namespace vmx
|
||||
pml1* find_pml1_table(uint64_t physical_address) const;
|
||||
|
||||
ept_split* allocate_ept_split();
|
||||
ept_hook* allocate_ept_hook();
|
||||
ept_hook* allocate_ept_hook(uint64_t physical_address);
|
||||
ept_hook* find_ept_hook(uint64_t physical_address) const;
|
||||
|
||||
ept_hook* get_or_create_ept_hook(void* destination, ept_translation_hint* translation_hint = nullptr);
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "std_include.hpp"
|
||||
#include "memory.hpp"
|
||||
#include "string.hpp"
|
||||
#include "process.hpp"
|
||||
|
||||
namespace memory
|
||||
{
|
||||
@ -84,6 +83,23 @@ namespace memory
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
|
||||
void* map_physical_memory(const uint64_t address, const size_t size)
|
||||
{
|
||||
PHYSICAL_ADDRESS physical_address{};
|
||||
physical_address.QuadPart = static_cast<LONGLONG>(address);
|
||||
return MmMapIoSpace(physical_address, size, MmNonCached);
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
|
||||
void unmap_physical_memory(void* address, const size_t size)
|
||||
{
|
||||
MmUnmapIoSpace(address, size);
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
|
||||
void* allocate_non_paged_memory(const size_t size)
|
||||
{
|
||||
void* memory = ExAllocatePoolWithTag(NonPagedPool, size, 'MOMO');
|
||||
|
@ -13,6 +13,13 @@ namespace memory
|
||||
uint64_t get_physical_address(void* address);
|
||||
void* get_virtual_address(uint64_t address);
|
||||
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void* map_physical_memory(const uint64_t address, const size_t size);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void unmap_physical_memory(void* address, const size_t size);
|
||||
|
||||
_Must_inspect_result_
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
void* allocate_non_paged_memory(size_t size);
|
||||
|
Loading…
x
Reference in New Issue
Block a user