mirror of
https://github.com/momo5502/hypervisor.git
synced 2025-04-19 21:52:55 +00:00
Some cleanup
This commit is contained in:
parent
ce27636f3c
commit
811d11af97
@ -4,159 +4,10 @@
|
|||||||
#include "irp.hpp"
|
#include "irp.hpp"
|
||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
#include "hypervisor.hpp"
|
#include "hypervisor.hpp"
|
||||||
#include "memory.hpp"
|
|
||||||
#include "process.hpp"
|
|
||||||
|
|
||||||
#define DOS_DEV_NAME L"\\DosDevices\\HelloDev"
|
#define DOS_DEV_NAME L"\\DosDevices\\HelloDev"
|
||||||
#define DEV_NAME L"\\Device\\HelloDev"
|
#define DEV_NAME L"\\Device\\HelloDev"
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
void log_current_process_name()
|
|
||||||
{
|
|
||||||
const auto process = process::get_current_process();
|
|
||||||
const auto* name = process.get_image_filename();
|
|
||||||
|
|
||||||
if (name)
|
|
||||||
{
|
|
||||||
debug_log("Denied for process: %s\n", name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS (*NtCreateFileOrig)(
|
|
||||||
PHANDLE FileHandle,
|
|
||||||
ACCESS_MASK DesiredAccess,
|
|
||||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
|
||||||
PIO_STATUS_BLOCK IoStatusBlock,
|
|
||||||
PLARGE_INTEGER AllocationSize,
|
|
||||||
ULONG FileAttributes,
|
|
||||||
ULONG ShareAccess,
|
|
||||||
ULONG CreateDisposition,
|
|
||||||
ULONG CreateOptions,
|
|
||||||
PVOID EaBuffer,
|
|
||||||
ULONG EaLength
|
|
||||||
);
|
|
||||||
|
|
||||||
NTSTATUS NtCreateFileHook(
|
|
||||||
PHANDLE FileHandle,
|
|
||||||
ACCESS_MASK DesiredAccess,
|
|
||||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
|
||||||
PIO_STATUS_BLOCK IoStatusBlock,
|
|
||||||
PLARGE_INTEGER AllocationSize,
|
|
||||||
ULONG FileAttributes,
|
|
||||||
ULONG ShareAccess,
|
|
||||||
ULONG CreateDisposition,
|
|
||||||
ULONG CreateOptions,
|
|
||||||
PVOID EaBuffer,
|
|
||||||
ULONG EaLength
|
|
||||||
)
|
|
||||||
{
|
|
||||||
static WCHAR BlockedFileName[] = L"test.txt";
|
|
||||||
static SIZE_T BlockedFileNameLength = (sizeof(BlockedFileName) / sizeof(BlockedFileName[0])) - 1;
|
|
||||||
|
|
||||||
PWCH NameBuffer;
|
|
||||||
USHORT NameLength;
|
|
||||||
|
|
||||||
__try
|
|
||||||
{
|
|
||||||
ProbeForRead(ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), 1);
|
|
||||||
ProbeForRead(ObjectAttributes->ObjectName, sizeof(UNICODE_STRING), 1);
|
|
||||||
|
|
||||||
NameBuffer = ObjectAttributes->ObjectName->Buffer;
|
|
||||||
NameLength = ObjectAttributes->ObjectName->Length;
|
|
||||||
|
|
||||||
ProbeForRead(NameBuffer, NameLength, 1);
|
|
||||||
|
|
||||||
/* Convert to length in WCHARs */
|
|
||||||
NameLength /= sizeof(WCHAR);
|
|
||||||
|
|
||||||
/* Does the file path (ignoring case and null terminator) end with our blocked file name? */
|
|
||||||
if (NameLength >= BlockedFileNameLength &&
|
|
||||||
_wcsnicmp(&NameBuffer[NameLength - BlockedFileNameLength], BlockedFileName,
|
|
||||||
BlockedFileNameLength) == 0)
|
|
||||||
{
|
|
||||||
log_current_process_name();
|
|
||||||
return STATUS_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
|
||||||
NOTHING;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NtCreateFileOrig(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize,
|
|
||||||
FileAttributes,
|
|
||||||
ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID HvEptHookWriteAbsoluteJump(uint8_t* TargetBuffer, SIZE_T TargetAddress)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Use 'push ret' instead of 'jmp qword[rip+0]',
|
|
||||||
* Because 'jmp qword[rip+0]' will read hooked page 8bytes.
|
|
||||||
*
|
|
||||||
* 14 bytes hook:
|
|
||||||
* 0x68 0x12345678 ......................push 'low 32bit of TargetAddress'
|
|
||||||
* 0xC7 0x44 0x24 0x04 0x12345678........mov dword[rsp + 4], 'high 32bit of TargetAddress'
|
|
||||||
* 0xC3..................................ret
|
|
||||||
*/
|
|
||||||
|
|
||||||
UINT32 Low32;
|
|
||||||
UINT32 High32;
|
|
||||||
|
|
||||||
Low32 = (UINT32)TargetAddress;
|
|
||||||
High32 = (UINT32)(TargetAddress >> 32);
|
|
||||||
|
|
||||||
/* push 'low 32bit of TargetAddress' */
|
|
||||||
TargetBuffer[0] = 0x68;
|
|
||||||
*((UINT32*)&TargetBuffer[1]) = Low32;
|
|
||||||
|
|
||||||
/* mov dword[rsp + 4], 'high 32bit of TargetAddress' */
|
|
||||||
*((UINT32*)&TargetBuffer[5]) = 0x042444C7;
|
|
||||||
*((UINT32*)&TargetBuffer[9]) = High32;
|
|
||||||
|
|
||||||
/* ret */
|
|
||||||
TargetBuffer[13] = 0xC3;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* HookCreateFile(hypervisor& hypervisor)
|
|
||||||
{
|
|
||||||
const uint8_t fixup[] = {
|
|
||||||
0x48, 0x81, 0xEC, 0x88, 0x00, 0x00, 0x00, 0x33, 0xC0, 0x48, 0x89, 0x44, 0x24, 0x78
|
|
||||||
};
|
|
||||||
|
|
||||||
auto* target = reinterpret_cast<uint8_t*>(&NtCreateFile);
|
|
||||||
if (memcmp(target, fixup, sizeof(fixup)) != 0)
|
|
||||||
{
|
|
||||||
debug_log("Fixup is invalid\n");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* trampoline = static_cast<uint8_t*>(memory::allocate_non_paged_memory(sizeof(fixup) + 14));
|
|
||||||
if (!trampoline)
|
|
||||||
{
|
|
||||||
debug_log("Failed to allocate trampoline\n");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(trampoline, fixup, sizeof(fixup));
|
|
||||||
|
|
||||||
|
|
||||||
HvEptHookWriteAbsoluteJump(trampoline + sizeof(fixup),
|
|
||||||
size_t(target) + sizeof(fixup));
|
|
||||||
|
|
||||||
/* Let the hook function call the original function */
|
|
||||||
NtCreateFileOrig = reinterpret_cast<decltype(NtCreateFileOrig)>(trampoline);
|
|
||||||
|
|
||||||
/* Write the absolute jump to our shadow page memory to jump to our hook. */
|
|
||||||
uint8_t hook[14];
|
|
||||||
HvEptHookWriteAbsoluteJump(hook, reinterpret_cast<size_t>(NtCreateFileHook));
|
|
||||||
|
|
||||||
hypervisor.install_ept_hook(target, hook, sizeof(hook));
|
|
||||||
return trampoline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class global_driver
|
class global_driver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -168,14 +19,12 @@ public:
|
|||||||
, irp_(driver_object, DEV_NAME, DOS_DEV_NAME)
|
, irp_(driver_object, DEV_NAME, DOS_DEV_NAME)
|
||||||
{
|
{
|
||||||
debug_log("Driver started\n");
|
debug_log("Driver started\n");
|
||||||
this->trampoline_ = HookCreateFile(this->hypervisor_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~global_driver()
|
~global_driver()
|
||||||
{
|
{
|
||||||
debug_log("Unloading driver\n");
|
debug_log("Unloading driver\n");
|
||||||
this->hypervisor_.disable_all_ept_hooks();
|
this->hypervisor_.disable_all_ept_hooks();
|
||||||
memory::free_non_paged_memory(this->trampoline_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
global_driver(global_driver&&) noexcept = delete;
|
global_driver(global_driver&&) noexcept = delete;
|
||||||
@ -193,7 +42,6 @@ private:
|
|||||||
hypervisor hypervisor_{};
|
hypervisor hypervisor_{};
|
||||||
sleep_callback sleep_callback_{};
|
sleep_callback sleep_callback_{};
|
||||||
irp irp_{};
|
irp irp_{};
|
||||||
void* trampoline_{nullptr};
|
|
||||||
|
|
||||||
void sleep_notification(const sleep_callback::type type)
|
void sleep_notification(const sleep_callback::type type)
|
||||||
{
|
{
|
||||||
|
@ -10,12 +10,12 @@
|
|||||||
#define MTRR_PAGE_SIZE 4096
|
#define MTRR_PAGE_SIZE 4096
|
||||||
#define MTRR_PAGE_MASK (~(MTRR_PAGE_SIZE-1))
|
#define MTRR_PAGE_MASK (~(MTRR_PAGE_SIZE-1))
|
||||||
|
|
||||||
#define ADDRMASK_EPT_PML1_OFFSET(_VAR_) (_VAR_ & 0xFFFULL)
|
#define ADDRMASK_EPT_PML1_OFFSET(_VAR_) ((_VAR_) & 0xFFFULL)
|
||||||
|
|
||||||
#define ADDRMASK_EPT_PML1_INDEX(_VAR_) ((_VAR_ & 0x1FF000ULL) >> 12)
|
#define ADDRMASK_EPT_PML1_INDEX(_VAR_) (((_VAR_) & 0x1FF000ULL) >> 12)
|
||||||
#define ADDRMASK_EPT_PML2_INDEX(_VAR_) ((_VAR_ & 0x3FE00000ULL) >> 21)
|
#define ADDRMASK_EPT_PML2_INDEX(_VAR_) (((_VAR_) & 0x3FE00000ULL) >> 21)
|
||||||
#define ADDRMASK_EPT_PML3_INDEX(_VAR_) ((_VAR_ & 0x7FC0000000ULL) >> 30)
|
#define ADDRMASK_EPT_PML3_INDEX(_VAR_) (((_VAR_) & 0x7FC0000000ULL) >> 30)
|
||||||
#define ADDRMASK_EPT_PML4_INDEX(_VAR_) ((_VAR_ & 0xFF8000000000ULL) >> 39)
|
#define ADDRMASK_EPT_PML4_INDEX(_VAR_) (((_VAR_) & 0xFF8000000000ULL) >> 39)
|
||||||
|
|
||||||
namespace vmx
|
namespace vmx
|
||||||
{
|
{
|
||||||
@ -316,10 +316,10 @@ namespace vmx
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto* pml2 = reinterpret_cast<pml2_ptr*>(pml2_entry);
|
const auto* pml2 = reinterpret_cast<pml2_ptr*>(pml2_entry);
|
||||||
auto* pml1 = static_cast<epte*>(memory::get_virtual_address(pml2->page_frame_number * PAGE_SIZE));
|
auto* pml1 = this->find_pml1_table(pml2->page_frame_number * PAGE_SIZE);
|
||||||
if (!pml1)
|
if (!pml1)
|
||||||
{
|
{
|
||||||
pml1 = this->find_pml1_table(pml2->page_frame_number * PAGE_SIZE);
|
pml1 = static_cast<epte*>(memory::get_virtual_address(pml2->page_frame_number * PAGE_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pml1)
|
if (!pml1)
|
||||||
|
@ -159,7 +159,8 @@ bool hypervisor::is_enabled() const
|
|||||||
return is_hypervisor_present();
|
return is_hypervisor_present();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hypervisor::install_ept_hook(const void* destination, const void* source, const size_t length, vmx::ept_translation_hint* translation_hint)
|
bool hypervisor::install_ept_hook(const void* destination, const void* source, const size_t length,
|
||||||
|
vmx::ept_translation_hint* translation_hint)
|
||||||
{
|
{
|
||||||
volatile long failures = 0;
|
volatile long failures = 0;
|
||||||
thread::dispatch_on_all_cores([&]()
|
thread::dispatch_on_all_cores([&]()
|
||||||
@ -573,6 +574,8 @@ void vmx_dispatch_vm_exit(vmx::guest_context& guest_context, const vmx::state& v
|
|||||||
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:
|
||||||
|
// break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1005,7 +1008,8 @@ void hypervisor::free_vm_states()
|
|||||||
this->vm_state_count_ = 0;
|
this->vm_state_count_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hypervisor::try_install_ept_hook_on_core(const void* destination, const void* source, const size_t length, vmx::ept_translation_hint* translation_hint)
|
bool hypervisor::try_install_ept_hook_on_core(const void* destination, const void* source, const size_t length,
|
||||||
|
vmx::ept_translation_hint* translation_hint)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -1024,7 +1028,8 @@ bool hypervisor::try_install_ept_hook_on_core(const void* destination, const voi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hypervisor::install_ept_hook_on_core(const void* destination, const void* source, const size_t length, vmx::ept_translation_hint* translation_hint)
|
void hypervisor::install_ept_hook_on_core(const void* destination, const void* source, const size_t length,
|
||||||
|
vmx::ept_translation_hint* translation_hint)
|
||||||
{
|
{
|
||||||
auto* vm_state = this->get_current_vm_state();
|
auto* vm_state = this->get_current_vm_state();
|
||||||
if (!vm_state)
|
if (!vm_state)
|
||||||
|
@ -75,6 +75,15 @@ void unsafe_main(const int /*argc*/, char* /*argv*/[])
|
|||||||
hook_request.source_data = buffer;
|
hook_request.source_data = buffer;
|
||||||
hook_request.source_data_size = sizeof(buffer);
|
hook_request.source_data_size = sizeof(buffer);
|
||||||
|
|
||||||
|
input.assign(reinterpret_cast<uint8_t*>(&hook_request),
|
||||||
|
reinterpret_cast<uint8_t*>(&hook_request) + sizeof(hook_request));
|
||||||
|
|
||||||
|
(void)driver_device.send(HOOK_DRV_IOCTL, input);
|
||||||
|
|
||||||
|
hook_request.target_address = (void*)0x47F6C7;
|
||||||
|
hook_request.source_data = buffer;
|
||||||
|
hook_request.source_data_size = sizeof(buffer);
|
||||||
|
|
||||||
input.assign(reinterpret_cast<uint8_t*>(&hook_request),
|
input.assign(reinterpret_cast<uint8_t*>(&hook_request),
|
||||||
reinterpret_cast<uint8_t*>(&hook_request) + sizeof(hook_request));
|
reinterpret_cast<uint8_t*>(&hook_request) + sizeof(hook_request));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user