### Start Virtual Machine Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8cpp_source.html Initiates the virtualization process for the current processor using the provided context. ```cpp _Use_decl_annotations_ static NTSTATUS VmpStartVm(void *context) { PAGED_CODE(); HYPERPLATFORM_LOG_INFO("Initializing VMX for the processor %lu.", KeGetCurrentProcessorNumberEx(nullptr)); const auto ok = AsmInitializeVm(VmpInitializeVm, context); NT_ASSERT(VmpIsHyperPlatformInstalled() == ok); if (!ok) { return STATUS_UNSUCCESSFUL; } HYPERPLATFORM_LOG_INFO("Initialized successfully."); return STATUS_SUCCESS; } ``` -------------------------------- ### Check HyperPlatform Installation Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8cpp_source.html Verifies if HyperPlatform is currently installed by checking CPUID features. ```cpp _Use_decl_annotations_ static bool VmpIsHyperPlatformInstalled() { PAGED_CODE(); int cpu_info[4] = {}; __cpuid(cpu_info, 1); const CpuFeaturesEcx cpu_features = {static_cast(cpu_info[2])}; if (!cpu_features.fields.not_used) { return false; } __cpuid(cpu_info, kHyperVCpuidInterface); return cpu_info[0] == 'PpyH'; } ``` -------------------------------- ### VmHotplugCallback Implementation Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8cpp_source.html Handles the virtualization of a newly added processor by switching affinity and starting the VM. ```cpp 997 VmHotplugCallback(const PROCESSOR_NUMBER &proc_num) { 998 PAGED_CODE(); 999 1000 // Switch to the processor 0 to get SharedProcessorData 1001 GROUP_AFFINITY affinity = {}; 1002 GROUP_AFFINITY previous_affinity = {}; 1003 KeSetSystemGroupAffinityThread(&affinity, &previous_affinity); 1004 1005 SharedProcessorData *shared_data = nullptr; 1006 auto status = 1007 UtilVmCall(HypercallNumber::kGetSharedProcessorData, &shared_data); 1008 1009 KeSetSystemGroupAffinityThread(&affinity, &previous_affinity); 1010 1011 if (!NT_SUCCESS(status)) { 1012 return status; 1013 } 1014 if (!shared_data) { 1015 return STATUS_UNSUCCESSFUL; 1016 } 1017 1018 // Switch to the newly added processor to virtualize it 1019 affinity.Group = proc_num.Group; 1020 affinity.Mask = 1ull << proc_num.Number; 1021 KeSetSystemGroupAffinityThread(&affinity, &previous_affinity); 1022 1023 status = VmpStartVm(shared_data); 1024 1025 KeRevertToUserGroupAffinityThread(&previous_affinity); 1026 return status; 1027 } 1028 1029 } // extern "C" ``` -------------------------------- ### Initialize Log Buffer Flush Thread Source: https://tandasat.github.io/HyperPlatform/doxygen/log_8cpp_source.html Initializes a system thread to handle log buffer flushing and waits for it to start. ```cpp 280 FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, nullptr, 0); 281 if (!NT_SUCCESS(status)) { 282 return status; 283 } 284 285 // Initialize a log buffer flush thread. 286 info->buffer_flush_thread_should_be_alive = true; 287 status = PsCreateSystemThread(&info->buffer_flush_thread_handle, GENERIC_ALL, 288 nullptr, nullptr, nullptr, 289 LogpBufferFlushThreadRoutine, info); 290 if (!NT_SUCCESS(status)) { 291 ZwClose(info->log_file_handle); 292 info->log_file_handle = nullptr; 293 info->buffer_flush_thread_should_be_alive = false; 294 return status; 295 } 296 297 // Wait until the thread has started 298 while (!info->buffer_flush_thread_started) { 299 LogpSleep(100); 300 } 301 return status; 302 } ``` -------------------------------- ### Internal VM Function Prototypes Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8cpp_source.html Declarations for internal functions used to manage VMX mode, VMCS setup, and processor data initialization. ```cpp _IRQL_requires_max_(PASSIVE_LEVEL) static bool VmpIsVmxAvailable(); _IRQL_requires_max_(PASSIVE_LEVEL) static NTSTATUS VmpSetLockBitCallback(_In_opt_ void *context); _IRQL_requires_max_( PASSIVE_LEVEL) static SharedProcessorData *VmpInitializeSharedData(); _IRQL_requires_max_(PASSIVE_LEVEL) static void *VmpBuildMsrBitmap(); _IRQL_requires_max_(PASSIVE_LEVEL) static UCHAR *VmpBuildIoBitmaps(); _IRQL_requires_max_(PASSIVE_LEVEL) static NTSTATUS VmpStartVm(_In_opt_ void *context); _IRQL_requires_max_(PASSIVE_LEVEL) static void VmpInitializeVm( _In_ ULONG_PTR guest_stack_pointer, _In_ ULONG_PTR guest_instruction_pointer, _In_opt_ void *context); _IRQL_requires_max_(PASSIVE_LEVEL) static bool VmpEnterVmxMode( _Inout_ ProcessorData *processor_data); _IRQL_requires_max_(PASSIVE_LEVEL) static bool VmpInitializeVmcs( _Inout_ ProcessorData *processor_data); _IRQL_requires_max_(PASSIVE_LEVEL) static bool VmpSetupVmcs( _In_ const ProcessorData *processor_data, _In_ ULONG_PTR guest_stack_pointer, _In_ ULONG_PTR guest_instruction_pointer, _In_ ULONG_PTR vmm_stack_pointer); _IRQL_requires_max_(PASSIVE_LEVEL) static void VmpLaunchVm(); _IRQL_requires_max_(PASSIVE_LEVEL) static ULONG VmpGetSegmentAccessRight(_In_ USHORT segment_selector); _IRQL_requires_max_(PASSIVE_LEVEL) static ULONG_PTR VmpGetSegmentBase(_In_ ULONG_PTR gdt_base, _In_ USHORT segment_selector); _IRQL_requires_max_(PASSIVE_LEVEL) static SegmentDescriptor *VmpGetSegmentDescriptor(_In_ ULONG_PTR descriptor_table_base, _In_ USHORT segment_selector); _IRQL_requires_max_(PASSIVE_LEVEL) static ULONG_PTR VmpGetSegmentBaseByDescriptor( _In_ const SegmentDescriptor *segment_descriptor); _IRQL_requires_max_(PASSIVE_LEVEL) static ULONG VmpAdjustControlValue(_In_ Msr msr, _In_ ULONG requested_value); _IRQL_requires_max_(PASSIVE_LEVEL) static NTSTATUS VmpStopVm(_In_opt_ void *context); _IRQL_requires_max_(PASSIVE_LEVEL) static void VmpFreeProcessorData( _In_opt_ ProcessorData *processor_data); _IRQL_requires_max_(PASSIVE_LEVEL) static void VmpFreeSharedData( _In_ ProcessorData *processor_data); _IRQL_requires_max_(PASSIVE_LEVEL) static bool VmpIsHyperPlatformInstalled(); ``` -------------------------------- ### VM Initialization and Entry Point Source: https://tandasat.github.io/HyperPlatform/doxygen/x64_8asm_source.html Procedures for initializing the virtual machine and handling the VM entry point. ```asm AsmInitializeVm PROC ; RSP is not 16 bit aligned when it gets called, but the following odd ; number (17 times) of push makes RSP 16 bit aligned. pushfq PUSHAQ ; -8 * 16 mov rax, rcx mov r8, rdx mov rdx, asmResumeVm mov rcx, rsp sub rsp, 20h call rax ; vm_initialization_routine(rsp, asmResumeVm, context) add rsp, 20h POPAQ popfq xor rax, rax ; return false ret ; This is where the virtualized guest start to execute after successful ; vmlaunch. asmResumeVm: nop ; keep this nop for ease of debugging POPAQ popfq sub rsp, 8 ; align RSP ASM_DUMP_REGISTERS add rsp, 8 ; restore RSP xor rax, rax inc rax ; return true ret AsmInitializeVm ENDP ; void __stdcall AsmVmmEntryPoint(); AsmVmmEntryPoint PROC ; No need to save the flag registers since it is restored from the VMCS at ; the time of vmresume. PUSHAQ ; -8 * 16 mov rcx, rsp ; save volatile XMM registers sub rsp, 60h movaps xmmword ptr [rsp + 0h], xmm0 movaps xmmword ptr [rsp + 10h], xmm1 movaps xmmword ptr [rsp + 20h], xmm2 movaps xmmword ptr [rsp + 30h], xmm3 movaps xmmword ptr [rsp + 40h], xmm4 movaps xmmword ptr [rsp + 50h], xmm5 sub rsp, 20h call VmmVmExitHandler ; bool vm_continue = VmmVmExitHandler(guest_context); add rsp, 20h ; restore XMM registers movaps xmm0, xmmword ptr [rsp + 0h] ``` -------------------------------- ### Get Kernel CR3 Source: https://tandasat.github.io/HyperPlatform/doxygen/vmm_8cpp_source.html Retrieves the kernel CR3 register value. ```cpp static ULONG_PTR VmmpGetKernelCr3() ``` -------------------------------- ### Get Segment Limit Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8cpp_source.html Retrieves the limit of a segment given its selector. ```cpp ULONG GetSegmentLimit(_In_ ULONG selector) ``` -------------------------------- ### Initialize Virtual Machine Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8cpp_source.html Allocates necessary structures, initializes the VMCS, and sets up the EPT for the current processor. ```cpp _Use_decl_annotations_ static void VmpInitializeVm( ULONG_PTR guest_stack_pointer, ULONG_PTR guest_instruction_pointer, void *context) { PAGED_CODE(); const auto shared_data = reinterpret_cast(context); if (!shared_data) { return; } // Allocate related structures const auto processor_data = reinterpret_cast(ExAllocatePoolWithTag( NonPagedPool, sizeof(ProcessorData), kHyperPlatformCommonPoolTag)); if (!processor_data) { return; } RtlZeroMemory(processor_data, sizeof(ProcessorData)); processor_data->shared_data = shared_data; InterlockedIncrement(&processor_data->shared_data->reference_count); // Set up EPT processor_data->ept_data = EptInitialization(); if (!processor_data->ept_data) { goto ReturnFalse; } // Allocate other processor data fields processor_data->vmm_stack_limit = UtilAllocateContiguousMemory(KERNEL_STACK_SIZE); if (!processor_data->vmm_stack_limit) { goto ReturnFalse; } RtlZeroMemory(processor_data->vmm_stack_limit, KERNEL_STACK_SIZE); processor_data->vmcs_region = reinterpret_cast(ExAllocatePoolWithTag( NonPagedPool, kVmxMaxVmcsSize, kHyperPlatformCommonPoolTag)); if (!processor_data->vmcs_region) { goto ReturnFalse; } RtlZeroMemory(processor_data->vmcs_region, kVmxMaxVmcsSize); processor_data->vmxon_region = reinterpret_cast(ExAllocatePoolWithTag( NonPagedPool, kVmxMaxVmcsSize, kHyperPlatformCommonPoolTag)); ``` -------------------------------- ### Global Functions - O Source: https://tandasat.github.io/HyperPlatform/doxygen/globals_func_o.html List of global functions starting with O available in the HyperPlatform project. ```APIDOC ## Global Functions (O) ### Functions - **operator delete()** - Defined in: kernel_stl.cpp - **operator new()** - Defined in: kernel_stl.cpp - **operator<<()** - Defined in: ia32_type.h - **operator|=()** - Defined in: util.h ``` -------------------------------- ### VM Initialization Routine Source: https://tandasat.github.io/HyperPlatform/doxygen/x86_8asm_source.html Initializes the virtual machine and defines the resume point for guest execution. ```asm AsmInitializeVm PROC vm_initialization_routine, context pushfd pushad ; -4 * 8 mov ecx, esp ; esp ; vm_initialization_routine(rsp, asmResumeVm, context) push context push asmResumeVm push ecx call vm_initialization_routine popad popfd xor eax, eax ; return false ret ; This is where the virtualized guest start to execute after successful ; vmlaunch. asmResumeVm: nop ; keep this nop for ease of debugging popad popfd ASM_DUMP_REGISTERS xor eax, eax inc eax ; return true ret AsmInitializeVm ENDP ``` -------------------------------- ### Get Physical Memory Ranges Source: https://tandasat.github.io/HyperPlatform/doxygen/util_8cpp_source.html Returns the cached physical memory descriptor structure. ```cpp /*_Use_decl_annotations_*/ const PhysicalMemoryDescriptor * UtilGetPhysicalMemoryRanges() { return g_utilp_physical_memory_ranges; } ``` -------------------------------- ### Initialize VM Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8cpp_source.html Initializes the virtual machine using a provided routine. ```cpp bool __stdcall AsmInitializeVm(_In_ void(*vm_initialization_routine)(_In_ ULONG_PTR, _In_ ULONG_PTR, _In_opt_ void *), _In_opt_ void *context) ``` -------------------------------- ### Get System Procedure Address Source: https://tandasat.github.io/HyperPlatform/doxygen/util_8cpp_source.html Wraps MmGetSystemRoutineAddress to retrieve the address of a system function by name. ```cpp 502 _Use_decl_annotations_ void *UtilGetSystemProcAddress( 503 const wchar_t *proc_name) { 504 PAGED_CODE(); 505 506 UNICODE_STRING proc_name_U = {}; 507 RtlInitUnicodeString(&proc_name_U, proc_name); 508 return MmGetSystemRoutineAddress(&proc_name_U); 509 } ``` -------------------------------- ### VmInitialization Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8h_source.html Initializes the virtual machine environment by virtualizing all processors. ```APIDOC ## NTSTATUS VmInitialization() ### Description Virtualizes all processors in the system. ### Parameters None ### Returns - **NTSTATUS** - Returns STATUS_SUCCESS if the initialization was successful, otherwise returns an error code. ``` -------------------------------- ### Get Current Performance Time Source: https://tandasat.github.io/HyperPlatform/doxygen/performance_8cpp_source.html Returns the current time value used for performance measurement. ```cpp ULONG64 PerfGetTime() ``` -------------------------------- ### AsmInitializeVm Source: https://tandasat.github.io/HyperPlatform/doxygen/asm_8h.html Initializes the Virtual Machine environment. ```APIDOC ## bool AsmInitializeVm(void(*vm_initialization_routine)(ULONG_PTR, ULONG_PTR, void*), void *context) ### Description A wrapper function used to execute the VMX-mode initialization routine. ### Parameters - **vm_initialization_routine** (function pointer) - Required - The routine to execute for entering VMX-mode. - **context** (void*) - Optional - A context parameter passed to the initialization routine. ### Returns - **bool** - Returns true if the initialization routine executed successfully. ``` -------------------------------- ### LogInitialization() Source: https://tandasat.github.io/HyperPlatform/doxygen/globals_l.html Initializes the logging system. ```APIDOC ## LogInitialization() ### Description Initializes the logging system for HyperPlatform. ### Definition void LogInitialization(); ``` -------------------------------- ### Execute VMLAUNCH Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8cpp_source.html Attempts to launch the virtual machine and logs errors if the instruction fails. ```cpp // Executes vmlaunch 779 _Use_decl_annotations_ static void VmpLaunchVm() { 780 PAGED_CODE(); 781 782 auto error_code = UtilVmRead(VmcsField::kVmInstructionError); 783 if (error_code) { 784 HYPERPLATFORM_LOG_WARN("VM_INSTRUCTION_ERROR = %Iu", error_code); 785 } 786 787 auto vmx_status = static_cast(__vmx_vmlaunch()); 788 789 // Here should not executed with successful vmlaunch. Instead, the context 790 // jumps to an address specified by GUEST_RIP. 791 if (vmx_status == VmxStatus::kErrorWithStatus) { 792 error_code = UtilVmRead(VmcsField::kVmInstructionError); 793 HYPERPLATFORM_LOG_ERROR("VM_INSTRUCTION_ERROR = %Iu", error_code); 794 } 795 HYPERPLATFORM_COMMON_DBG_BREAK(); 796 } ``` -------------------------------- ### Get Segment Base Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8cpp_source.html Retrieves the base address of a segment given the GDT base and segment selector. ```cpp static ULONG_PTR VmpGetSegmentBase(_In_ ULONG_PTR gdt_base, _In_ USHORT segment_selector) ``` -------------------------------- ### Initialize VMM Stack and Launch VM Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8cpp_source.html Configures the VMM stack memory layout and initiates the virtualization process via VmpLaunchVm. ```cpp 403 NonPagedPool, kVmxMaxVmcsSize, kHyperPlatformCommonPoolTag)); 404 if (!processor_data->vmxon_region) { 405 goto ReturnFalse; 406 } 407 RtlZeroMemory(processor_data->vmxon_region, kVmxMaxVmcsSize); 408 409 // Initialize stack memory for VMM like this: 410 // 411 // (High) 412 // +------------------+ <- vmm_stack_region_base (eg, AED37000) 413 // | processor_data | <- vmm_stack_data (eg, AED36FFC) 414 // +------------------+ 415 // | MAXULONG_PTR | <- vmm_stack_base (initial SP)(eg, AED36FF8) 416 // +------------------+ v 417 // | | v 418 // | (VMM Stack) | v (grow) 419 // | | v 420 // +------------------+ <- vmm_stack_limit (eg, AED34000) 421 // (Low) 422 const auto vmm_stack_region_base = 423 reinterpret_cast(processor_data->vmm_stack_limit) + 424 KERNEL_STACK_SIZE; 425 const auto vmm_stack_data = vmm_stack_region_base - sizeof(void *); 426 const auto vmm_stack_base = vmm_stack_data - sizeof(void *); 427 HYPERPLATFORM_LOG_DEBUG("vmm_stack_limit = %p", 428 processor_data->vmm_stack_limit); 429 HYPERPLATFORM_LOG_DEBUG("vmm_stack_region_base = %016Ix", 430 vmm_stack_region_base); 431 HYPERPLATFORM_LOG_DEBUG("vmm_stack_data = %016Ix", vmm_stack_data); 432 HYPERPLATFORM_LOG_DEBUG("vmm_stack_base = %016Ix", vmm_stack_base); 433 HYPERPLATFORM_LOG_DEBUG("processor_data = %p stored at %016Ix", 434 processor_data, vmm_stack_data); 435 HYPERPLATFORM_LOG_DEBUG("guest_stack_pointer = %016Ix", 436 guest_stack_pointer); 437 HYPERPLATFORM_LOG_DEBUG("guest_inst_pointer = %016Ix", 438 guest_instruction_pointer); 439 *reinterpret_cast(vmm_stack_base) = MAXULONG_PTR; 440 *reinterpret_cast(vmm_stack_data) = processor_data; 441 442 // Set up VMCS 443 if (!VmpEnterVmxMode(processor_data)) { 444 goto ReturnFalse; 445 } 446 if (!VmpInitializeVmcs(processor_data)) { 447 goto ReturnFalseWithVmxOff; 448 } 449 if (!VmpSetupVmcs(processor_data, guest_stack_pointer, 450 guest_instruction_pointer, vmm_stack_base)) { 451 goto ReturnFalseWithVmxOff; 452 } 453 454 // Do virtualize the processor 455 VmpLaunchVm(); 456 457 // Here is not be executed with successful vmlaunch. Instead, the context 458 // jumps to an address specified by guest_instruction_pointer. 459 460 ReturnFalseWithVmxOff:; 461 __vmx_off(); 462 463 ReturnFalse:; 464 VmpFreeProcessorData(processor_data); 465 } ``` -------------------------------- ### LogInitialization Source: https://tandasat.github.io/HyperPlatform/doxygen/log_8h_source.html Initializes the logging system with a specified flag and optional file path. ```APIDOC ## LogInitialization ### Description Initializes the logging system. This function must be called at PASSIVE_LEVEL. ### Parameters - **flag** (ULONG) - Required - Configuration flags for the logging system. - **file_path** (const wchar_t *) - Optional - Path to the log file. ### Returns - **NTSTATUS** - Returns STATUS_SUCCESS on success, or an error code. ``` -------------------------------- ### Bit-field and Register Definitions Source: https://tandasat.github.io/HyperPlatform/doxygen/ia32__type_8h_source.html Examples of various bit-field definitions and register structures used for hardware interaction. ```cpp Cpuid80000008Eax::physical_address_bits ULONG32 physical_address_bits [0:7] ``` ```cpp VmxSecondaryProcessorBasedControls::ept_violation_ve unsigned ept_violation_ve [18] ``` ```cpp Ia32VmxEptVpidCapMsr::support_pdpte_1_gb_pages unsigned support_pdpte_1_gb_pages [17] ``` ```cpp EptPdEntry::pt_address ULONG64 pt_address [12:48-1] ``` ```cpp GpRegistersX64::r14 ULONG_PTR r14 ``` ```cpp SegmentDescriptor::l ULONG64 l 64-bit code segment (IA-32e mode only) ``` ```cpp Cr0::am unsigned am [18] Alignment Mask ``` ```cpp HardwarePteX64::owner ULONG64 owner [2] ``` ```cpp VmxVmEntryControls::reserved2 unsigned reserved2 [3:8] ``` ```cpp MovDrQualification::debugl_register ULONG_PTR debugl_register [0:2] ``` ```cpp Ia32VmxEptVpidCapMsr::all unsigned __int64 all ``` ```cpp VmxVmEntryControls::deactivate_dual_monitor_treatment unsigned deactivate_dual_monitor_treatment [11] ``` ```cpp Cr0::ts unsigned ts [3] Task Switched FLAG ``` ```cpp Ia32VmxBasicMsr::revision_identifier unsigned revision_identifier [0:30] ``` ```cpp VmExitInformation::vm_exit_from_vmx_root unsigned short vm_exit_from_vmx_root [29] ``` ```cpp CpuFeaturesEcx::cid ULONG32 cid [10] L1 context ID ``` ```cpp CpuFeaturesEdx::psn ULONG32 psn [18] Processor Serial Number ``` ```cpp VmxProcessorBasedControls::monitor_trap_flag unsigned monitor_trap_flag [27] ``` ```cpp Cr4::reserved1 unsigned reserved1 [11:12] ``` ```cpp EptPdptEntry::read_access ULONG64 read_access [0] ``` ```cpp LdtrOrTrInstInformation::all ULONG32 all ``` ```cpp HardwarePteARM::unknown1 ULONG unknown1 ``` ```cpp EptPdptEntry::ignored2 ULONG64 ignored2 [11] ``` ```cpp Ia32VmxMiscMsr::supported_vmwrite_vm_exit_information unsigned supported_vmwrite_vm_exit_information [29] ``` ```cpp VmxPinBasedControls::virtual_nmis unsigned virtual_nmis [5] ``` ```cpp VmxVmExitControls::all unsigned int all ``` ```cpp GpRegistersX64::r12 ULONG_PTR r12 ``` ```cpp EptPdptSuperPageEntry::reserved2 ULONG64 reserved2 [48:51] ``` ```cpp FlagRegister::sf ULONG_PTR sf [7] Sign flag ``` ```cpp VmxProcessorBasedControls::cr8_load_exiting unsigned cr8_load_exiting [19] ``` ```cpp EptPdEntry::execute_access_for_user_mode_linear_address ULONG64 execute_access_for_user_mode_linear_address [10] ``` ```cpp HardwarePteX86Pae::page_frame_number ULONG64 page_frame_number [12:37] ``` ```cpp Ia32MtrrDefaultTypeMsr::default_mtemory_type ULONG64 default_mtemory_type ``` ```cpp EptViolationQualification::user_mode_linear_address ULONG64 user_mode_linear_address [9] ``` ```cpp Dr6::b1 unsigned b1 [1] Breakpoint Condition Detected 1 ``` ```cpp CpuFeaturesEcx::all ULONG32 all ``` ```cpp LdtrOrTrInstInformation::register1 ULONG32 register1 [3:6] ``` ```cpp EptViolationQualification::caused_by_translation ULONG64 caused_by_translation [8] ``` ```cpp InvEptOrPcidOrVpidInstInformation::base_register_invalid ULONG32 base_register_invalid [27] ``` ```cpp EptPtEntry::execute_access ULONG64 execute_access [2] ``` -------------------------------- ### Get PXE Address Source: https://tandasat.github.io/HyperPlatform/doxygen/util_8cpp_source.html Calculates the address of the Page Map Level 4 (PXE) entry for a given virtual address. ```cpp 554 _Use_decl_annotations_ static HardwarePte *UtilpAddressToPxe( 555 const void *address) { 556 const auto addr = reinterpret_cast(address); 557 const auto pxe_index = (addr >> g_utilp_pxi_shift) & g_utilp_pxi_mask; 558 const auto offset = pxe_index * sizeof(HardwarePte); 559 return reinterpret_cast(g_utilp_pxe_base + offset); 560 } ``` -------------------------------- ### VM and VMX Assembly Prototypes Source: https://tandasat.github.io/HyperPlatform/doxygen/asm_8h_source.html Prototypes for initializing the virtual machine, defining the entry point, and executing VMX calls. ```cpp bool __stdcall AsmInitializeVm( _In_ void (*vm_initialization_routine)(_In_ ULONG_PTR, _In_ ULONG_PTR, _In_opt_ void *), _In_opt_ void *context); void __stdcall AsmVmmEntryPoint(); unsigned char __stdcall AsmVmxCall(_In_ ULONG_PTR hypercall_number, _In_opt_ void *context); ``` -------------------------------- ### Log Initialization Routine Source: https://tandasat.github.io/HyperPlatform/doxygen/log_8cpp_source.html Initializes the logging system and prepares the log buffer if a file path is provided. ```cpp _Use_decl_annotations_ NTSTATUS LogInitialization(ULONG flag, const wchar_t *log_file_path) { PAGED_CODE(); auto status = STATUS_SUCCESS; g_logp_debug_flag = flag; // Initialize a log file if a log file path is specified. bool need_reinitialization = false; if (log_file_path) { status = LogpInitializeBufferInfo(log_file_path, &g_logp_log_buffer_info); if (status == STATUS_REINITIALIZATION_NEEDED) { need_reinitialization = true; } else if (!NT_SUCCESS(status)) { return status; } } // Test the log. status = HYPERPLATFORM_LOG_INFO("Log has been %sinitialized.", (need_reinitialization ? "partially " : "")); if (!NT_SUCCESS(status)) { goto Fail; } HYPERPLATFORM_LOG_DEBUG("Info= %p, Buffer= %p %p, File= %S", &g_logp_log_buffer_info, g_logp_log_buffer_info.log_buffer1, g_logp_log_buffer_info.log_buffer2, log_file_path); return (need_reinitialization ? STATUS_REINITIALIZATION_NEEDED : STATUS_SUCCESS); Fail:; if (log_file_path) { LogpFinalizeBufferInfo(&g_logp_log_buffer_info); } return status; } ``` -------------------------------- ### Get Memory Type from MTRRs Source: https://tandasat.github.io/HyperPlatform/doxygen/ept_8cpp_source.html Resolves the memory type for a physical address by checking stored MTRR entries against precedence rules. ```cpp _Use_decl_annotations_ static memory_type EptpGetMemoryType( ULONG64 physical_address) { // Indicate that MTRR is not defined (as a default) UCHAR result_type = MAXUCHAR; // Looks for MTRR that includes the specified physical_address for (const auto mtrr_entry : g_eptp_mtrr_entries) { if (!mtrr_entry.enabled) { // Reached out the end of stored MTRRs break; } if (!UtilIsInBounds(physical_address, mtrr_entry.range_base, mtrr_entry.range_end)) { // This MTRR does not describe a memory type of the physical_address continue; } // See: MTRR Precedences if (mtrr_entry.fixedMtrr) { // If a fixed MTRR describes a memory type, it is priority result_type = mtrr_entry.type; break; } if (mtrr_entry.type == static_cast(memory_type::kUncacheable)) { // If a memory type is UC, it is priority. Do not continue to search as // UC has the highest priority result_type = mtrr_entry.type; break; } if (result_type == static_cast(memory_type::kWriteThrough) || mtrr_entry.type == static_cast(memory_type::kWriteThrough)) { if (result_type == static_cast(memory_type::kWriteBack)) { // If two or more MTRRs describes an over-wrapped memory region, and // one is WT and the other one is WB, use WT. However, look for other // MTRRs, as the other MTRR specifies the memory address as UC, which is // priority. ``` -------------------------------- ### Initialize Virtual Machine Monitor Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8cpp_source.html Performs the main initialization sequence, including VMX availability checks, shared data allocation, and processor virtualization. ```cpp _Use_decl_annotations_ NTSTATUS VmInitialization() { PAGED_CODE(); if (VmpIsHyperPlatformInstalled()) { return STATUS_CANCELLED; } if (!VmpIsVmxAvailable()) { return STATUS_HV_FEATURE_UNAVAILABLE; } const auto shared_data = VmpInitializeSharedData(); if (!shared_data) { return STATUS_MEMORY_NOT_ALLOCATED; } // Read and store all MTRRs to set a correct memory type for EPT EptInitializeMtrrEntries(); // Virtualize all processors auto status = UtilForEachProcessor(VmpStartVm, shared_data); if (!NT_SUCCESS(status)) { UtilForEachProcessor(VmpStopVm, nullptr); return status; } return status; } ``` -------------------------------- ### Performance Initialization Source: https://tandasat.github.io/HyperPlatform/doxygen/performance_8cpp_source.html Prepares the environment for using HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE(). ```cpp NTSTATUS PerfInitialization() ``` -------------------------------- ### Use STL with Lambda Expressions Source: https://tandasat.github.io/HyperPlatform/userdocument/index.html Example of using STL containers and algorithms with lambda expressions, requiring extern C++ linkage. ```cpp // Uses STL for test extern "C++" void TestStl() { std::vector> strs; for (auto i = 0ul; i < 10; ++i) { strs.push_back( std::make_unique(L"i = " + std::to_wstring(i))); } // Using a lambda expression std::for_each(strs.cbegin(), strs.cend(), [](const auto &str) { HYPERPLATFORM_LOG_DEBUG("%S", str->c_str()); }); } ``` -------------------------------- ### Log File Initialization Source: https://tandasat.github.io/HyperPlatform/doxygen/log_8cpp_source.html Opens the log file handle for writing. ```cpp _Use_decl_annotations_ static NTSTATUS LogpInitializeLogFile( LogBufferInfo *info) { PAGED_CODE(); if (info->log_file_handle) { return STATUS_SUCCESS; } // Initialize a log file UNICODE_STRING log_file_path_u = {}; RtlInitUnicodeString(&log_file_path_u, info->log_file_path); OBJECT_ATTRIBUTES oa = {}; InitializeObjectAttributes(&oa, &log_file_path_u, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, nullptr, nullptr); IO_STATUS_BLOCK io_status = {}; auto status = ZwCreateFile( &info->log_file_handle, FILE_APPEND_DATA | SYNCHRONIZE, &oa, &io_status, nullptr, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN_IF, ``` -------------------------------- ### Virtual Machine Interface Definitions Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8h_source.html Core header definitions for VM initialization, termination, and hotplug callbacks. ```cpp 1 // Copyright (c) 2015-2017, Satoshi Tanda. All rights reserved. 2 // Use of this source code is governed by a MIT-style license that can be 3 // found in the LICENSE file. 4 7 8 #ifndef HYPERPLATFORM_VM_H_ 9 #define HYPERPLATFORM_VM_H_ 10 11 #include 12 13 extern "C" { 15 // 16 // macro utilities 17 // 18 20 // 21 // constants and macros 22 // 23 25 // 26 // types 27 // 28 30 // 31 // prototypes 32 // 33 41 _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS VmInitialization(); 42 44 _IRQL_requires_max_(PASSIVE_LEVEL) void VmTermination(); 45 51 _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS 52 VmHotplugCallback(const PROCESSOR_NUMBER& proc_num); 53 55 // 56 // variables 57 // 58 60 // 61 // implementations 62 // 63 64 } // extern "C" 65 66 #endif // HYPERPLATFORM_VM_H_ ``` ```cpp void VmTermination() ``` ```cpp NTSTATUS VmHotplugCallback(const PROCESSOR_NUMBER &proc_num) ``` ```cpp NTSTATUS VmInitialization() ``` -------------------------------- ### Define C++ classes for Doxygen graph visualization Source: https://tandasat.github.io/HyperPlatform/doxygen/graph_legend.html Example C++ code structure used to demonstrate various inheritance and containment relationships in Doxygen graphs. ```cpp /*! Invisible class because of truncation */ class Invisible { }; /*! Truncated class, inheritance relation is hidden */ class Truncated : public Invisible { }; /* Class not documented with doxygen comments */ class Undocumented { }; /*! Class that is inherited using public inheritance */ class PublicBase : public Truncated { }; /*! A template class */ template class Templ { }; /*! Class that is inherited using protected inheritance */ class ProtectedBase { }; /*! Class that is inherited using private inheritance */ class PrivateBase { }; /*! Class that is used by the Inherited class */ class Used { }; /*! Super class that inherits a number of other classes */ class Inherited : public PublicBase, protected ProtectedBase, private PrivateBase, public Undocumented, public Templ { private: Used *m_usedClass; }; ``` -------------------------------- ### UtilInitialization() Source: https://tandasat.github.io/HyperPlatform/doxygen/util_8h.html Initializes the utility functions for use within a driver. ```APIDOC ## UtilInitialization() ### Description Makes the Util functions ready for use. ### Parameters - **driver_object** (PDRIVER_OBJECT) - Required - The current driver's driver object. ### Returns - **NTSTATUS** - STATUS_SUCCESS on success. ``` -------------------------------- ### LogInitialization Function Source: https://tandasat.github.io/HyperPlatform/doxygen/log_8h.html Initializes the logging system, including buffer allocation and log file creation. ```c NTSTATUS LogInitialization(_In_ ULONG flag, _In_opt_ const wchar_t *file_path) ``` -------------------------------- ### EptInitialization Source: https://tandasat.github.io/HyperPlatform/doxygen/ept_8h.html Builds EPT and initializes EptData. ```APIDOC ## EptData* EptInitialization() ### Description Builds EPT, allocates pre-allocated entries, initializes and returns EptData. A driver must call EptTermination() with a returned value when this function succeeded. ### Returns - **EptData*** - An allocated EptData on success, or nullptr ``` -------------------------------- ### VmInitialization() Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8h.html Initializes a VMCS region and virtualizes all processors by entering VMX non-root operation mode. ```APIDOC ## VmInitialization() ### Description Virtualizes all processors. Initializes a VMCS region and virtualizes for each processor. If any processor fails to virtualize, the function de-virtualizes any processors that were already successfully virtualized. ### Returns - **NTSTATUS** - STATUS_SUCCESS on success, otherwise a non-success error code. ``` -------------------------------- ### Initialize EPT Table Entry Source: https://tandasat.github.io/HyperPlatform/doxygen/ept_8cpp_source.html Sets up an EPT entry with default read/write/execute permissions and memory type. ```cpp _Use_decl_annotations_ static void EptpInitTableEntry( EptCommonEntry *entry, ULONG table_level, ULONG64 physical_address) { entry->fields.read_access = true; entry->fields.write_access = true; entry->fields.execute_access = true; entry->fields.physial_address = UtilPfnFromPa(physical_address); if (table_level == 1) { entry->fields.memory_type = static_cast(EptpGetMemoryType(physical_address)); } } ``` -------------------------------- ### Configure Exception and CR Bitmaps Source: https://tandasat.github.io/HyperPlatform/doxygen/vm_8cpp_source.html Sets up exception bitmaps and CR0/CR4 shadow registers to control VM-exit behavior on guest register modifications. ```cpp const auto exception_bitmap = // 1 << InterruptionVector::kBreakpointException | // 1 << InterruptionVector::kGeneralProtectionException | // 1 << InterruptionVector::kPageFaultException | 0; // Set up CR0 and CR4 bitmaps // - Where a bit is masked, the shadow bit appears // - Where a bit is not masked, the actual bit appears // VM-exit occurs when a guest modifies any of those fields Cr0 cr0_mask = {}; Cr0 cr0_shadow = {__readcr0()}; Cr4 cr4_mask = {}; Cr4 cr4_shadow = {__readcr4()}; // For example, when we want to hide CR4.VMXE from the guest, comment in below // cr4_mask.fields.vmxe = true; // cr4_shadow.fields.vmxe = false; // See: PDPTE Registers // If PAE paging would be in use following an execution of MOV to CR0 or MOV // to CR4 (see Section 4.1.1) and the instruction is modifying any of CR0.CD, // CR0.NW, CR0.PG, CR4.PAE, CR4.PGE, CR4.PSE, or CR4.SMEP; then the PDPTEs are // loaded from the address in CR3. if (UtilIsX86Pae()) { cr0_mask.fields.pg = true; cr0_mask.fields.cd = true; cr0_mask.fields.nw = true; cr4_mask.fields.pae = true; cr4_mask.fields.pge = true; cr4_mask.fields.pse = true; cr4_mask.fields.smep = true; } ``` -------------------------------- ### Virtualization Entry and Exit Routines Source: https://tandasat.github.io/HyperPlatform/doxygen/x64_8asm_source.html Procedures for handling VM entry, VM exit, and critical VMX failure diagnostics. ```Assembly 157 movaps xmm1, xmmword ptr [rsp + 10h] 158 movaps xmm2, xmmword ptr [rsp + 20h] 159 movaps xmm3, xmmword ptr [rsp + 30h] 160 movaps xmm4, xmmword ptr [rsp + 40h] 161 movaps xmm5, xmmword ptr [rsp + 50h] 162 add rsp, 60h 163 164 test al, al 165 jz exitVm ; if (!vm_continue) jmp exitVm 166 167 POPAQ 168 vmresume 169 jmp vmxError 170 171 exitVm: 172 ; Executes vmxoff and ends virtualization 173 ; rax = Guest's rflags 174 ; rdx = Guest's rsp 175 ; rcx = Guest's rip for the next instruction 176 POPAQ 177 vmxoff 178 jz vmxError ; if (ZF) jmp 179 jc vmxError ; if (CF) jmp 180 push rax 181 popfq ; rflags <= GurstFlags 182 mov rsp, rdx ; rsp <= GuestRsp 183 push rcx 184 ret ; jmp AddressToReturn 185 186 vmxError: 187 ; Diagnose a critical error 188 pushfq 189 PUSHAQ ; -8 * 16 190 mov rcx, rsp ; all_regs 191 192 sub rsp, 28h ; 28h for alignment 193 call VmmVmxFailureHandler ; VmmVmxFailureHandler(all_regs); 194 add rsp, 28h 195 int 3 196 AsmVmmEntryPoint ENDP ``` -------------------------------- ### Initialize Physical Memory Ranges Source: https://tandasat.github.io/HyperPlatform/doxygen/util_8cpp_source.html Builds and logs the system's physical memory ranges for diagnostic purposes. ```cpp _Use_decl_annotations_ static NTSTATUS UtilpInitializePhysicalMemoryRanges() { PAGED_CODE(); const auto ranges = UtilpBuildPhysicalMemoryRanges(); if (!ranges) { return STATUS_UNSUCCESSFUL; } g_utilp_physical_memory_ranges = ranges; for (auto i = 0ul; i < ranges->number_of_runs; ++i) { const auto base_addr = static_cast(ranges->run[i].base_page) * PAGE_SIZE; HYPERPLATFORM_LOG_DEBUG("Physical Memory Range: %016llx - %016llx", base_addr, base_addr + ranges->run[i].page_count * PAGE_SIZE); } const auto pm_size = static_cast(ranges->number_of_pages) * PAGE_SIZE; HYPERPLATFORM_LOG_DEBUG("Physical Memory Total: %llu KB", pm_size / 1024); return STATUS_SUCCESS; } ``` -------------------------------- ### PowerCallbackInitialization() Source: https://tandasat.github.io/HyperPlatform/doxygen/power__callback_8h.html Initializes the power callback mechanisms. ```APIDOC ## PowerCallbackInitialization() ### Description Initializes the power callback functionality for the system. ### Signature `NTSTATUS PowerCallbackInitialization()` ### Returns - **NTSTATUS**: Returns the status of the initialization process. ``` -------------------------------- ### UtilForEachProcessor Source: https://tandasat.github.io/HyperPlatform/doxygen/util_8h.html Executes a provided callback routine on every processor. ```APIDOC ## UtilForEachProcessor ### Description Executes the specified callback routine on each processor in the system. ### Parameters - **callback_routine** (NTSTATUS(*)(void *)) - A function to execute - **context** (void *) - An arbitrary parameter for callback_routine ### Returns - **NTSTATUS** - STATUS_SUCCESS when returned STATUS_SUCCESS on all processors ``` -------------------------------- ### EptInitialization Source: https://tandasat.github.io/HyperPlatform/doxygen/ept_8h_source.html Initializes the EPT structures. ```APIDOC ## EptData* EptInitialization() ### Description Builds EPT, allocates pre-allocated entries, initializes and returns EptData. ### Signature EptData* EptInitialization() ``` -------------------------------- ### PerfInitialization Source: https://tandasat.github.io/HyperPlatform/doxygen/performance_8h.html Initializes the performance measurement system, making the HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE macro ready for use. ```APIDOC ## NTSTATUS PerfInitialization() ### Description Makes HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE() ready for use. ### Returns - **NTSTATUS**: STATUS_SUCCESS on success. ``` -------------------------------- ### UtilInvvpidAllContext() Source: https://tandasat.github.io/HyperPlatform/doxygen/util_8h.html Executes the INVVPID instruction for all contexts. ```APIDOC ## UtilInvvpidAllContext() ### Description Executes the INVVPID instruction (type 2). ### Returns - **VmxStatus** - A result of the INVVPID instruction. ``` -------------------------------- ### Execute VMLAUNCH Source: https://tandasat.github.io/HyperPlatform/doxygen/asm_8h_source.html Executes the VMLAUNCH instruction and returns a status code based on the CPU flags. ```cpp inline unsigned char __vmx_vmlaunch() { FlagRegister flags = {}; __asm { _emit 0x0f _emit 0x01 _emit 0xc2 // VMLAUNCH pushfd pop flags.all } if (flags.fields.cf) { return 2; } if (flags.fields.zf) { return 1; } /* UNREACHABLE */ return 0; } ``` -------------------------------- ### Main VM-Exit Handler Implementation Source: https://tandasat.github.io/HyperPlatform/doxygen/vmm_8cpp_source.html The primary entry point for VM-exits, responsible for saving guest state, dispatching events, and restoring state. ```cpp #pragma warning(push) #pragma warning(disable : 28167) _Use_decl_annotations_ bool __stdcall VmmVmExitHandler(VmmInitialStack *stack) { // Save guest's context and raise IRQL as quick as possible const auto guest_irql = KeGetCurrentIrql(); const auto guest_cr8 = IsX64() ? __readcr8() : 0; if (guest_irql < DISPATCH_LEVEL) { KeRaiseIrqlToDpcLevel(); } NT_ASSERT(stack->reserved == MAXULONG_PTR); // Capture the current guest state GuestContext guest_context = {stack, UtilVmRead(VmcsField::kGuestRflags), UtilVmRead(VmcsField::kGuestRip), guest_cr8, guest_irql, true}; guest_context.gp_regs->sp = UtilVmRead(VmcsField::kGuestRsp); // Dispatch the current VM-exit event VmmpHandleVmExit(&guest_context); // See: Guidelines for Use of the INVVPID Instruction, and Guidelines for Use // of the INVEPT Instruction if (!guest_context.vm_continue) { UtilInveptGlobal(); UtilInvvpidAllContext(); } // Restore guest's context if (guest_context.irql < DISPATCH_LEVEL) { KeLowerIrql(guest_context.irql); } // Apply possibly updated CR8 by the handler if (IsX64()) { __writecr8(guest_context.cr8); } return guest_context.vm_continue; } #pragma warning(pop) ``` -------------------------------- ### Re-initialization Routine Implementation Source: https://tandasat.github.io/HyperPlatform/doxygen/log_8cpp_source.html Handles the activation of the log file during the re-initialization phase. ```cpp 313 // Initializes a log file at the re-initialization phase. 314 _Use_decl_annotations_ VOID static LogpReinitializationRoutine( 315 _DRIVER_OBJECT *driver_object, PVOID context, ULONG count) { 316 PAGED_CODE(); 317 UNREFERENCED_PARAMETER(driver_object); 318 UNREFERENCED_PARAMETER(count); 319 NT_ASSERT(context); 320 _Analysis_assume_(context); 321 322 auto info = reinterpret_cast(context); 323 auto status = LogpInitializeLogFile(info); 324 NT_ASSERT(NT_SUCCESS(status)); 325 if (NT_SUCCESS(status)) { 326 HYPERPLATFORM_LOG_INFO("The log file has been activated."); 327 } 328 } ``` -------------------------------- ### Initialize RtlPcToFileHeader Utility Source: https://tandasat.github.io/HyperPlatform/doxygen/util_8cpp_source.html Initializes the function pointer for PcToFileHeader, falling back to an unsafe manual implementation if the system function is unavailable. ```cpp _Use_decl_annotations_ static NTSTATUS UtilpInitializeRtlPcToFileHeader( PDRIVER_OBJECT driver_object) { PAGED_CODE(); if (kUtilpUseRtlPcToFileHeader) { const auto p_RtlPcToFileHeader = UtilGetSystemProcAddress(L"RtlPcToFileHeader"); if (p_RtlPcToFileHeader) { g_utilp_RtlPcToFileHeader = reinterpret_cast(p_RtlPcToFileHeader); return STATUS_SUCCESS; } } #pragma warning(push) #pragma warning(disable : 28175) auto module = reinterpret_cast(driver_object->DriverSection); #pragma warning(pop) g_utilp_PsLoadedModuleList = module->in_load_order_links.Flink; g_utilp_RtlPcToFileHeader = UtilpUnsafePcToFileHeader; return STATUS_SUCCESS; } ```