Skip to content

Commit

Permalink
EPT handling improvements (closes wbenny#6)
Browse files Browse the repository at this point in the history
- Use 2MB pages by default
- Cover first 512GB of memory with them
- Implement splitting of large pages
- Implemnt complementary joining (merging) back into large pages
  • Loading branch information
wbenny committed Sep 1, 2018
1 parent ce01c7a commit ce837f5
Show file tree
Hide file tree
Showing 11 changed files with 1,025 additions and 293 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ read and navigate through 5000 pages with browser's built-in PDF reader.

### Features

- EPT with identity mapping **with usage of 2MB pages** for device physical memory ranges (see [ept.cpp](src/hvpp/hvpp/ept.cpp))
and any memory in first 4GB range which is not backed by actual physical memory.
- EPT with identity mapping **with usage of 2MB pages** for the first 512GB of physical memory (see [ept.cpp](src/hvpp/hvpp/ept.cpp)).
This results in faster translations of the memory. It also means splitting particular 2MB pages into 4kb pages might
be desired if EPT hooking is required. This process is actually not complicated at all and this repository includes
example on how to achieve that.
- Simple pass-through VM-exit handler, which can handle:
- exceptions or [NMIs][nmi]
- `CPUID`, `(WB)INVD`, `INVLPG`, `RDTSC(P)`, `MOV CR`, `MOV DR`, `IN/OUT`, `RDMSR`, `WRMSR`, `SGDT`, `SIDT`, `LGDT`,
Expand Down
12 changes: 9 additions & 3 deletions src/hvpp/custom_vmexit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,12 @@ void custom_vmexit_handler::handle_execute_vmcall(vcpu_t& vp) noexcept
hvpp_trace("vmcall (hook) EXEC: 0x%p READ: 0x%p", data.page_exec.value(), data.page_read.value());

//
// Set execute-only access.
// Split the 2MB page where the code we want to hook resides.
//
vp.ept().split_2mb_to_4kb(data.page_exec & ept_pd_t::mask, data.page_exec & ept_pd_t::mask);

//
// Set execute-only access on the page we want to hook.
//
vp.ept().map_4kb(data.page_exec, data.page_exec, epte_t::access_type::execute);

Expand All @@ -130,9 +135,10 @@ void custom_vmexit_handler::handle_execute_vmcall(vcpu_t& vp) noexcept
hvpp_trace("vmcall (unhook)");

//
// Set back read-write-execute access.
// Merge the 4kb pages back to the original 2MB large page. Note that this
// will also automatically set the access rights to read_write_execute.
//
vp.ept().map_4kb(data.page_exec, data.page_exec, epte_t::access_type::read_write_execute);
vp.ept().join_4kb_to_2mb(data.page_exec & ept_pd_t::mask, data.page_exec & ept_pd_t::mask);

//
// We've changed EPT structure - mappings derived from EPT need to be
Expand Down
1 change: 1 addition & 0 deletions src/hvpp/hvpp.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
<ClInclude Include="ia32\msr\mtrr.h" />
<ClInclude Include="ia32\msr\vmx.h" />
<ClInclude Include="ia32\mtrr.h" />
<ClInclude Include="ia32\paging.h" />
<ClInclude Include="ia32\vmx.h" />
<ClInclude Include="ia32\vmx\exception_bitmap.h" />
<ClInclude Include="ia32\vmx\instruction_info.h" />
Expand Down
3 changes: 3 additions & 0 deletions src/hvpp/hvpp.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,9 @@
<ClInclude Include="ia32\cpuid\cpuid_eax_01.h">
<Filter>Header Files\ia32\cpuid</Filter>
</ClInclude>
<ClInclude Include="ia32\paging.h">
<Filter>Header Files\ia32</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<MASM Include="ia32\context.asm">
Expand Down
Loading

0 comments on commit ce837f5

Please sign in to comment.