parent
0ddabe809e
commit
0d63ad288a
Binary file not shown.
@ -0,0 +1,65 @@
|
||||
#include "vmxlaunch.hpp"
|
||||
#include "idt.hpp"
|
||||
|
||||
auto driver_unload(
|
||||
PDRIVER_OBJECT driver_object
|
||||
) -> void
|
||||
{
|
||||
// no unloading this hypervisor... reboot!
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
auto driver_entry(
|
||||
PDRIVER_OBJECT driver_object,
|
||||
PUNICODE_STRING registry_path
|
||||
) -> NTSTATUS
|
||||
{
|
||||
vmxon::g_vmx_ctx =
|
||||
reinterpret_cast<hv::pvmx_ctx>(
|
||||
ExAllocatePool(NonPagedPool, sizeof hv::vmx_ctx));
|
||||
|
||||
// setup vcpu structures (vmx on region and vmcs...)
|
||||
vmxon::create_vcpus(vmxon::g_vmx_ctx);
|
||||
|
||||
// setup host address space...
|
||||
cr3 cr3_value;
|
||||
cr3_value.flags = __readcr3();
|
||||
cr3_value.address_of_page_directory =
|
||||
(MmGetPhysicalAddress(mm::pml4).QuadPart >> 12);
|
||||
|
||||
memset(mm::pml4, NULL, sizeof mm::pml4);
|
||||
mm::pml4[PML4_SELF_REF].pfn = cr3_value.address_of_page_directory;
|
||||
mm::pml4[PML4_SELF_REF].present = true;
|
||||
mm::pml4[PML4_SELF_REF].rw = true;
|
||||
mm::pml4[PML4_SELF_REF].user_supervisor = false;
|
||||
|
||||
PHYSICAL_ADDRESS current_pml4;
|
||||
current_pml4.QuadPart =
|
||||
(cr3{ __readcr3() }.address_of_page_directory << 12);
|
||||
|
||||
const auto kernel_pml4 =
|
||||
reinterpret_cast<mm::ppml4e>(
|
||||
MmGetVirtualForPhysical(current_pml4));
|
||||
|
||||
// vmxroot will have the same "address space" as the current one being executed in...
|
||||
memcpy(&mm::pml4[255], &kernel_pml4[255], sizeof(mm::pml4e) * 255);
|
||||
|
||||
// setup mapping ptes to be present and writable...
|
||||
for (auto idx = 0u; idx < 254; ++idx)
|
||||
{
|
||||
reinterpret_cast<mm::ppte>(mm::pml4)[idx].present = true;
|
||||
reinterpret_cast<mm::ppte>(mm::pml4)[idx].rw = true;
|
||||
}
|
||||
|
||||
// enable vmx operation on all cores...
|
||||
KeIpiGenericCall((PKIPI_BROADCAST_WORKER)&vmxon::init_vmxon, NULL);
|
||||
|
||||
// setup VMCS for all logical cores...
|
||||
KeIpiGenericCall((PKIPI_BROADCAST_WORKER)&vmxlaunch::init_vmcs, cr3_value.flags);
|
||||
|
||||
// vmxlaunch for all cores...
|
||||
KeIpiGenericCall((PKIPI_BROADCAST_WORKER)&vmxlaunch::launch, NULL);
|
||||
|
||||
driver_object->DriverUnload = &driver_unload;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
#include "vmxlaunch.hpp"
|
||||
|
||||
auto driver_unload(
|
||||
PDRIVER_OBJECT driver_object
|
||||
) -> void
|
||||
{
|
||||
// test to see if invalid opcode happens...
|
||||
__vmx_off();
|
||||
}
|
||||
|
||||
auto driver_entry(
|
||||
PDRIVER_OBJECT driver_object,
|
||||
PUNICODE_STRING registry_path
|
||||
) -> NTSTATUS
|
||||
{
|
||||
vmxon::g_vmx_ctx =
|
||||
reinterpret_cast<hv::pvmx_ctx>(
|
||||
ExAllocatePool(NonPagedPool, sizeof hv::vmx_ctx));
|
||||
|
||||
// setup vcpu structures (vmx on region and vmcs...)
|
||||
vmxon::create_vcpus(vmxon::g_vmx_ctx);
|
||||
|
||||
// enable vmx operation on all cores...
|
||||
KeIpiGenericCall((PKIPI_BROADCAST_WORKER)&vmxon::init_vmxon, NULL);
|
||||
|
||||
// setup VMCS for all logical cores...
|
||||
KeIpiGenericCall((PKIPI_BROADCAST_WORKER)&vmxlaunch::init_vmcs, NULL);
|
||||
|
||||
// vmxlaunch for all cores...
|
||||
KeIpiGenericCall((PKIPI_BROADCAST_WORKER)&vmxlaunch::launch, NULL);
|
||||
|
||||
driver_object->DriverUnload = &driver_unload;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "hv_types.hpp"
|
||||
#pragma section(".gdt", read, write)
|
||||
|
||||
#define GDT_CS_INDEX 0
|
||||
#define GDT_DS_INDEX 1
|
||||
#define GDT_TSS_INDEX 2
|
||||
|
||||
namespace gdt
|
||||
{
|
||||
__declspec(allocate(".gdt"))
|
||||
inline segment_descriptor_64 table[3]; // TODO...
|
||||
|
||||
auto init()->void;
|
||||
auto get_info(const segment_descriptor_register_64& gdt_value, segment_selector segment_selector)->hv::segment_info_ctx;
|
||||
auto get_access_rights(segment_descriptor_64* segment_descriptor)->vmx_segment_access_rights;
|
||||
}
|
@ -1,20 +1,30 @@
|
||||
#include "idt.hpp"
|
||||
|
||||
void seh_handler(hv::pidt_regs_t regs)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
namespace idt
|
||||
{
|
||||
auto create_entry(void* address) -> hv::idt_entry_t
|
||||
auto create_entry(hv::idt_addr_t idt_handler) -> hv::idt_entry_t
|
||||
{
|
||||
hv::idt_addr_t idt_addr{ (u64) address };
|
||||
hv::idt_entry_t result{};
|
||||
|
||||
result.dpl = 0;
|
||||
result.storage_segment = 0;
|
||||
result.segment_selector = readcs();
|
||||
result.gate_type = SEGMENT_DESCRIPTOR_TYPE_INTERRUPT_GATE;
|
||||
result.present = 1;
|
||||
result.offset_high = idt_addr.offset_high;
|
||||
result.offset_middle = idt_addr.offset_middle;
|
||||
result.offset_low = idt_addr.offset_low;
|
||||
result.present = true;
|
||||
|
||||
result.offset_high = idt_handler.offset_high;
|
||||
result.offset_middle = idt_handler.offset_middle;
|
||||
result.offset_low = idt_handler.offset_low;
|
||||
return result;
|
||||
}
|
||||
|
||||
auto init() -> u64
|
||||
{
|
||||
idt::table[general_protection] = create_entry(hv::idt_addr_t{ __gp_handler });
|
||||
idt::table[page_fault] = create_entry(hv::idt_addr_t{ __pf_handler });
|
||||
idt::table[divide_error] = create_entry(hv::idt_addr_t{ __de_handler });
|
||||
return reinterpret_cast<u64>(idt::table);
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
extern seh_handler : proc
|
||||
|
||||
.code
|
||||
__pf_handler proc
|
||||
__de_handler proc
|
||||
__gp_handler proc
|
||||
push rax
|
||||
push rbx
|
||||
push rcx
|
||||
push rdx
|
||||
push rsi
|
||||
push rdi
|
||||
push rbp
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
|
||||
sub rsp, 0108h ; 16 xmm registers... and +8 bytes for alignment...
|
||||
movaps [rsp], xmm0
|
||||
movaps [rsp + 010h], xmm1
|
||||
movaps [rsp + 020h], xmm2
|
||||
movaps [rsp + 030h], xmm3
|
||||
movaps [rsp + 040h], xmm4
|
||||
movaps [rsp + 050h], xmm5
|
||||
movaps [rsp + 060h], xmm6
|
||||
movaps [rsp + 070h], xmm7
|
||||
movaps [rsp + 080h], xmm8
|
||||
movaps [rsp + 090h], xmm9
|
||||
movaps [rsp + 0A0h], xmm10
|
||||
movaps [rsp + 0B0h], xmm11
|
||||
movaps [rsp + 0C0h], xmm12
|
||||
movaps [rsp + 0D0h], xmm13
|
||||
movaps [rsp + 0E0h], xmm14
|
||||
movaps [rsp + 0F0h], xmm15
|
||||
|
||||
mov rcx, rsp
|
||||
sub rsp, 20h
|
||||
call seh_handler
|
||||
add rsp, 20h
|
||||
|
||||
movups xmm0, [rsp]
|
||||
movups xmm1, [rsp + 010h]
|
||||
movups xmm2, [rsp + 020h]
|
||||
movups xmm3, [rsp + 030h]
|
||||
movups xmm4, [rsp + 040h]
|
||||
movups xmm5, [rsp + 050h]
|
||||
movups xmm6, [rsp + 060h]
|
||||
movups xmm7, [rsp + 070h]
|
||||
movups xmm8, [rsp + 080h]
|
||||
movups xmm9, [rsp + 090h]
|
||||
movups xmm10, [rsp + 0A0h]
|
||||
movups xmm11, [rsp + 0B0h]
|
||||
movups xmm12, [rsp + 0C0h]
|
||||
movups xmm13, [rsp + 0D0h]
|
||||
movups xmm14, [rsp + 0E0h]
|
||||
movups xmm15, [rsp + 0F0h]
|
||||
add rsp, 0108h ; 16 xmm registers... and +8 bytes for alignment...
|
||||
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rbp
|
||||
pop rdi
|
||||
pop rsi
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rbx
|
||||
pop rax
|
||||
|
||||
iretq
|
||||
__gp_handler endp
|
||||
__de_handler endp
|
||||
__pf_handler endp
|
||||
end
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "hv_types.hpp"
|
||||
#include "invd.hpp"
|
||||
|
||||
extern "C" auto vmxexit_handler() -> void;
|
||||
extern "C" auto exit_handler(hv::pguest_registers regs) -> void;
|
Loading…
Reference in new issue