Reflect memory writes to shadow page

This commit is contained in:
momo5502 2022-05-15 13:07:17 +02:00
parent 489fba2b60
commit 76fcdd0d8e
4 changed files with 73 additions and 5 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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');

View File

@ -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);