├── kHypervisorBasic ├── vmcs.cpp ├── vmx_common.cpp ├── lib │ └── capstone │ │ ├── debug │ │ ├── capstone_static_winkernel.lib │ │ └── capstone_static_winkernel.pdb │ │ └── release │ │ └── capstone_static_winkernel.lib ├── kHypervisorBasic.vcxproj.user ├── include │ ├── windowsce │ │ ├── intrin.h │ │ └── stdint.h │ ├── platform.h │ └── capstone │ │ ├── platform.h │ │ ├── mos65xx.h │ │ ├── evm.h │ │ └── xcore.h ├── kHypervisorBasic.inf ├── driver.h ├── power_callback.h ├── hotplug_callback.h ├── global_object.h ├── vmx.h ├── vm.h ├── performance.h ├── hotplug_callback.cpp ├── vmcs.h ├── performance.cpp ├── power_callback.cpp ├── global_object.cpp ├── vmm.h ├── kernel_stl.h ├── vmx_common.h ├── ept.h ├── kHypervisorBasic.vcxproj.filters ├── util_page_constants.h ├── kernel_stl.cpp └── common.h ├── kHypervisor ├── kHypervisor │ ├── vmcs.cpp │ ├── vmx_common.cpp │ ├── Filehook.h │ ├── kHypervisor.vcxproj.user │ ├── shadow_hook.h │ ├── hook.h │ ├── kHypervisor.inf │ ├── vmx.h │ ├── vmcs.h │ ├── list.h │ ├── Filehook.cpp │ ├── kHypervisor.filters │ ├── shadow_hook.cpp │ ├── vmx_common.h │ ├── Common.h │ └── list.c ├── doc │ └── NestedVmInsturction.pdf ├── LICENSE.txt ├── HyperPlatform │ ├── driver.h │ ├── power_callback.h │ ├── hotplug_callback.h │ ├── global_object.h │ ├── vm.h │ ├── performance.h │ ├── HyperPlatform.inf │ ├── HyperPlatform │ │ ├── hotplug_callback.cpp │ │ ├── power_callback.cpp │ │ └── global_object.cpp │ ├── hotplug_callback.cpp │ ├── performance.cpp │ ├── power_callback.cpp │ ├── global_object.cpp │ ├── vmm.h │ ├── HyperPlatform.vcxproj.filters │ ├── kernel_stl.h │ ├── ept.h │ ├── util_page_constants.h │ ├── kernel_stl.cpp │ └── common.h └── kHypervisor.sln ├── .gitignore └── README.md /kHypervisorBasic/vmcs.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TimelifeCzy/kHypervisorBasic/HEAD/kHypervisorBasic/vmcs.cpp -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/vmcs.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TimelifeCzy/kHypervisorBasic/HEAD/kHypervisor/kHypervisor/vmcs.cpp -------------------------------------------------------------------------------- /kHypervisorBasic/vmx_common.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TimelifeCzy/kHypervisorBasic/HEAD/kHypervisorBasic/vmx_common.cpp -------------------------------------------------------------------------------- /kHypervisor/doc/NestedVmInsturction.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TimelifeCzy/kHypervisorBasic/HEAD/kHypervisor/doc/NestedVmInsturction.pdf -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/vmx_common.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TimelifeCzy/kHypervisorBasic/HEAD/kHypervisor/kHypervisor/vmx_common.cpp -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | kHypervisor/x64 2 | kHypervisor/Debug 3 | kHypervisor/Release 4 | kHypervisor/.vs 5 | kHypervisor/kHypervisor/x64 6 | kHypervisor/kHypervisor/Debug 7 | kHypervisor/kHypervisor/Release 8 | -------------------------------------------------------------------------------- /kHypervisorBasic/lib/capstone/debug/capstone_static_winkernel.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TimelifeCzy/kHypervisorBasic/HEAD/kHypervisorBasic/lib/capstone/debug/capstone_static_winkernel.lib -------------------------------------------------------------------------------- /kHypervisorBasic/lib/capstone/debug/capstone_static_winkernel.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TimelifeCzy/kHypervisorBasic/HEAD/kHypervisorBasic/lib/capstone/debug/capstone_static_winkernel.pdb -------------------------------------------------------------------------------- /kHypervisorBasic/lib/capstone/release/capstone_static_winkernel.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TimelifeCzy/kHypervisorBasic/HEAD/kHypervisorBasic/lib/capstone/release/capstone_static_winkernel.lib -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/Filehook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Native.h" 4 | 5 | extern "C" { 6 | // Enable Hook 7 | NTSTATUS FileMsrHook(const PSYSTEM_SERVICE_DESCRIPTOR_TABLE pssdt); 8 | } -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/kHypervisor.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /kHypervisorBasic/kHypervisorBasic.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /kHypervisorBasic/include/windowsce/intrin.h: -------------------------------------------------------------------------------- 1 | 2 | #if defined(_MSC_VER) && defined(_WIN32_WCE) && (_WIN32_WCE < 0x800) && !defined(__INTRIN_H_) && !defined(_INTRIN) 3 | #define _STDINT 4 | 5 | #ifdef _M_ARM 6 | #include 7 | #if (_WIN32_WCE >= 0x700) && defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) 8 | #include 9 | #endif 10 | #endif // _M_ARM 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | kHypervisor: https://github.com/Kelvinhack/kHypervisor 2 | 3 | ### v1.0 4 | 基于kHypervisor框架添加了Msr/Ept Hook,仅用于学习和示例使用。 5 | 6 | **see directory: kHypervisor/kHypervisor** 7 | 8 | ### v2.0(待开发) 9 | 根据Kelvinhack建议,可以尝试将khypervisor分离设计hv_lib接口 10 | ``` 11 | |-- hv 12 | |-- nested hv 13 | |-- pci device mon 14 | |-- ept 15 | |-- ept hook 16 | ... 17 | ``` 18 | **see directory: kHypervisor/kHypervisorBasic** 19 | -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/shadow_hook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | // Expresses where to install hooks by a function name, and its handlers 4 | struct ShadowHookTarget { 5 | UNICODE_STRING target_name; // An export name to hook 6 | void* handler; // An address of a hook handler 7 | 8 | // An address of a trampoline code to call original function. Initialized by 9 | // a successful call of ShInstallHook(). 10 | void* original_call; 11 | }; -------------------------------------------------------------------------------- /kHypervisorBasic/kHypervisorBasic.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; kHypervisorBasic.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} 9 | Provider=%ManufacturerName% 10 | DriverVer= 11 | CatalogFile=kHypervisorBasic.cat 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | 16 | 17 | [SourceDisksNames] 18 | 1 = %DiskName%,,,"" 19 | 20 | [SourceDisksFiles] 21 | 22 | 23 | [Manufacturer] 24 | %ManufacturerName%=Standard,NT$ARCH$ 25 | 26 | [Standard.NT$ARCH$] 27 | 28 | 29 | [Strings] 30 | ManufacturerName="" ;TODO: Replace with your manufacturer name 31 | ClassName="" 32 | DiskName="kHypervisorBasic Source Disk" 33 | -------------------------------------------------------------------------------- /kHypervisor/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Satoshi Tanda 4 | Copyright (c) 2016 Kelvin Chan 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. -------------------------------------------------------------------------------- /kHypervisorBasic/driver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// @brief Declares interfaces to driver functions. 8 | 9 | #ifndef HYPERPLATFORM_DRIVER_H_ 10 | #define HYPERPLATFORM_DRIVER_H_ 11 | 12 | extern "C" { 13 | //////////////////////////////////////////////////////////////////////////////// 14 | // 15 | // macro utilities 16 | // 17 | 18 | //////////////////////////////////////////////////////////////////////////////// 19 | // 20 | // constants and macros 21 | // 22 | 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // 25 | // types 26 | // 27 | 28 | //////////////////////////////////////////////////////////////////////////////// 29 | // 30 | // prototypes 31 | // 32 | 33 | //////////////////////////////////////////////////////////////////////////////// 34 | // 35 | // variables 36 | // 37 | 38 | //////////////////////////////////////////////////////////////////////////////// 39 | // 40 | // implementations 41 | // 42 | 43 | } // extern "C" 44 | 45 | #endif // HYPERPLATFORM_DRIVER_H_ 46 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/driver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// @brief Declares interfaces to driver functions. 8 | 9 | #ifndef HYPERPLATFORM_DRIVER_H_ 10 | #define HYPERPLATFORM_DRIVER_H_ 11 | 12 | extern "C" { 13 | //////////////////////////////////////////////////////////////////////////////// 14 | // 15 | // macro utilities 16 | // 17 | 18 | //////////////////////////////////////////////////////////////////////////////// 19 | // 20 | // constants and macros 21 | // 22 | 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // 25 | // types 26 | // 27 | 28 | //////////////////////////////////////////////////////////////////////////////// 29 | // 30 | // prototypes 31 | // 32 | 33 | //////////////////////////////////////////////////////////////////////////////// 34 | // 35 | // variables 36 | // 37 | 38 | //////////////////////////////////////////////////////////////////////////////// 39 | // 40 | // implementations 41 | // 42 | 43 | } // extern "C" 44 | 45 | #endif // HYPERPLATFORM_DRIVER_H_ 46 | -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/hook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // #include 3 | #include 4 | 5 | enum HOOK_KIND { 6 | 7 | INST_UNKNOWN = 0, 8 | INST_MOVE, 9 | INST_CTLXFER, // jmp/jcc/call with 32-bit disp 10 | INST_CTLXFER_REG, // jmp/call reg or [reg] 11 | INST_CALL_MEM, // call [mem] 12 | INST_JUMP_MEM, // jmp [mem] 13 | INST_SYSCALL, 14 | INST_RET 15 | }; 16 | 17 | typedef struct _HOOK_INST { 18 | ULONG len; 19 | UCHAR kind; 20 | UCHAR op1, op2; 21 | ULONG64 parm; 22 | LONG* rel32; // --> 32-bit relocation for control-xfer 23 | UCHAR* modrm; 24 | ULONG flags; 25 | 26 | } HOOK_INST; 27 | 28 | extern "C" { 29 | NTSTATUS SHInitMsrHook(void* context); 30 | NTSTATUS EptSshookEntry(void* context); 31 | NTSTATUS SHDestroyMsrHook(); 32 | NTSTATUS SHRestoreMsrSyscall(IN ULONG index); 33 | NTSTATUS AddMsrHook(IN ULONG index, IN PVOID hookPtr, IN CHAR argCount); 34 | PVOID PuGetSSDTEntry(IN ULONG index); 35 | PVOID UtilKernelBase(OUT PULONG pSize); 36 | BOOLEAN Hook_Analyze(void* address, BOOLEAN probe_address, BOOLEAN is64, 37 | HOOK_INST* inst); 38 | 39 | //static BOOLEAN Hook_Tramp_CountBytes(void* SysProc, ULONG* ByteCount, 40 | // BOOLEAN is64, BOOLEAN probe); 41 | } 42 | -------------------------------------------------------------------------------- /kHypervisorBasic/power_callback.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// @brief Declares interfaces to power functions. 8 | 9 | #ifndef HYPERPLATFORM_POWER_CALLBACK_H_ 10 | #define HYPERPLATFORM_POWER_CALLBACK_H_ 11 | 12 | #include 13 | 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // prototypes 33 | // 34 | 35 | _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS PowerCallbackInitialization(); 36 | 37 | _IRQL_requires_max_(PASSIVE_LEVEL) void PowerCallbackTermination(); 38 | 39 | //////////////////////////////////////////////////////////////////////////////// 40 | // 41 | // variables 42 | // 43 | 44 | //////////////////////////////////////////////////////////////////////////////// 45 | // 46 | // implementations 47 | // 48 | 49 | } // extern "C" 50 | 51 | #endif // HYPERPLATFORM_POWER_CALLBACK_H_ 52 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/power_callback.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// @brief Declares interfaces to power functions. 8 | 9 | #ifndef HYPERPLATFORM_POWER_CALLBACK_H_ 10 | #define HYPERPLATFORM_POWER_CALLBACK_H_ 11 | 12 | #include 13 | 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // prototypes 33 | // 34 | 35 | _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS PowerCallbackInitialization(); 36 | 37 | _IRQL_requires_max_(PASSIVE_LEVEL) void PowerCallbackTermination(); 38 | 39 | //////////////////////////////////////////////////////////////////////////////// 40 | // 41 | // variables 42 | // 43 | 44 | //////////////////////////////////////////////////////////////////////////////// 45 | // 46 | // implementations 47 | // 48 | 49 | } // extern "C" 50 | 51 | #endif // HYPERPLATFORM_POWER_CALLBACK_H_ 52 | -------------------------------------------------------------------------------- /kHypervisorBasic/hotplug_callback.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// @brief Declares interfaces to hot-plug functions. 8 | 9 | #ifndef HYPERPLATFORM_HOTPLUG_CALLBACK_H_ 10 | #define HYPERPLATFORM_HOTPLUG_CALLBACK_H_ 11 | 12 | #include 13 | 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // prototypes 33 | // 34 | 35 | _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS HotplugCallbackInitialization(); 36 | 37 | _IRQL_requires_max_(PASSIVE_LEVEL) void HotplugCallbackTermination(); 38 | 39 | //////////////////////////////////////////////////////////////////////////////// 40 | // 41 | // variables 42 | // 43 | 44 | //////////////////////////////////////////////////////////////////////////////// 45 | // 46 | // implementations 47 | // 48 | 49 | } // extern "C" 50 | 51 | #endif // HYPERPLATFORM_HOTPLUG_CALLBACK_H_ 52 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/hotplug_callback.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// @brief Declares interfaces to hot-plug functions. 8 | 9 | #ifndef HYPERPLATFORM_HOTPLUG_CALLBACK_H_ 10 | #define HYPERPLATFORM_HOTPLUG_CALLBACK_H_ 11 | 12 | #include 13 | 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // prototypes 33 | // 34 | 35 | _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS HotplugCallbackInitialization(); 36 | 37 | _IRQL_requires_max_(PASSIVE_LEVEL) void HotplugCallbackTermination(); 38 | 39 | //////////////////////////////////////////////////////////////////////////////// 40 | // 41 | // variables 42 | // 43 | 44 | //////////////////////////////////////////////////////////////////////////////// 45 | // 46 | // implementations 47 | // 48 | 49 | } // extern "C" 50 | 51 | #endif // HYPERPLATFORM_HOTPLUG_CALLBACK_H_ 52 | -------------------------------------------------------------------------------- /kHypervisorBasic/global_object.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Declares interfaces to global object functions. 8 | 9 | #ifndef HYPERPLATFORM_GLOBAL_OBJECT_H_ 10 | #define HYPERPLATFORM_GLOBAL_OBJECT_H_ 11 | 12 | #include 13 | 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // prototypes 33 | // 34 | 35 | /// Calls all constructors and register all destructor 36 | /// @return STATUS_SUCCESS on success 37 | _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS GlobalObjectInitialization(); 38 | 39 | /// Calls all destructors 40 | _IRQL_requires_max_(PASSIVE_LEVEL) void GlobalObjectTermination(); 41 | 42 | //////////////////////////////////////////////////////////////////////////////// 43 | // 44 | // variables 45 | // 46 | 47 | //////////////////////////////////////////////////////////////////////////////// 48 | // 49 | // implementations 50 | // 51 | 52 | } // extern "C" 53 | 54 | #endif // HYPERPLATFORM_GLOBAL_OBJECT_H_ 55 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/global_object.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Declares interfaces to global object functions. 8 | 9 | #ifndef HYPERPLATFORM_GLOBAL_OBJECT_H_ 10 | #define HYPERPLATFORM_GLOBAL_OBJECT_H_ 11 | 12 | #include 13 | 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // prototypes 33 | // 34 | 35 | /// Calls all constructors and register all destructor 36 | /// @return STATUS_SUCCESS on success 37 | _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS GlobalObjectInitialization(); 38 | 39 | /// Calls all destructors 40 | _IRQL_requires_max_(PASSIVE_LEVEL) void GlobalObjectTermination(); 41 | 42 | //////////////////////////////////////////////////////////////////////////////// 43 | // 44 | // variables 45 | // 46 | 47 | //////////////////////////////////////////////////////////////////////////////// 48 | // 49 | // implementations 50 | // 51 | 52 | } // extern "C" 53 | 54 | #endif // HYPERPLATFORM_GLOBAL_OBJECT_H_ 55 | -------------------------------------------------------------------------------- /kHypervisorBasic/vmx.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2016 KelvinChan. All rights reserved. 4 | Use of this source code is governed by a MIT-style license that can be 5 | found in the LICENSE file. 6 | 7 | Module Name: 8 | 9 | vmx.h 10 | 11 | Abstract: 12 | 13 | VMX Instruction Emulation 14 | 15 | Author: 16 | 17 | Kelvin Chan 18 | 19 | Environment: 20 | 21 | Kernel VMM Mode 22 | 23 | --*/ 24 | #pragma once 25 | #ifndef NESTED_HYPERPLATFORM_VMX_H_ 26 | #define NESTED_HYPERPLATFORM_VMX_H_ 27 | #include 28 | #include "vmm.h" 29 | #include "util.h" 30 | 31 | struct GuestContext; 32 | 33 | enum VMX_state 34 | { 35 | VMCS_STATE_CLEAR = 0, 36 | VMCS_STATE_LAUNCHED 37 | }; 38 | 39 | extern "C" 40 | { 41 | 42 | VOID 43 | VmxVmxonEmulate( 44 | _In_ GuestContext* guest_context 45 | ); 46 | 47 | VOID 48 | VmxVmxoffEmulate( 49 | _In_ GuestContext* guest_context 50 | ); 51 | 52 | VOID 53 | VmxVmclearEmulate( 54 | _In_ GuestContext* guest_context 55 | ); 56 | 57 | VOID 58 | VmxVmptrldEmulate( 59 | _In_ GuestContext* guest_context 60 | ); 61 | 62 | VOID 63 | VmxVmreadEmulate( 64 | _In_ GuestContext* guest_context 65 | ); 66 | 67 | VOID 68 | VmxVmwriteEmulate( 69 | _In_ GuestContext* guest_context 70 | ); 71 | 72 | VOID 73 | VmxVmlaunchEmulate( 74 | _In_ GuestContext* guest_context 75 | ); 76 | 77 | VOID 78 | VmxVmresumeEmulate( 79 | _In_ GuestContext* guest_context 80 | ); 81 | 82 | VOID 83 | VmxVmptrstEmulate( 84 | _In_ GuestContext* guest_context 85 | ); 86 | 87 | VOID VmxInveptEmulate( 88 | _In_ GuestContext* guest_context 89 | ); 90 | VOID 91 | LEAVE_GUEST_MODE( 92 | _In_ VCPUVMX* vcpu 93 | ); 94 | VOID 95 | ENTER_GUEST_MODE( 96 | _In_ VCPUVMX* vcpu 97 | ); 98 | VMX_MODE 99 | VmxGetVmxMode( 100 | _In_ VCPUVMX* vcpu 101 | ); 102 | 103 | NTSTATUS 104 | VmxVMExitEmulate( 105 | _In_ VCPUVMX* vCPU, 106 | _In_ GuestContext* guest_context 107 | ); 108 | 109 | } 110 | 111 | #endif -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/kHypervisor.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; kHypervisor.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=Sample ; TODO: edit Class 8 | ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=kHypervisor.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | 16 | ; ================= Class section ===================== 17 | 18 | [ClassInstall32] 19 | Addreg=SampleClassReg 20 | 21 | [SampleClassReg] 22 | HKR,,,0,%ClassName% 23 | HKR,,Icon,,-5 24 | 25 | [SourceDisksNames] 26 | 1 = %DiskName%,,,"" 27 | 28 | [SourceDisksFiles] 29 | kHypervisor.sys = 1,, 30 | 31 | ;***************************************** 32 | ; Install Section 33 | ;***************************************** 34 | 35 | [Manufacturer] 36 | %ManufacturerName%=Standard,NT$ARCH$ 37 | 38 | [Standard.NT$ARCH$] 39 | %kHypervisor.DeviceDesc%=kHypervisor_Device, Root\kHypervisor ; TODO: edit hw-id 40 | 41 | [kHypervisor_Device.NT] 42 | CopyFiles=Drivers_Dir 43 | 44 | [Drivers_Dir] 45 | kHypervisor.sys 46 | 47 | ;-------------- Service installation 48 | [kHypervisor_Device.NT.Services] 49 | AddService = kHypervisor,%SPSVCINST_ASSOCSERVICE%, kHypervisor_Service_Inst 50 | 51 | ; -------------- kHypervisor driver install sections 52 | [kHypervisor_Service_Inst] 53 | DisplayName = %kHypervisor.SVCDESC% 54 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 55 | StartType = 3 ; SERVICE_DEMAND_START 56 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 57 | ServiceBinary = %12%\kHypervisor.sys 58 | 59 | ; 60 | ;--- kHypervisor_Device Coinstaller installation ------ 61 | ; 62 | 63 | 64 | [Strings] 65 | SPSVCINST_ASSOCSERVICE= 0x00000002 66 | ManufacturerName="" ;TODO: Replace with your manufacturer name 67 | ClassName="Samples" ; TODO: edit ClassName 68 | DiskName = "kHypervisor Installation Disk" 69 | kHypervisor.DeviceDesc = "kHypervisor Device" 70 | kHypervisor.SVCDESC = "kHypervisor Service" 71 | -------------------------------------------------------------------------------- /kHypervisorBasic/vm.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Declares interfaces to VMM initialization functions 8 | 9 | #ifndef HYPERPLATFORM_VM_H_ 10 | #define HYPERPLATFORM_VM_H_ 11 | 12 | #include 13 | 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // prototypes 33 | // 34 | 35 | /// Virtualizes all processors 36 | /// @return STATUS_SUCCESS on success 37 | /// 38 | /// Initializes a VMCS region and virtualizes (ie, enters the VMX non-root 39 | /// operation mode) for each processor. Returns non STATUS_SUCCESS value if any 40 | /// of processors failed to do so. In that case, this function de-virtualize 41 | /// already virtualized processors. 42 | _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS VmInitialization(); 43 | 44 | /// De-virtualize all processors 45 | _IRQL_requires_max_(PASSIVE_LEVEL) void VmTermination(); 46 | 47 | /// Virtualizes the specified processor 48 | /// @param proc_num A processor number to virtualize 49 | /// @return STATUS_SUCCESS on success 50 | /// 51 | /// The processor 0 must have already been virtualized, or it fails. 52 | _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS 53 | VmHotplugCallback(const PROCESSOR_NUMBER& proc_num); 54 | 55 | //////////////////////////////////////////////////////////////////////////////// 56 | // 57 | // variables 58 | // 59 | 60 | //////////////////////////////////////////////////////////////////////////////// 61 | // 62 | // implementations 63 | // 64 | 65 | } // extern "C" 66 | 67 | #endif // HYPERPLATFORM_VM_H_ 68 | -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/vmx.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2016 KelvinChan. All rights reserved. 4 | Use of this source code is governed by a MIT-style license that can be 5 | found in the LICENSE file. 6 | 7 | Module Name: 8 | 9 | vmx.h 10 | 11 | Abstract: 12 | 13 | VMX Instruction Emulation 14 | 15 | Author: 16 | 17 | Kelvin Chan 18 | 19 | Environment: 20 | 21 | Kernel VMM Mode 22 | 23 | --*/ 24 | #pragma once 25 | #ifndef NESTED_HYPERPLATFORM_VMX_H_ 26 | #define NESTED_HYPERPLATFORM_VMX_H_ 27 | #include 28 | #include "..\HyperPlatform\vmm.h" 29 | #include "..\HyperPlatform\util.h" 30 | 31 | struct GuestContext; 32 | 33 | enum VMX_state 34 | { 35 | VMCS_STATE_CLEAR = 0, 36 | VMCS_STATE_LAUNCHED 37 | }; 38 | 39 | extern "C" 40 | { 41 | 42 | VOID 43 | VmxVmxonEmulate( 44 | _In_ GuestContext* guest_context 45 | ); 46 | 47 | VOID 48 | VmxVmxoffEmulate( 49 | _In_ GuestContext* guest_context 50 | ); 51 | 52 | VOID 53 | VmxVmclearEmulate( 54 | _In_ GuestContext* guest_context 55 | ); 56 | 57 | VOID 58 | VmxVmptrldEmulate( 59 | _In_ GuestContext* guest_context 60 | ); 61 | 62 | VOID 63 | VmxVmreadEmulate( 64 | _In_ GuestContext* guest_context 65 | ); 66 | 67 | VOID 68 | VmxVmwriteEmulate( 69 | _In_ GuestContext* guest_context 70 | ); 71 | 72 | VOID 73 | VmxVmlaunchEmulate( 74 | _In_ GuestContext* guest_context 75 | ); 76 | 77 | VOID 78 | VmxVmresumeEmulate( 79 | _In_ GuestContext* guest_context 80 | ); 81 | 82 | VOID 83 | VmxVmptrstEmulate( 84 | _In_ GuestContext* guest_context 85 | ); 86 | 87 | VOID VmxInveptEmulate( 88 | _In_ GuestContext* guest_context 89 | ); 90 | VOID 91 | LEAVE_GUEST_MODE( 92 | _In_ VCPUVMX* vcpu 93 | ); 94 | VOID 95 | ENTER_GUEST_MODE( 96 | _In_ VCPUVMX* vcpu 97 | ); 98 | VMX_MODE 99 | VmxGetVmxMode( 100 | _In_ VCPUVMX* vcpu 101 | ); 102 | 103 | NTSTATUS 104 | VmxVMExitEmulate( 105 | _In_ VCPUVMX* vCPU, 106 | _In_ GuestContext* guest_context 107 | ); 108 | 109 | } 110 | 111 | #endif -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/vm.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Declares interfaces to VMM initialization functions 8 | 9 | #ifndef HYPERPLATFORM_VM_H_ 10 | #define HYPERPLATFORM_VM_H_ 11 | 12 | #include 13 | 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // prototypes 33 | // 34 | 35 | /// Virtualizes all processors 36 | /// @return STATUS_SUCCESS on success 37 | /// 38 | /// Initializes a VMCS region and virtualizes (ie, enters the VMX non-root 39 | /// operation mode) for each processor. Returns non STATUS_SUCCESS value if any 40 | /// of processors failed to do so. In that case, this function de-virtualize 41 | /// already virtualized processors. 42 | _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS VmInitialization(); 43 | 44 | /// De-virtualize all processors 45 | _IRQL_requires_max_(PASSIVE_LEVEL) void VmTermination(); 46 | 47 | /// Virtualizes the specified processor 48 | /// @param proc_num A processor number to virtualize 49 | /// @return STATUS_SUCCESS on success 50 | /// 51 | /// The processor 0 must have already been virtualized, or it fails. 52 | _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS 53 | VmHotplugCallback(const PROCESSOR_NUMBER& proc_num); 54 | 55 | //////////////////////////////////////////////////////////////////////////////// 56 | // 57 | // variables 58 | // 59 | 60 | //////////////////////////////////////////////////////////////////////////////// 61 | // 62 | // implementations 63 | // 64 | 65 | } // extern "C" 66 | 67 | #endif // HYPERPLATFORM_VM_H_ 68 | -------------------------------------------------------------------------------- /kHypervisorBasic/performance.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Declares interfaces to performance measurement functions. 8 | 9 | #ifndef HYPERPLATFORM_PERFORMANCE_H_ 10 | #define HYPERPLATFORM_PERFORMANCE_H_ 11 | 12 | #include "perf_counter.h" 13 | 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | #if (HYPERPLATFORM_PERFORMANCE_ENABLE_PERFCOUNTER != 0) 21 | 22 | /// Measures an elapsed time from execution of this macro to the end of a scope 23 | /// 24 | /// @warning 25 | /// This macro cannot be called from an INIT section. See 26 | /// #HYPERPLATFORM_PERFCOUNTER_MEASURE_TIME() for details. 27 | #define HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE() \ 28 | HYPERPLATFORM_PERFCOUNTER_MEASURE_TIME(g_performance_collector, PerfGetTime) 29 | 30 | #else 31 | #define HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE() 32 | #endif 33 | 34 | //////////////////////////////////////////////////////////////////////////////// 35 | // 36 | // constants and macros 37 | // 38 | 39 | //////////////////////////////////////////////////////////////////////////////// 40 | // 41 | // types 42 | // 43 | 44 | //////////////////////////////////////////////////////////////////////////////// 45 | // 46 | // prototypes 47 | // 48 | 49 | /// Makes #HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE() ready for use 50 | /// @return STATUS_SUCCESS on success 51 | _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS PerfInitialization(); 52 | 53 | /// Ends performance monitoring and outputs its results 54 | _IRQL_requires_max_(PASSIVE_LEVEL) void PerfTermination(); 55 | 56 | /// Returns the current "time" for performance measurement. 57 | /// @return Current performance counter 58 | /// 59 | /// It should only be used by #HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE(). 60 | ULONG64 PerfGetTime(); 61 | 62 | //////////////////////////////////////////////////////////////////////////////// 63 | // 64 | // variables 65 | // 66 | 67 | /// Stores all performance data collected by 68 | /// #HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE(). 69 | extern PerfCollector* g_performance_collector; 70 | 71 | //////////////////////////////////////////////////////////////////////////////// 72 | // 73 | // implementations 74 | // 75 | 76 | } // extern "C" 77 | 78 | #endif // HYPERPLATFORM_PERFORMANCE_H_ 79 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/performance.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Declares interfaces to performance measurement functions. 8 | 9 | #ifndef HYPERPLATFORM_PERFORMANCE_H_ 10 | #define HYPERPLATFORM_PERFORMANCE_H_ 11 | 12 | #include "perf_counter.h" 13 | 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | #if (HYPERPLATFORM_PERFORMANCE_ENABLE_PERFCOUNTER != 0) 21 | 22 | /// Measures an elapsed time from execution of this macro to the end of a scope 23 | /// 24 | /// @warning 25 | /// This macro cannot be called from an INIT section. See 26 | /// #HYPERPLATFORM_PERFCOUNTER_MEASURE_TIME() for details. 27 | #define HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE() \ 28 | HYPERPLATFORM_PERFCOUNTER_MEASURE_TIME(g_performance_collector, PerfGetTime) 29 | 30 | #else 31 | #define HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE() 32 | #endif 33 | 34 | //////////////////////////////////////////////////////////////////////////////// 35 | // 36 | // constants and macros 37 | // 38 | 39 | //////////////////////////////////////////////////////////////////////////////// 40 | // 41 | // types 42 | // 43 | 44 | //////////////////////////////////////////////////////////////////////////////// 45 | // 46 | // prototypes 47 | // 48 | 49 | /// Makes #HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE() ready for use 50 | /// @return STATUS_SUCCESS on success 51 | _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS PerfInitialization(); 52 | 53 | /// Ends performance monitoring and outputs its results 54 | _IRQL_requires_max_(PASSIVE_LEVEL) void PerfTermination(); 55 | 56 | /// Returns the current "time" for performance measurement. 57 | /// @return Current performance counter 58 | /// 59 | /// It should only be used by #HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE(). 60 | ULONG64 PerfGetTime(); 61 | 62 | //////////////////////////////////////////////////////////////////////////////// 63 | // 64 | // variables 65 | // 66 | 67 | /// Stores all performance data collected by 68 | /// #HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE(). 69 | extern PerfCollector* g_performance_collector; 70 | 71 | //////////////////////////////////////////////////////////////////////////////// 72 | // 73 | // implementations 74 | // 75 | 76 | } // extern "C" 77 | 78 | #endif // HYPERPLATFORM_PERFORMANCE_H_ 79 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/HyperPlatform.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; HyperPlatform.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=Sample ; TODO: edit Class 8 | ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=HyperPlatform.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | 16 | ; ================= Class section ===================== 17 | 18 | [ClassInstall32] 19 | Addreg=SampleClassReg 20 | 21 | [SampleClassReg] 22 | HKR,,,0,%ClassName% 23 | HKR,,Icon,,-5 24 | 25 | [SourceDisksNames] 26 | 1 = %DiskName%,,,"" 27 | 28 | [SourceDisksFiles] 29 | HyperPlatform.sys = 1,, 30 | 31 | ;***************************************** 32 | ; Install Section 33 | ;***************************************** 34 | 35 | [Manufacturer] 36 | %ManufacturerName%=Standard,NT$ARCH$ 37 | 38 | [Standard.NT$ARCH$] 39 | %HyperPlatform.DeviceDesc%=HyperPlatform_Device, Root\HyperPlatform ; TODO: edit hw-id 40 | 41 | [HyperPlatform_Device.NT] 42 | CopyFiles=Drivers_Dir 43 | 44 | [Drivers_Dir] 45 | HyperPlatform.sys 46 | 47 | ;-------------- Service installation 48 | [HyperPlatform_Device.NT.Services] 49 | AddService = HyperPlatform,%SPSVCINST_ASSOCSERVICE%, HyperPlatform_Service_Inst 50 | 51 | ; -------------- HyperPlatform driver install sections 52 | [HyperPlatform_Service_Inst] 53 | DisplayName = %HyperPlatform.SVCDESC% 54 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 55 | StartType = 3 ; SERVICE_DEMAND_START 56 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 57 | ServiceBinary = %12%\HyperPlatform.sys 58 | 59 | ; 60 | ;--- HyperPlatform_Device Coinstaller installation ------ 61 | ; 62 | 63 | [DestinationDirs] 64 | HyperPlatform_Device_CoInstaller_CopyFiles = 11 65 | 66 | [HyperPlatform_Device.NT.CoInstallers] 67 | AddReg=HyperPlatform_Device_CoInstaller_AddReg 68 | CopyFiles=HyperPlatform_Device_CoInstaller_CopyFiles 69 | 70 | [HyperPlatform_Device_CoInstaller_AddReg] 71 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 72 | 73 | [HyperPlatform_Device_CoInstaller_CopyFiles] 74 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 75 | 76 | [SourceDisksFiles] 77 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 78 | 79 | [HyperPlatform_Device.NT.Wdf] 80 | KmdfService = HyperPlatform, HyperPlatform_wdfsect 81 | [HyperPlatform_wdfsect] 82 | KmdfLibraryVersion = $KMDFVERSION$ 83 | 84 | [Strings] 85 | SPSVCINST_ASSOCSERVICE= 0x00000002 86 | ManufacturerName="" ;TODO: Replace with your manufacturer name 87 | ClassName="Samples" ; TODO: edit ClassName 88 | DiskName = "HyperPlatform Installation Disk" 89 | HyperPlatform.DeviceDesc = "HyperPlatform Device" 90 | HyperPlatform.SVCDESC = "HyperPlatform Service" 91 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/HyperPlatform/hotplug_callback.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. 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 | 5 | /// @file 6 | /// Implements hot-plug callback functions. 7 | 8 | #include "hotplug_callback.h" 9 | #include "common.h" 10 | #include "log.h" 11 | #include "vm.h" 12 | 13 | extern "C" { 14 | //////////////////////////////////////////////////////////////////////////////// 15 | // 16 | // macro utilities 17 | // 18 | 19 | //////////////////////////////////////////////////////////////////////////////// 20 | // 21 | // constants and macros 22 | // 23 | 24 | //////////////////////////////////////////////////////////////////////////////// 25 | // 26 | // types 27 | // 28 | 29 | //////////////////////////////////////////////////////////////////////////////// 30 | // 31 | // prototypes 32 | // 33 | 34 | static PROCESSOR_CALLBACK_FUNCTION HotplugCallbackpCallbackRoutine; 35 | 36 | #if defined(ALLOC_PRAGMA) 37 | #pragma alloc_text(INIT, HotplugCallbackInitialization) 38 | #pragma alloc_text(PAGE, HotplugCallbackTermination) 39 | #pragma alloc_text(PAGE, HotplugCallbackpCallbackRoutine) 40 | #endif 41 | 42 | //////////////////////////////////////////////////////////////////////////////// 43 | // 44 | // variables 45 | // 46 | 47 | static PVOID g_hpp_callback_handle = nullptr; 48 | 49 | //////////////////////////////////////////////////////////////////////////////// 50 | // 51 | // implementations 52 | // 53 | 54 | // Registers power callback 55 | _Use_decl_annotations_ NTSTATUS HotplugCallbackInitialization() { 56 | PAGED_CODE(); 57 | 58 | auto callback_handle = KeRegisterProcessorChangeCallback( 59 | HotplugCallbackpCallbackRoutine, nullptr, 0); 60 | if (!callback_handle) { 61 | return STATUS_UNSUCCESSFUL; 62 | } 63 | 64 | g_hpp_callback_handle = callback_handle; 65 | return STATUS_SUCCESS; 66 | } 67 | 68 | // Unregister power callback 69 | _Use_decl_annotations_ void HotplugCallbackTermination() { 70 | PAGED_CODE(); 71 | 72 | if (g_hpp_callback_handle) { 73 | KeDeregisterProcessorChangeCallback(g_hpp_callback_handle); 74 | } 75 | } 76 | 77 | _Use_decl_annotations_ static void HotplugCallbackpCallbackRoutine( 78 | PVOID callback_context, PKE_PROCESSOR_CHANGE_NOTIFY_CONTEXT change_context, 79 | PNTSTATUS operation_status) { 80 | PAGED_CODE(); 81 | UNREFERENCED_PARAMETER(callback_context); 82 | UNREFERENCED_PARAMETER(operation_status); 83 | 84 | if (change_context->State != KeProcessorAddCompleteNotify) { 85 | return; 86 | } 87 | 88 | HYPERPLATFORM_LOG_DEBUG("A new processor %hu:%hu has been added.", 89 | change_context->ProcNumber.Group, 90 | change_context->ProcNumber.Number); 91 | HYPERPLATFORM_COMMON_DBG_BREAK(); 92 | 93 | auto status = VmHotplugCallback(change_context->ProcNumber); 94 | if (!NT_SUCCESS(status)) { 95 | HYPERPLATFORM_LOG_ERROR("Failed to virtualize the new processors."); 96 | } 97 | } 98 | 99 | } // extern "C" 100 | -------------------------------------------------------------------------------- /kHypervisorBasic/hotplug_callback.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Implements hot-plug callback functions. 8 | 9 | #include "hotplug_callback.h" 10 | #include "common.h" 11 | #include "log.h" 12 | #include "vm.h" 13 | 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // prototypes 33 | // 34 | 35 | static PROCESSOR_CALLBACK_FUNCTION HotplugCallbackpCallbackRoutine; 36 | 37 | #if defined(ALLOC_PRAGMA) 38 | #pragma alloc_text(INIT, HotplugCallbackInitialization) 39 | #pragma alloc_text(PAGE, HotplugCallbackTermination) 40 | #pragma alloc_text(PAGE, HotplugCallbackpCallbackRoutine) 41 | #endif 42 | 43 | //////////////////////////////////////////////////////////////////////////////// 44 | // 45 | // variables 46 | // 47 | 48 | static PVOID g_hpp_callback_handle = nullptr; 49 | 50 | //////////////////////////////////////////////////////////////////////////////// 51 | // 52 | // implementations 53 | // 54 | 55 | // Registers power callback 56 | _Use_decl_annotations_ NTSTATUS HotplugCallbackInitialization() { 57 | PAGED_CODE(); 58 | 59 | auto callback_handle = KeRegisterProcessorChangeCallback( 60 | HotplugCallbackpCallbackRoutine, nullptr, 0); 61 | if (!callback_handle) { 62 | return STATUS_UNSUCCESSFUL; 63 | } 64 | 65 | g_hpp_callback_handle = callback_handle; 66 | return STATUS_SUCCESS; 67 | } 68 | 69 | // Unregister power callback 70 | _Use_decl_annotations_ void HotplugCallbackTermination() { 71 | PAGED_CODE(); 72 | 73 | if (g_hpp_callback_handle) { 74 | KeDeregisterProcessorChangeCallback(g_hpp_callback_handle); 75 | } 76 | } 77 | 78 | _Use_decl_annotations_ static void HotplugCallbackpCallbackRoutine( 79 | PVOID callback_context, PKE_PROCESSOR_CHANGE_NOTIFY_CONTEXT change_context, 80 | PNTSTATUS operation_status) { 81 | PAGED_CODE(); 82 | UNREFERENCED_PARAMETER(callback_context); 83 | UNREFERENCED_PARAMETER(operation_status); 84 | 85 | if (change_context->State != KeProcessorAddCompleteNotify) { 86 | return; 87 | } 88 | 89 | HYPERPLATFORM_LOG_DEBUG("A new processor %hu:%hu has been added.", 90 | change_context->ProcNumber.Group, 91 | change_context->ProcNumber.Number); 92 | HYPERPLATFORM_COMMON_DBG_BREAK(); 93 | 94 | auto status = VmHotplugCallback(change_context->ProcNumber); 95 | if (!NT_SUCCESS(status)) { 96 | HYPERPLATFORM_LOG_ERROR("Failed to virtualize the new processors."); 97 | } 98 | } 99 | 100 | } // extern "C" 101 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/hotplug_callback.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Implements hot-plug callback functions. 8 | 9 | #include "hotplug_callback.h" 10 | #include "common.h" 11 | #include "log.h" 12 | #include "vm.h" 13 | 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // prototypes 33 | // 34 | 35 | static PROCESSOR_CALLBACK_FUNCTION HotplugCallbackpCallbackRoutine; 36 | 37 | #if defined(ALLOC_PRAGMA) 38 | #pragma alloc_text(INIT, HotplugCallbackInitialization) 39 | #pragma alloc_text(PAGE, HotplugCallbackTermination) 40 | #pragma alloc_text(PAGE, HotplugCallbackpCallbackRoutine) 41 | #endif 42 | 43 | //////////////////////////////////////////////////////////////////////////////// 44 | // 45 | // variables 46 | // 47 | 48 | static PVOID g_hpp_callback_handle = nullptr; 49 | 50 | //////////////////////////////////////////////////////////////////////////////// 51 | // 52 | // implementations 53 | // 54 | 55 | // Registers power callback 56 | _Use_decl_annotations_ NTSTATUS HotplugCallbackInitialization() { 57 | PAGED_CODE(); 58 | 59 | auto callback_handle = KeRegisterProcessorChangeCallback( 60 | HotplugCallbackpCallbackRoutine, nullptr, 0); 61 | if (!callback_handle) { 62 | return STATUS_UNSUCCESSFUL; 63 | } 64 | 65 | g_hpp_callback_handle = callback_handle; 66 | return STATUS_SUCCESS; 67 | } 68 | 69 | // Unregister power callback 70 | _Use_decl_annotations_ void HotplugCallbackTermination() { 71 | PAGED_CODE(); 72 | 73 | if (g_hpp_callback_handle) { 74 | KeDeregisterProcessorChangeCallback(g_hpp_callback_handle); 75 | } 76 | } 77 | 78 | _Use_decl_annotations_ static void HotplugCallbackpCallbackRoutine( 79 | PVOID callback_context, PKE_PROCESSOR_CHANGE_NOTIFY_CONTEXT change_context, 80 | PNTSTATUS operation_status) { 81 | PAGED_CODE(); 82 | UNREFERENCED_PARAMETER(callback_context); 83 | UNREFERENCED_PARAMETER(operation_status); 84 | 85 | if (change_context->State != KeProcessorAddCompleteNotify) { 86 | return; 87 | } 88 | 89 | HYPERPLATFORM_LOG_DEBUG("A new processor %hu:%hu has been added.", 90 | change_context->ProcNumber.Group, 91 | change_context->ProcNumber.Number); 92 | HYPERPLATFORM_COMMON_DBG_BREAK(); 93 | 94 | auto status = VmHotplugCallback(change_context->ProcNumber); 95 | if (!NT_SUCCESS(status)) { 96 | HYPERPLATFORM_LOG_ERROR("Failed to virtualize the new processors."); 97 | } 98 | } 99 | 100 | } // extern "C" 101 | -------------------------------------------------------------------------------- /kHypervisorBasic/vmcs.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2016 KelvinChan. All rights reserved. 4 | Use of this source code is governed by a MIT-style license that can be 5 | found in the LICENSE file. 6 | 7 | Module Name: 8 | 9 | vmcs.h 10 | 11 | Abstract: 12 | 13 | VMCS utilies 14 | 15 | Author: 16 | 17 | Kelvin Chan 18 | 19 | Environment: 20 | 21 | Kernel VMM Mode 22 | 23 | --*/ 24 | #include 25 | #include "asm.h" 26 | 27 | extern "C" 28 | { 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // macro utilities 33 | // 34 | #define PrintVMCS(){ VmcsPrintAllField(__func__);} 35 | #define PrintVMCS12(vmcs12){ VmcsPrintAllFieldForVmcs12(__func__, vmcs12);} 36 | 37 | //////////////////////////////////////////////////////////////////////////////// 38 | // 39 | // constants and macros 40 | // 41 | #define CHECK_BOUNDARY_FOR_IA32 0xFFFFFFFF00000000 42 | #define CHECK_PAGE_ALGINMENT 0xFFF 43 | #define VMX_HIGHEST_VMCS_ENCODING 0x2C 44 | #define VMCS_DATA_OFFSET 0x0010 45 | #define VMX_VMCS_AREA_SIZE 0x1000 46 | 47 | #define VMCS_FIELD_WIDTH_16BIT 0x0 48 | #define VMCS_FIELD_WIDTH_64BIT 0x1 49 | #define VMCS_FIELD_WIDTH_32BIT 0x2 50 | #define VMCS_FIELD_WIDTH_NATURAL_WIDTH 0x3 51 | 52 | 53 | #define MY_SUPPORT_VMX 2 54 | 55 | //////////////////////////////////////////////////////////////////////////////// 56 | // 57 | // types 58 | // 59 | 60 | 61 | //////////////////////////////////////////////////////////////////////////////// 62 | // 63 | // prototype 64 | // 65 | VOID 66 | BuildGernericVMCSMap(); 67 | 68 | BOOLEAN 69 | RegularCheck(); 70 | 71 | BOOLEAN 72 | is_vmcs_field_supported( 73 | _In_ VmcsField encoding 74 | ); 75 | 76 | VOID 77 | VmcsVmRead64( 78 | _In_ VmcsField Field, 79 | _In_ ULONG_PTR base, 80 | _In_ PULONG64 destination 81 | ); 82 | 83 | VOID 84 | VmcsVmRead32( 85 | _In_ VmcsField Field, 86 | _In_ ULONG_PTR base, 87 | _In_ PULONG32 destination 88 | ); 89 | 90 | VOID 91 | VmcsVmRead16( 92 | _In_ VmcsField Field, 93 | _In_ ULONG_PTR base, 94 | _In_ PUSHORT destination 95 | ); 96 | 97 | VOID 98 | VmcsVmWrite64( 99 | _In_ VmcsField Field, 100 | _In_ ULONG_PTR base, 101 | _In_ ULONG_PTR value 102 | ); 103 | 104 | VOID 105 | VmcsVmWrite32( 106 | _In_ VmcsField Field, 107 | _In_ ULONG_PTR base, 108 | _In_ ULONG_PTR value 109 | ); 110 | 111 | VOID 112 | VmcsVmWrite16( 113 | _In_ VmcsField Field, 114 | _In_ ULONG_PTR base, 115 | _In_ ULONG_PTR value 116 | ); 117 | 118 | VmcsField 119 | VmcsDecodeVmwriteOrVmRead( 120 | _In_ GpRegisters* guest_context, 121 | _In_ ULONG_PTR* Offset, 122 | _In_ ULONG_PTR* Value, 123 | _In_ BOOLEAN* RorM, 124 | _In_ ULONG_PTR* RegIndex = NULL, 125 | _In_ ULONG_PTR* MemAddr = NULL 126 | ); 127 | 128 | 129 | VOID 130 | VmcsPrepareHostAndControlField( 131 | _In_ ULONG_PTR vmcs12_va, 132 | _In_ ULONG_PTR vmcs02_va, 133 | _In_ BOOLEAN isLaunch 134 | ); 135 | 136 | VOID 137 | VmcsPrepareGuestStateField( 138 | _In_ ULONG_PTR guest_vmcs_va 139 | ); 140 | 141 | VOID 142 | VmcsPrintControlField(); 143 | 144 | VOID 145 | VmcsPrintHostStateField(); 146 | 147 | VOID 148 | VmcsPrintGuestStateField(); 149 | 150 | VOID 151 | VmcsPrintReadOnlyField(); 152 | 153 | VOID 154 | VmcsPrintAllField( 155 | _In_ const char* func 156 | ); 157 | 158 | VOID 159 | VmcsPrintReadOnlyFieldForVmcs12( 160 | _In_ ULONG64 vmcs12_va 161 | ); 162 | 163 | VOID 164 | VmcsPrintAllFieldForVmcs12( 165 | _In_ const char* func, 166 | _In_ ULONG64 vmcs12 167 | ); 168 | 169 | } 170 | #pragma once 171 | -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/vmcs.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2016 KelvinChan. All rights reserved. 4 | Use of this source code is governed by a MIT-style license that can be 5 | found in the LICENSE file. 6 | 7 | Module Name: 8 | 9 | vmcs.h 10 | 11 | Abstract: 12 | 13 | VMCS utilies 14 | 15 | Author: 16 | 17 | Kelvin Chan 18 | 19 | Environment: 20 | 21 | Kernel VMM Mode 22 | 23 | --*/ 24 | #include 25 | #include "..\HyperPlatform\asm.h" 26 | 27 | extern "C" 28 | { 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // macro utilities 33 | // 34 | #define PrintVMCS(){ VmcsPrintAllField(__func__);} 35 | #define PrintVMCS12(vmcs12){ VmcsPrintAllFieldForVmcs12(__func__, vmcs12);} 36 | 37 | //////////////////////////////////////////////////////////////////////////////// 38 | // 39 | // constants and macros 40 | // 41 | #define CHECK_BOUNDARY_FOR_IA32 0xFFFFFFFF00000000 42 | #define CHECK_PAGE_ALGINMENT 0xFFF 43 | #define VMX_HIGHEST_VMCS_ENCODING 0x2C 44 | #define VMCS_DATA_OFFSET 0x0010 45 | #define VMX_VMCS_AREA_SIZE 0x1000 46 | 47 | #define VMCS_FIELD_WIDTH_16BIT 0x0 48 | #define VMCS_FIELD_WIDTH_64BIT 0x1 49 | #define VMCS_FIELD_WIDTH_32BIT 0x2 50 | #define VMCS_FIELD_WIDTH_NATURAL_WIDTH 0x3 51 | 52 | 53 | #define MY_SUPPORT_VMX 2 54 | 55 | //////////////////////////////////////////////////////////////////////////////// 56 | // 57 | // types 58 | // 59 | 60 | 61 | //////////////////////////////////////////////////////////////////////////////// 62 | // 63 | // prototype 64 | // 65 | VOID 66 | BuildGernericVMCSMap(); 67 | 68 | BOOLEAN 69 | RegularCheck(); 70 | 71 | BOOLEAN 72 | is_vmcs_field_supported( 73 | _In_ VmcsField encoding 74 | ); 75 | 76 | VOID 77 | VmcsVmRead64( 78 | _In_ VmcsField Field, 79 | _In_ ULONG_PTR base, 80 | _In_ PULONG64 destination 81 | ); 82 | 83 | VOID 84 | VmcsVmRead32( 85 | _In_ VmcsField Field, 86 | _In_ ULONG_PTR base, 87 | _In_ PULONG32 destination 88 | ); 89 | 90 | VOID 91 | VmcsVmRead16( 92 | _In_ VmcsField Field, 93 | _In_ ULONG_PTR base, 94 | _In_ PUSHORT destination 95 | ); 96 | 97 | VOID 98 | VmcsVmWrite64( 99 | _In_ VmcsField Field, 100 | _In_ ULONG_PTR base, 101 | _In_ ULONG_PTR value 102 | ); 103 | 104 | VOID 105 | VmcsVmWrite32( 106 | _In_ VmcsField Field, 107 | _In_ ULONG_PTR base, 108 | _In_ ULONG_PTR value 109 | ); 110 | 111 | VOID 112 | VmcsVmWrite16( 113 | _In_ VmcsField Field, 114 | _In_ ULONG_PTR base, 115 | _In_ ULONG_PTR value 116 | ); 117 | 118 | VmcsField 119 | VmcsDecodeVmwriteOrVmRead( 120 | _In_ GpRegisters* guest_context, 121 | _In_ ULONG_PTR* Offset, 122 | _In_ ULONG_PTR* Value, 123 | _In_ BOOLEAN* RorM, 124 | _In_ ULONG_PTR* RegIndex = NULL, 125 | _In_ ULONG_PTR* MemAddr = NULL 126 | ); 127 | 128 | 129 | VOID 130 | VmcsPrepareHostAndControlField( 131 | _In_ ULONG_PTR vmcs12_va, 132 | _In_ ULONG_PTR vmcs02_va, 133 | _In_ BOOLEAN isLaunch 134 | ); 135 | 136 | VOID 137 | VmcsPrepareGuestStateField( 138 | _In_ ULONG_PTR guest_vmcs_va 139 | ); 140 | 141 | VOID 142 | VmcsPrintControlField(); 143 | 144 | VOID 145 | VmcsPrintHostStateField(); 146 | 147 | VOID 148 | VmcsPrintGuestStateField(); 149 | 150 | VOID 151 | VmcsPrintReadOnlyField(); 152 | 153 | VOID 154 | VmcsPrintAllField( 155 | _In_ const char* func 156 | ); 157 | 158 | VOID 159 | VmcsPrintReadOnlyFieldForVmcs12( 160 | _In_ ULONG64 vmcs12_va 161 | ); 162 | 163 | VOID 164 | VmcsPrintAllFieldForVmcs12( 165 | _In_ const char* func, 166 | _In_ ULONG64 vmcs12 167 | ); 168 | 169 | } 170 | #pragma once 171 | -------------------------------------------------------------------------------- /kHypervisorBasic/performance.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Implements performance measurement functions. 8 | 9 | #include "performance.h" 10 | #include "common.h" 11 | #include "log.h" 12 | 13 | //////////////////////////////////////////////////////////////////////////////// 14 | // 15 | // macro utilities 16 | // 17 | 18 | //////////////////////////////////////////////////////////////////////////////// 19 | // 20 | // constants and macros 21 | // 22 | 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // 25 | // types 26 | // 27 | 28 | //////////////////////////////////////////////////////////////////////////////// 29 | // 30 | // prototypes 31 | // 32 | 33 | static PerfCollector::InitialOutputRoutine PerfpInitialOutputRoutine; 34 | static PerfCollector::OutputRoutine PerfpOutputRoutine; 35 | static PerfCollector::FinalOutputRoutine PerfpFinalOutputRoutine; 36 | 37 | #if defined(ALLOC_PRAGMA) 38 | #pragma alloc_text(INIT, PerfInitialization) 39 | #pragma alloc_text(PAGE, PerfTermination) 40 | #endif 41 | 42 | //////////////////////////////////////////////////////////////////////////////// 43 | // 44 | // variables 45 | // 46 | 47 | PerfCollector* g_performance_collector; 48 | 49 | //////////////////////////////////////////////////////////////////////////////// 50 | // 51 | // implementations 52 | // 53 | 54 | _Use_decl_annotations_ NTSTATUS PerfInitialization() { 55 | PAGED_CODE(); 56 | auto status = STATUS_SUCCESS; 57 | 58 | const auto perf_collector = 59 | reinterpret_cast(ExAllocatePoolWithTag( 60 | NonPagedPool, sizeof(PerfCollector), kHyperPlatformCommonPoolTag)); 61 | if (!perf_collector) { 62 | return STATUS_MEMORY_NOT_ALLOCATED; 63 | } 64 | 65 | // No lock to avoid calling kernel APIs from VMM and race condition here is 66 | // not an issue. 67 | perf_collector->Initialize(PerfpOutputRoutine, PerfpInitialOutputRoutine, 68 | PerfpFinalOutputRoutine); 69 | 70 | g_performance_collector = perf_collector; 71 | return status; 72 | } 73 | 74 | _Use_decl_annotations_ void PerfTermination() { 75 | PAGED_CODE(); 76 | 77 | if (g_performance_collector) { 78 | g_performance_collector->Terminate(); 79 | ExFreePoolWithTag(g_performance_collector, kHyperPlatformCommonPoolTag); 80 | g_performance_collector = nullptr; 81 | } 82 | } 83 | 84 | /*_Use_decl_annotations_*/ ULONG64 PerfGetTime() { 85 | LARGE_INTEGER counter = KeQueryPerformanceCounter(nullptr); 86 | return static_cast(counter.QuadPart); 87 | } 88 | 89 | _Use_decl_annotations_ static void PerfpInitialOutputRoutine( 90 | void* output_context) { 91 | UNREFERENCED_PARAMETER(output_context); 92 | HYPERPLATFORM_LOG_INFO("%-45s,%-20s,%-20s", "FunctionName(Line)", 93 | "Execution Count", "Elapsed Time"); 94 | } 95 | 96 | _Use_decl_annotations_ static void PerfpOutputRoutine( 97 | const char* location_name, ULONG64 total_execution_count, 98 | ULONG64 total_elapsed_time, void* output_context) { 99 | UNREFERENCED_PARAMETER(output_context); 100 | HYPERPLATFORM_LOG_INFO("%-45s,%20I64u,%20I64u,", location_name, 101 | total_execution_count, total_elapsed_time); 102 | } 103 | 104 | _Use_decl_annotations_ static void PerfpFinalOutputRoutine( 105 | void* output_context) { 106 | UNREFERENCED_PARAMETER(output_context); 107 | } 108 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/performance.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Implements performance measurement functions. 8 | 9 | #include "performance.h" 10 | #include "common.h" 11 | #include "log.h" 12 | 13 | //////////////////////////////////////////////////////////////////////////////// 14 | // 15 | // macro utilities 16 | // 17 | 18 | //////////////////////////////////////////////////////////////////////////////// 19 | // 20 | // constants and macros 21 | // 22 | 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // 25 | // types 26 | // 27 | 28 | //////////////////////////////////////////////////////////////////////////////// 29 | // 30 | // prototypes 31 | // 32 | 33 | static PerfCollector::InitialOutputRoutine PerfpInitialOutputRoutine; 34 | static PerfCollector::OutputRoutine PerfpOutputRoutine; 35 | static PerfCollector::FinalOutputRoutine PerfpFinalOutputRoutine; 36 | 37 | #if defined(ALLOC_PRAGMA) 38 | #pragma alloc_text(INIT, PerfInitialization) 39 | #pragma alloc_text(PAGE, PerfTermination) 40 | #endif 41 | 42 | //////////////////////////////////////////////////////////////////////////////// 43 | // 44 | // variables 45 | // 46 | 47 | PerfCollector* g_performance_collector; 48 | 49 | //////////////////////////////////////////////////////////////////////////////// 50 | // 51 | // implementations 52 | // 53 | 54 | _Use_decl_annotations_ NTSTATUS PerfInitialization() { 55 | PAGED_CODE(); 56 | auto status = STATUS_SUCCESS; 57 | 58 | const auto perf_collector = 59 | reinterpret_cast(ExAllocatePoolWithTag( 60 | NonPagedPool, sizeof(PerfCollector), kHyperPlatformCommonPoolTag)); 61 | if (!perf_collector) { 62 | return STATUS_MEMORY_NOT_ALLOCATED; 63 | } 64 | 65 | // No lock to avoid calling kernel APIs from VMM and race condition here is 66 | // not an issue. 67 | perf_collector->Initialize(PerfpOutputRoutine, PerfpInitialOutputRoutine, 68 | PerfpFinalOutputRoutine); 69 | 70 | g_performance_collector = perf_collector; 71 | return status; 72 | } 73 | 74 | _Use_decl_annotations_ void PerfTermination() { 75 | PAGED_CODE(); 76 | 77 | if (g_performance_collector) { 78 | g_performance_collector->Terminate(); 79 | ExFreePoolWithTag(g_performance_collector, kHyperPlatformCommonPoolTag); 80 | g_performance_collector = nullptr; 81 | } 82 | } 83 | 84 | /*_Use_decl_annotations_*/ ULONG64 PerfGetTime() { 85 | LARGE_INTEGER counter = KeQueryPerformanceCounter(nullptr); 86 | return static_cast(counter.QuadPart); 87 | } 88 | 89 | _Use_decl_annotations_ static void PerfpInitialOutputRoutine( 90 | void* output_context) { 91 | UNREFERENCED_PARAMETER(output_context); 92 | HYPERPLATFORM_LOG_INFO("%-45s,%-20s,%-20s", "FunctionName(Line)", 93 | "Execution Count", "Elapsed Time"); 94 | } 95 | 96 | _Use_decl_annotations_ static void PerfpOutputRoutine( 97 | const char* location_name, ULONG64 total_execution_count, 98 | ULONG64 total_elapsed_time, void* output_context) { 99 | UNREFERENCED_PARAMETER(output_context); 100 | HYPERPLATFORM_LOG_INFO("%-45s,%20I64u,%20I64u,", location_name, 101 | total_execution_count, total_elapsed_time); 102 | } 103 | 104 | _Use_decl_annotations_ static void PerfpFinalOutputRoutine( 105 | void* output_context) { 106 | UNREFERENCED_PARAMETER(output_context); 107 | } 108 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/HyperPlatform/power_callback.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. 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 | 5 | /// @file 6 | /// Implements power callback functions. 7 | 8 | #include "power_callback.h" 9 | #include "common.h" 10 | #include "log.h" 11 | #include "vm.h" 12 | 13 | extern "C" { 14 | //////////////////////////////////////////////////////////////////////////////// 15 | // 16 | // macro utilities 17 | // 18 | 19 | //////////////////////////////////////////////////////////////////////////////// 20 | // 21 | // constants and macros 22 | // 23 | 24 | //////////////////////////////////////////////////////////////////////////////// 25 | // 26 | // types 27 | // 28 | 29 | //////////////////////////////////////////////////////////////////////////////// 30 | // 31 | // prototypes 32 | // 33 | 34 | static CALLBACK_FUNCTION PowerCallbackpCallbackRoutine; 35 | 36 | #if defined(ALLOC_PRAGMA) 37 | #pragma alloc_text(INIT, PowerCallbackInitialization) 38 | #pragma alloc_text(PAGE, PowerCallbackTermination) 39 | #pragma alloc_text(PAGE, PowerCallbackpCallbackRoutine) 40 | #endif 41 | 42 | //////////////////////////////////////////////////////////////////////////////// 43 | // 44 | // variables 45 | // 46 | 47 | static PCALLBACK_OBJECT g_pcp_callback_object = nullptr; 48 | static PVOID g_pcp_registration = nullptr; 49 | 50 | //////////////////////////////////////////////////////////////////////////////// 51 | // 52 | // implementations 53 | // 54 | 55 | // Registers power callback 56 | _Use_decl_annotations_ NTSTATUS PowerCallbackInitialization() { 57 | PAGED_CODE(); 58 | 59 | UNICODE_STRING name = RTL_CONSTANT_STRING(L"\\Callback\\PowerState"); 60 | OBJECT_ATTRIBUTES oa = 61 | RTL_CONSTANT_OBJECT_ATTRIBUTES(&name, OBJ_CASE_INSENSITIVE); 62 | 63 | auto status = ExCreateCallback(&g_pcp_callback_object, &oa, FALSE, TRUE); 64 | if (!NT_SUCCESS(status)) { 65 | return status; 66 | } 67 | 68 | g_pcp_registration = ExRegisterCallback( 69 | g_pcp_callback_object, PowerCallbackpCallbackRoutine, nullptr); 70 | if (!g_pcp_registration) { 71 | ObDereferenceObject(g_pcp_callback_object); 72 | g_pcp_callback_object = nullptr; 73 | return STATUS_UNSUCCESSFUL; 74 | } 75 | return status; 76 | } 77 | 78 | // Unregister power callback 79 | _Use_decl_annotations_ void PowerCallbackTermination() { 80 | PAGED_CODE(); 81 | 82 | if (g_pcp_registration) { 83 | ExUnregisterCallback(g_pcp_registration); 84 | } 85 | if (g_pcp_callback_object) { 86 | ObDereferenceObject(g_pcp_callback_object); 87 | } 88 | } 89 | 90 | // Power callback routine dealing with hibernate and sleep 91 | _Use_decl_annotations_ static void PowerCallbackpCallbackRoutine( 92 | PVOID callback_context, PVOID argument1, PVOID argument2) { 93 | UNREFERENCED_PARAMETER(callback_context); 94 | PAGED_CODE(); 95 | 96 | if (argument1 != reinterpret_cast(PO_CB_SYSTEM_STATE_LOCK)) { 97 | return; 98 | } 99 | 100 | HYPERPLATFORM_COMMON_DBG_BREAK(); 101 | 102 | if (argument2) { 103 | // the computer has just reentered S0. 104 | HYPERPLATFORM_LOG_INFO("Resuming the system..."); 105 | auto status = VmInitialization(); 106 | if (!NT_SUCCESS(status)) { 107 | HYPERPLATFORM_LOG_ERROR( 108 | "Failed to re-virtualize processors. Please unload the driver."); 109 | } 110 | } else { 111 | // the computer is about to exit system power state S0 112 | HYPERPLATFORM_LOG_INFO("Suspending the system..."); 113 | VmTermination(); 114 | } 115 | } 116 | 117 | } // extern "C" 118 | -------------------------------------------------------------------------------- /kHypervisorBasic/include/windowsce/stdint.h: -------------------------------------------------------------------------------- 1 | 2 | #if defined(_MSC_VER) && defined(_WIN32_WCE) && (_WIN32_WCE < 0x800) && !defined(_STDINT_H_) && !defined(_STDINT) 3 | #define _STDINT 4 | 5 | typedef __int8 6 | int8_t, 7 | int_least8_t; 8 | 9 | typedef __int16 10 | int16_t, 11 | int_least16_t; 12 | 13 | typedef __int32 14 | int32_t, 15 | int_least32_t, 16 | int_fast8_t, 17 | int_fast16_t, 18 | int_fast32_t; 19 | 20 | typedef __int64 21 | int64_t, 22 | intmax_t, 23 | int_least64_t, 24 | int_fast64_t; 25 | 26 | typedef unsigned __int8 27 | uint8_t, 28 | uint_least8_t; 29 | 30 | typedef unsigned __int16 31 | uint16_t, 32 | uint_least16_t; 33 | 34 | typedef unsigned __int32 35 | uint32_t, 36 | uint_least32_t, 37 | uint_fast8_t, 38 | uint_fast16_t, 39 | uint_fast32_t; 40 | 41 | typedef unsigned __int64 42 | uint64_t, 43 | uintmax_t, 44 | uint_least64_t, 45 | uint_fast64_t; 46 | 47 | #ifndef _INTPTR_T_DEFINED 48 | #define _INTPTR_T_DEFINED 49 | typedef __int32 intptr_t; 50 | #endif 51 | 52 | #ifndef _UINTPTR_T_DEFINED 53 | #define _UINTPTR_T_DEFINED 54 | typedef unsigned __int32 uintptr_t; 55 | #endif 56 | 57 | #define INT8_MIN (-127i8 - 1) 58 | #define INT16_MIN (-32767i16 - 1) 59 | #define INT32_MIN (-2147483647i32 - 1) 60 | #define INT64_MIN (-9223372036854775807i64 - 1) 61 | #define INT8_MAX 127i8 62 | #define INT16_MAX 32767i16 63 | #define INT32_MAX 2147483647i32 64 | #define INT64_MAX 9223372036854775807i64 65 | #define UINT8_MAX 0xffui8 66 | #define UINT16_MAX 0xffffui16 67 | #define UINT32_MAX 0xffffffffui32 68 | #define UINT64_MAX 0xffffffffffffffffui64 69 | 70 | #define INT_LEAST8_MIN INT8_MIN 71 | #define INT_LEAST16_MIN INT16_MIN 72 | #define INT_LEAST32_MIN INT32_MIN 73 | #define INT_LEAST64_MIN INT64_MIN 74 | #define INT_LEAST8_MAX INT8_MAX 75 | #define INT_LEAST16_MAX INT16_MAX 76 | #define INT_LEAST32_MAX INT32_MAX 77 | #define INT_LEAST64_MAX INT64_MAX 78 | #define UINT_LEAST8_MAX UINT8_MAX 79 | #define UINT_LEAST16_MAX UINT16_MAX 80 | #define UINT_LEAST32_MAX UINT32_MAX 81 | #define UINT_LEAST64_MAX UINT64_MAX 82 | 83 | #define INT_FAST8_MIN INT8_MIN 84 | #define INT_FAST16_MIN INT32_MIN 85 | #define INT_FAST32_MIN INT32_MIN 86 | #define INT_FAST64_MIN INT64_MIN 87 | #define INT_FAST8_MAX INT8_MAX 88 | #define INT_FAST16_MAX INT32_MAX 89 | #define INT_FAST32_MAX INT32_MAX 90 | #define INT_FAST64_MAX INT64_MAX 91 | #define UINT_FAST8_MAX UINT8_MAX 92 | #define UINT_FAST16_MAX UINT32_MAX 93 | #define UINT_FAST32_MAX UINT32_MAX 94 | #define UINT_FAST64_MAX UINT64_MAX 95 | 96 | #define INTPTR_MIN INT32_MIN 97 | #define INTPTR_MAX INT32_MAX 98 | #define UINTPTR_MAX UINT32_MAX 99 | 100 | #define INTMAX_MIN INT64_MIN 101 | #define INTMAX_MAX INT64_MAX 102 | #define UINTMAX_MAX UINT64_MAX 103 | 104 | #define PTRDIFF_MIN INTPTR_MIN 105 | #define PTRDIFF_MAX INTPTR_MAX 106 | 107 | #ifndef SIZE_MAX 108 | #define SIZE_MAX UINTPTR_MAX 109 | #endif 110 | 111 | #define SIG_ATOMIC_MIN INT32_MIN 112 | #define SIG_ATOMIC_MAX INT32_MAX 113 | 114 | #define WCHAR_MIN 0x0000 115 | #define WCHAR_MAX 0xffff 116 | 117 | #define WINT_MIN 0x0000 118 | #define WINT_MAX 0xffff 119 | 120 | #define INT8_C(x) (x) 121 | #define INT16_C(x) (x) 122 | #define INT32_C(x) (x) 123 | #define INT64_C(x) (x ## LL) 124 | 125 | #define UINT8_C(x) (x) 126 | #define UINT16_C(x) (x) 127 | #define UINT32_C(x) (x ## U) 128 | #define UINT64_C(x) (x ## ULL) 129 | 130 | #define INTMAX_C(x) INT64_C(x) 131 | #define UINTMAX_C(x) UINT64_C(x) 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /kHypervisorBasic/power_callback.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Implements power callback functions. 8 | 9 | #include "power_callback.h" 10 | #include "common.h" 11 | #include "log.h" 12 | #include "vm.h" 13 | 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // prototypes 33 | // 34 | 35 | static CALLBACK_FUNCTION PowerCallbackpCallbackRoutine; 36 | 37 | #if defined(ALLOC_PRAGMA) 38 | #pragma alloc_text(INIT, PowerCallbackInitialization) 39 | #pragma alloc_text(PAGE, PowerCallbackTermination) 40 | #pragma alloc_text(PAGE, PowerCallbackpCallbackRoutine) 41 | #endif 42 | 43 | //////////////////////////////////////////////////////////////////////////////// 44 | // 45 | // variables 46 | // 47 | 48 | static PCALLBACK_OBJECT g_pcp_callback_object = nullptr; 49 | static PVOID g_pcp_registration = nullptr; 50 | 51 | //////////////////////////////////////////////////////////////////////////////// 52 | // 53 | // implementations 54 | // 55 | 56 | // Registers power callback 57 | _Use_decl_annotations_ NTSTATUS PowerCallbackInitialization() { 58 | PAGED_CODE(); 59 | 60 | UNICODE_STRING name = RTL_CONSTANT_STRING(L"\\Callback\\PowerState"); 61 | OBJECT_ATTRIBUTES oa = 62 | RTL_CONSTANT_OBJECT_ATTRIBUTES(&name, OBJ_CASE_INSENSITIVE); 63 | 64 | auto status = ExCreateCallback(&g_pcp_callback_object, &oa, FALSE, TRUE); 65 | if (!NT_SUCCESS(status)) { 66 | return status; 67 | } 68 | 69 | g_pcp_registration = ExRegisterCallback( 70 | g_pcp_callback_object, PowerCallbackpCallbackRoutine, nullptr); 71 | if (!g_pcp_registration) { 72 | ObDereferenceObject(g_pcp_callback_object); 73 | g_pcp_callback_object = nullptr; 74 | return STATUS_UNSUCCESSFUL; 75 | } 76 | return status; 77 | } 78 | 79 | // Unregister power callback 80 | _Use_decl_annotations_ void PowerCallbackTermination() { 81 | PAGED_CODE(); 82 | 83 | if (g_pcp_registration) { 84 | ExUnregisterCallback(g_pcp_registration); 85 | } 86 | if (g_pcp_callback_object) { 87 | ObDereferenceObject(g_pcp_callback_object); 88 | } 89 | } 90 | 91 | // Power callback routine dealing with hibernate and sleep 92 | _Use_decl_annotations_ static void PowerCallbackpCallbackRoutine( 93 | PVOID callback_context, PVOID argument1, PVOID argument2) { 94 | UNREFERENCED_PARAMETER(callback_context); 95 | PAGED_CODE(); 96 | 97 | if (argument1 != reinterpret_cast(PO_CB_SYSTEM_STATE_LOCK)) { 98 | return; 99 | } 100 | 101 | HYPERPLATFORM_COMMON_DBG_BREAK(); 102 | 103 | if (argument2) { 104 | // the computer has just reentered S0. 105 | HYPERPLATFORM_LOG_INFO("Resuming the system..."); 106 | auto status = VmInitialization(); 107 | if (!NT_SUCCESS(status)) { 108 | HYPERPLATFORM_LOG_ERROR( 109 | "Failed to re-virtualize processors. Please unload the driver."); 110 | } 111 | } else { 112 | // the computer is about to exit system power state S0 113 | HYPERPLATFORM_LOG_INFO("Suspending the system..."); 114 | VmTermination(); 115 | } 116 | } 117 | 118 | } // extern "C" 119 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/power_callback.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Implements power callback functions. 8 | 9 | #include "power_callback.h" 10 | #include "common.h" 11 | #include "log.h" 12 | #include "vm.h" 13 | 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // prototypes 33 | // 34 | 35 | static CALLBACK_FUNCTION PowerCallbackpCallbackRoutine; 36 | 37 | #if defined(ALLOC_PRAGMA) 38 | #pragma alloc_text(INIT, PowerCallbackInitialization) 39 | #pragma alloc_text(PAGE, PowerCallbackTermination) 40 | #pragma alloc_text(PAGE, PowerCallbackpCallbackRoutine) 41 | #endif 42 | 43 | //////////////////////////////////////////////////////////////////////////////// 44 | // 45 | // variables 46 | // 47 | 48 | static PCALLBACK_OBJECT g_pcp_callback_object = nullptr; 49 | static PVOID g_pcp_registration = nullptr; 50 | 51 | //////////////////////////////////////////////////////////////////////////////// 52 | // 53 | // implementations 54 | // 55 | 56 | // Registers power callback 57 | _Use_decl_annotations_ NTSTATUS PowerCallbackInitialization() { 58 | PAGED_CODE(); 59 | 60 | UNICODE_STRING name = RTL_CONSTANT_STRING(L"\\Callback\\PowerState"); 61 | OBJECT_ATTRIBUTES oa = 62 | RTL_CONSTANT_OBJECT_ATTRIBUTES(&name, OBJ_CASE_INSENSITIVE); 63 | 64 | auto status = ExCreateCallback(&g_pcp_callback_object, &oa, FALSE, TRUE); 65 | if (!NT_SUCCESS(status)) { 66 | return status; 67 | } 68 | 69 | g_pcp_registration = ExRegisterCallback( 70 | g_pcp_callback_object, PowerCallbackpCallbackRoutine, nullptr); 71 | if (!g_pcp_registration) { 72 | ObDereferenceObject(g_pcp_callback_object); 73 | g_pcp_callback_object = nullptr; 74 | return STATUS_UNSUCCESSFUL; 75 | } 76 | return status; 77 | } 78 | 79 | // Unregister power callback 80 | _Use_decl_annotations_ void PowerCallbackTermination() { 81 | PAGED_CODE(); 82 | 83 | if (g_pcp_registration) { 84 | ExUnregisterCallback(g_pcp_registration); 85 | } 86 | if (g_pcp_callback_object) { 87 | ObDereferenceObject(g_pcp_callback_object); 88 | } 89 | } 90 | 91 | // Power callback routine dealing with hibernate and sleep 92 | _Use_decl_annotations_ static void PowerCallbackpCallbackRoutine( 93 | PVOID callback_context, PVOID argument1, PVOID argument2) { 94 | UNREFERENCED_PARAMETER(callback_context); 95 | PAGED_CODE(); 96 | 97 | if (argument1 != reinterpret_cast(PO_CB_SYSTEM_STATE_LOCK)) { 98 | return; 99 | } 100 | 101 | HYPERPLATFORM_COMMON_DBG_BREAK(); 102 | 103 | if (argument2) { 104 | // the computer has just reentered S0. 105 | HYPERPLATFORM_LOG_INFO("Resuming the system..."); 106 | auto status = VmInitialization(); 107 | if (!NT_SUCCESS(status)) { 108 | HYPERPLATFORM_LOG_ERROR( 109 | "Failed to re-virtualize processors. Please unload the driver."); 110 | } 111 | } else { 112 | // the computer is about to exit system power state S0 113 | HYPERPLATFORM_LOG_INFO("Suspending the system..."); 114 | VmTermination(); 115 | } 116 | } 117 | 118 | } // extern "C" 119 | -------------------------------------------------------------------------------- /kHypervisorBasic/include/platform.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Axel Souchet & Nguyen Anh Quynh, 2014 */ 3 | 4 | #ifndef CAPSTONE_PLATFORM_H 5 | #define CAPSTONE_PLATFORM_H 6 | 7 | // handle C99 issue (for pre-2013 VisualStudio) 8 | #if !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)) 9 | // MSVC 10 | 11 | // stdbool.h 12 | #if (_MSC_VER < 1800) || defined(_KERNEL_MODE) 13 | // this system does not have stdbool.h 14 | #ifndef __cplusplus 15 | typedef unsigned char bool; 16 | #define false 0 17 | #define true 1 18 | #endif 19 | 20 | #else 21 | // VisualStudio 2013+ -> C99 is supported 22 | #include 23 | #endif 24 | 25 | #else 26 | // not MSVC -> C99 is supported 27 | #include 28 | #endif 29 | 30 | 31 | // handle C99 issue (for pre-2013 VisualStudio) 32 | #if defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE))) 33 | // this system does not have inttypes.h 34 | 35 | #if defined(_MSC_VER) && (_MSC_VER < 1600 || defined(_KERNEL_MODE)) 36 | // this system does not have stdint.h 37 | typedef signed char int8_t; 38 | typedef signed short int16_t; 39 | typedef signed int int32_t; 40 | typedef unsigned char uint8_t; 41 | typedef unsigned short uint16_t; 42 | typedef unsigned int uint32_t; 43 | typedef signed long long int64_t; 44 | typedef unsigned long long uint64_t; 45 | 46 | #define INT8_MIN (-127i8 - 1) 47 | #define INT16_MIN (-32767i16 - 1) 48 | #define INT32_MIN (-2147483647i32 - 1) 49 | #define INT64_MIN (-9223372036854775807i64 - 1) 50 | #define INT8_MAX 127i8 51 | #define INT16_MAX 32767i16 52 | #define INT32_MAX 2147483647i32 53 | #define INT64_MAX 9223372036854775807i64 54 | #define UINT8_MAX 0xffui8 55 | #define UINT16_MAX 0xffffui16 56 | #define UINT32_MAX 0xffffffffui32 57 | #define UINT64_MAX 0xffffffffffffffffui64 58 | #endif 59 | 60 | #define __PRI_8_LENGTH_MODIFIER__ "hh" 61 | #define __PRI_64_LENGTH_MODIFIER__ "ll" 62 | 63 | #define PRId8 __PRI_8_LENGTH_MODIFIER__ "d" 64 | #define PRIi8 __PRI_8_LENGTH_MODIFIER__ "i" 65 | #define PRIo8 __PRI_8_LENGTH_MODIFIER__ "o" 66 | #define PRIu8 __PRI_8_LENGTH_MODIFIER__ "u" 67 | #define PRIx8 __PRI_8_LENGTH_MODIFIER__ "x" 68 | #define PRIX8 __PRI_8_LENGTH_MODIFIER__ "X" 69 | 70 | #define PRId16 "hd" 71 | #define PRIi16 "hi" 72 | #define PRIo16 "ho" 73 | #define PRIu16 "hu" 74 | #define PRIx16 "hx" 75 | #define PRIX16 "hX" 76 | 77 | #if defined(_MSC_VER) && _MSC_VER <= 1700 78 | #define PRId32 "ld" 79 | #define PRIi32 "li" 80 | #define PRIo32 "lo" 81 | #define PRIu32 "lu" 82 | #define PRIx32 "lx" 83 | #define PRIX32 "lX" 84 | #else // OSX 85 | #define PRId32 "d" 86 | #define PRIi32 "i" 87 | #define PRIo32 "o" 88 | #define PRIu32 "u" 89 | #define PRIx32 "x" 90 | #define PRIX32 "X" 91 | #endif 92 | 93 | #if defined(_MSC_VER) && _MSC_VER <= 1700 94 | // redefine functions from inttypes.h used in cstool 95 | #define strtoull _strtoui64 96 | #endif 97 | 98 | #define PRId64 __PRI_64_LENGTH_MODIFIER__ "d" 99 | #define PRIi64 __PRI_64_LENGTH_MODIFIER__ "i" 100 | #define PRIo64 __PRI_64_LENGTH_MODIFIER__ "o" 101 | #define PRIu64 __PRI_64_LENGTH_MODIFIER__ "u" 102 | #define PRIx64 __PRI_64_LENGTH_MODIFIER__ "x" 103 | #define PRIX64 __PRI_64_LENGTH_MODIFIER__ "X" 104 | 105 | #else 106 | // this system has inttypes.h by default 107 | #include 108 | #endif 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/HyperPlatform/global_object.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. 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 | 5 | /// @file 6 | /// Implements global object functions. 7 | 8 | #include "global_object.h" 9 | 10 | // .CRT section is required to invoke ctors and dtors. This pragma embeds a .CRT 11 | // section into the .rdata section. Or else, a LNK warning would be raised. 12 | #pragma comment(linker, "/merge:.CRT=.rdata") 13 | 14 | // Create two sections that are used by MSVC to place an array of ctors at a 15 | // compile time. It is important to be ordered in alphabetical order. 16 | #pragma section(".CRT$XCA", read) 17 | #pragma section(".CRT$XCZ", read) 18 | 19 | extern "C" { 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // macro utilities 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // constants and macros 28 | // 29 | 30 | /// A pool tag for this module 31 | static const ULONG kGlobalObjectpPoolTag = 'jbOG'; 32 | 33 | //////////////////////////////////////////////////////////////////////////////// 34 | // 35 | // types 36 | // 37 | 38 | using Destructor = void(__cdecl *)(); 39 | 40 | struct DestructorEntry { 41 | Destructor dtor; 42 | SINGLE_LIST_ENTRY list_entry; 43 | }; 44 | 45 | //////////////////////////////////////////////////////////////////////////////// 46 | // 47 | // prototypes 48 | // 49 | 50 | #if defined(ALLOC_PRAGMA) 51 | #pragma alloc_text(INIT, GlobalObjectInitialization) 52 | #pragma alloc_text(INIT, atexit) 53 | #pragma alloc_text(PAGE, GlobalObjectTermination) 54 | #endif 55 | 56 | //////////////////////////////////////////////////////////////////////////////// 57 | // 58 | // variables 59 | // 60 | 61 | // Place markers pointing to the beginning and end of the ctors arrays embedded 62 | // by MSVC. 63 | __declspec(allocate(".CRT$XCA")) static Destructor g_gop_ctors_begin[1] = {}; 64 | __declspec(allocate(".CRT$XCZ")) static Destructor g_gop_ctors_end[1] = {}; 65 | 66 | // Stores pointers to dtors to be called at the exit. 67 | static SINGLE_LIST_ENTRY g_gop_dtors_list_head = {}; 68 | 69 | //////////////////////////////////////////////////////////////////////////////// 70 | // 71 | // implementations 72 | // 73 | 74 | // Calls all constructors and register all destructor 75 | _Use_decl_annotations_ NTSTATUS GlobalObjectInitialization() { 76 | PAGED_CODE(); 77 | 78 | // Call all constructors 79 | for (auto ctor = g_gop_ctors_begin + 1; ctor < g_gop_ctors_end; ++ctor) { 80 | (*ctor)(); 81 | } 82 | return STATUS_SUCCESS; 83 | } 84 | 85 | // Calls all registered destructors 86 | _Use_decl_annotations_ void GlobalObjectTermination() { 87 | PAGED_CODE(); 88 | 89 | auto entry = PopEntryList(&g_gop_dtors_list_head); 90 | while (entry) { 91 | const auto element = CONTAINING_RECORD(entry, DestructorEntry, list_entry); 92 | element->dtor(); 93 | ExFreePoolWithTag(element, kGlobalObjectpPoolTag); 94 | entry = PopEntryList(&g_gop_dtors_list_head); 95 | } 96 | } 97 | 98 | // Registers destructor; this is called through a call to constructor 99 | _IRQL_requires_max_(PASSIVE_LEVEL) int __cdecl atexit(_In_ Destructor dtor) { 100 | PAGED_CODE(); 101 | 102 | const auto element = 103 | reinterpret_cast(ExAllocatePoolWithTag( 104 | PagedPool, sizeof(DestructorEntry), kGlobalObjectpPoolTag)); 105 | if (!element) { 106 | return 1; 107 | } 108 | element->dtor = dtor; 109 | PushEntryList(&g_gop_dtors_list_head, &element->list_entry); 110 | return 0; 111 | } 112 | 113 | } // extern "C" 114 | -------------------------------------------------------------------------------- /kHypervisorBasic/global_object.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Implements global object functions. 8 | 9 | #include "global_object.h" 10 | 11 | // .CRT section is required to invoke ctors and dtors. This pragma embeds a .CRT 12 | // section into the .rdata section. Or else, a LNK warning would be raised. 13 | #pragma comment(linker, "/merge:.CRT=.rdata") 14 | 15 | // Create two sections that are used by MSVC to place an array of ctors at a 16 | // compile time. It is important to be ordered in alphabetical order. 17 | #pragma section(".CRT$XCA", read) 18 | #pragma section(".CRT$XCZ", read) 19 | 20 | extern "C" { 21 | //////////////////////////////////////////////////////////////////////////////// 22 | // 23 | // macro utilities 24 | // 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | // 28 | // constants and macros 29 | // 30 | 31 | /// A pool tag for this module 32 | static const ULONG kGlobalObjectpPoolTag = 'jbOG'; 33 | 34 | //////////////////////////////////////////////////////////////////////////////// 35 | // 36 | // types 37 | // 38 | 39 | using Destructor = void(__cdecl *)(); 40 | 41 | struct DestructorEntry { 42 | Destructor dtor; 43 | SINGLE_LIST_ENTRY list_entry; 44 | }; 45 | 46 | //////////////////////////////////////////////////////////////////////////////// 47 | // 48 | // prototypes 49 | // 50 | 51 | #if defined(ALLOC_PRAGMA) 52 | #pragma alloc_text(INIT, GlobalObjectInitialization) 53 | #pragma alloc_text(INIT, atexit) 54 | #pragma alloc_text(PAGE, GlobalObjectTermination) 55 | #endif 56 | 57 | //////////////////////////////////////////////////////////////////////////////// 58 | // 59 | // variables 60 | // 61 | 62 | // Place markers pointing to the beginning and end of the ctors arrays embedded 63 | // by MSVC. 64 | __declspec(allocate(".CRT$XCA")) static Destructor g_gop_ctors_begin[1] = {}; 65 | __declspec(allocate(".CRT$XCZ")) static Destructor g_gop_ctors_end[1] = {}; 66 | 67 | // Stores pointers to dtors to be called at the exit. 68 | static SINGLE_LIST_ENTRY g_gop_dtors_list_head = {}; 69 | 70 | //////////////////////////////////////////////////////////////////////////////// 71 | // 72 | // implementations 73 | // 74 | 75 | // Calls all constructors and register all destructor 76 | _Use_decl_annotations_ NTSTATUS GlobalObjectInitialization() { 77 | PAGED_CODE(); 78 | 79 | // Call all constructors 80 | for (auto ctor = g_gop_ctors_begin + 1; ctor < g_gop_ctors_end; ++ctor) { 81 | (*ctor)(); 82 | } 83 | return STATUS_SUCCESS; 84 | } 85 | 86 | // Calls all registered destructors 87 | _Use_decl_annotations_ void GlobalObjectTermination() { 88 | PAGED_CODE(); 89 | 90 | auto entry = PopEntryList(&g_gop_dtors_list_head); 91 | while (entry) { 92 | const auto element = CONTAINING_RECORD(entry, DestructorEntry, list_entry); 93 | element->dtor(); 94 | ExFreePoolWithTag(element, kGlobalObjectpPoolTag); 95 | entry = PopEntryList(&g_gop_dtors_list_head); 96 | } 97 | } 98 | 99 | // Registers destructor; this is called through a call to constructor 100 | _IRQL_requires_max_(PASSIVE_LEVEL) int __cdecl atexit(_In_ Destructor dtor) { 101 | PAGED_CODE(); 102 | 103 | const auto element = 104 | reinterpret_cast(ExAllocatePoolWithTag( 105 | PagedPool, sizeof(DestructorEntry), kGlobalObjectpPoolTag)); 106 | if (!element) { 107 | return 1; 108 | } 109 | element->dtor = dtor; 110 | PushEntryList(&g_gop_dtors_list_head, &element->list_entry); 111 | return 0; 112 | } 113 | 114 | } // extern "C" 115 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/global_object.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Implements global object functions. 8 | 9 | #include "global_object.h" 10 | 11 | // .CRT section is required to invoke ctors and dtors. This pragma embeds a .CRT 12 | // section into the .rdata section. Or else, a LNK warning would be raised. 13 | #pragma comment(linker, "/merge:.CRT=.rdata") 14 | 15 | // Create two sections that are used by MSVC to place an array of ctors at a 16 | // compile time. It is important to be ordered in alphabetical order. 17 | #pragma section(".CRT$XCA", read) 18 | #pragma section(".CRT$XCZ", read) 19 | 20 | extern "C" { 21 | //////////////////////////////////////////////////////////////////////////////// 22 | // 23 | // macro utilities 24 | // 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | // 28 | // constants and macros 29 | // 30 | 31 | /// A pool tag for this module 32 | static const ULONG kGlobalObjectpPoolTag = 'jbOG'; 33 | 34 | //////////////////////////////////////////////////////////////////////////////// 35 | // 36 | // types 37 | // 38 | 39 | using Destructor = void(__cdecl *)(); 40 | 41 | struct DestructorEntry { 42 | Destructor dtor; 43 | SINGLE_LIST_ENTRY list_entry; 44 | }; 45 | 46 | //////////////////////////////////////////////////////////////////////////////// 47 | // 48 | // prototypes 49 | // 50 | 51 | #if defined(ALLOC_PRAGMA) 52 | #pragma alloc_text(INIT, GlobalObjectInitialization) 53 | #pragma alloc_text(INIT, atexit) 54 | #pragma alloc_text(PAGE, GlobalObjectTermination) 55 | #endif 56 | 57 | //////////////////////////////////////////////////////////////////////////////// 58 | // 59 | // variables 60 | // 61 | 62 | // Place markers pointing to the beginning and end of the ctors arrays embedded 63 | // by MSVC. 64 | __declspec(allocate(".CRT$XCA")) static Destructor g_gop_ctors_begin[1] = {}; 65 | __declspec(allocate(".CRT$XCZ")) static Destructor g_gop_ctors_end[1] = {}; 66 | 67 | // Stores pointers to dtors to be called at the exit. 68 | static SINGLE_LIST_ENTRY g_gop_dtors_list_head = {}; 69 | 70 | //////////////////////////////////////////////////////////////////////////////// 71 | // 72 | // implementations 73 | // 74 | 75 | // Calls all constructors and register all destructor 76 | _Use_decl_annotations_ NTSTATUS GlobalObjectInitialization() { 77 | PAGED_CODE(); 78 | 79 | // Call all constructors 80 | for (auto ctor = g_gop_ctors_begin + 1; ctor < g_gop_ctors_end; ++ctor) { 81 | (*ctor)(); 82 | } 83 | return STATUS_SUCCESS; 84 | } 85 | 86 | // Calls all registered destructors 87 | _Use_decl_annotations_ void GlobalObjectTermination() { 88 | PAGED_CODE(); 89 | 90 | auto entry = PopEntryList(&g_gop_dtors_list_head); 91 | while (entry) { 92 | const auto element = CONTAINING_RECORD(entry, DestructorEntry, list_entry); 93 | element->dtor(); 94 | ExFreePoolWithTag(element, kGlobalObjectpPoolTag); 95 | entry = PopEntryList(&g_gop_dtors_list_head); 96 | } 97 | } 98 | 99 | // Registers destructor; this is called through a call to constructor 100 | _IRQL_requires_max_(PASSIVE_LEVEL) int __cdecl atexit(_In_ Destructor dtor) { 101 | PAGED_CODE(); 102 | 103 | const auto element = 104 | reinterpret_cast(ExAllocatePoolWithTag( 105 | PagedPool, sizeof(DestructorEntry), kGlobalObjectpPoolTag)); 106 | if (!element) { 107 | return 1; 108 | } 109 | element->dtor = dtor; 110 | PushEntryList(&g_gop_dtors_list_head, &element->list_entry); 111 | return 0; 112 | } 113 | 114 | } // extern "C" 115 | -------------------------------------------------------------------------------- /kHypervisorBasic/vmm.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Declares interfaces to VMM functions. 8 | 9 | #ifndef HYPERPLATFORM_VMM_H_ 10 | #define HYPERPLATFORM_VMM_H_ 11 | 12 | #include 13 | 14 | //////////////////////////////////////////////////////////////////////////////// 15 | // 16 | // macro utilities 17 | // 18 | #define ENABLE_NESTED_EPT 1 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | typedef enum { 25 | ProtectedMode = 0, 26 | VmxMode = 1, 27 | Virtual8086 = 2, 28 | RealMode = 3, 29 | SmmMode = 4, 30 | }CPU_MODE; 31 | 32 | typedef enum { 33 | RootMode = 0, 34 | GuestMode, 35 | }VMX_MODE; 36 | 37 | //////////////////////////////////////////////////////////////////////////////// 38 | // 39 | // types 40 | // 41 | 42 | /// Represents VMM related data shared across all processors 43 | struct SharedProcessorData { 44 | volatile long reference_count; //!< Number of processors sharing this data 45 | void* msr_bitmap; //!< Bitmap to activate MSR I/O VM-exit 46 | void* io_bitmap_a; //!< Bitmap to activate IO VM-exit (~ 0x7FFF) 47 | void* io_bitmap_b; //!< Bitmap to activate IO VM-exit (~ 0xffff) 48 | }; 49 | 50 | typedef struct _VCPU_VMX 51 | { 52 | ULONG64 vmxon_region; 53 | ULONG64 vmcs02_pa; ///VMCS02 , actual VMCS L1 will runs on 54 | ULONG64 vmcs12_pa; ///VMCS12 , for L1's VMREAD and VMWRITE, as a shadow VMCS 55 | ULONG64 vmcs01_pa; ///VMCS01 , Initial VMCS 56 | ULONG InitialCpuNumber; ///VCPU number 57 | BOOLEAN blockINITsignal; ///NOT USED 58 | BOOLEAN blockAndDisableA20M; ///NOT USED 59 | VMX_MODE inRoot; ///is it in root mode 60 | USHORT kVirtualProcessorId; ///NOT USED 61 | ULONG_PTR guest_irql; 62 | ULONG_PTR guest_cr8; 63 | }VCPUVMX, *PVCPUVMX; 64 | 65 | /// Represents VMM related data associated with each processor 66 | struct ProcessorData { 67 | SharedProcessorData* shared_data; //!< Shared data 68 | void* vmm_stack_limit; //!< A head of VA for VMM stack 69 | struct VmControlStructure* vmxon_region; //!< VA of a VMXON region 70 | struct VmControlStructure* vmcs_region; //!< VA of a VMCS region 71 | struct EptData* ept_data; //!< A pointer to EPT related data 72 | void* xsave_area; //!< VA to store state components 73 | ULONG64 xsave_inst_mask; //!< A mask to save state components 74 | UCHAR fxsave_area[512 + 16]; //!< For fxsave (+16 for alignment) 75 | LARGE_INTEGER Ia32FeatureMsr; //!< For Msr Read / Write 76 | LARGE_INTEGER VmxBasicMsr; //!< For Msr Read / Write 77 | LARGE_INTEGER VmxEptMsr; //!< For Msr Read / Write 78 | LARGE_INTEGER HostKernelGsBase; ///guest_gs_kernel_base 79 | LARGE_INTEGER GuestKernelGsBase; ///guest_gs_kernel_base 80 | VCPUVMX* vcpu_vmx; //!< For nested vmx context 81 | CPU_MODE CpuMode; //!< For CPU Mode 82 | 83 | #ifdef ENABLE_NESTED_EPT 84 | EptData* EptDat02; 85 | EptData* EptDat12; 86 | ULONG_PTR LastEptFaultAddr; 87 | #endif 88 | 89 | }; 90 | 91 | 92 | 93 | //////////////////////////////////////////////////////////////////////////////// 94 | // 95 | // prototypes 96 | // 97 | 98 | //////////////////////////////////////////////////////////////////////////////// 99 | // 100 | // variables 101 | // 102 | 103 | //////////////////////////////////////////////////////////////////////////////// 104 | // 105 | // implementations 106 | // 107 | 108 | #endif // HYPERPLATFORM_VMM_H_ 109 | -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2004-2020 Sandboxie Holdings, LLC 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | //--------------------------------------------------------------------------- 19 | // Double-linked List based on a Cell Pool 20 | //--------------------------------------------------------------------------- 21 | 22 | #ifndef _MY_LIST_H 23 | #define _MY_LIST_H 24 | 25 | #ifdef LIST_WITH_MEMORY_MANAGEMENT 26 | #include "pool.h" 27 | #endif 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | //--------------------------------------------------------------------------- 34 | // Structures 35 | //--------------------------------------------------------------------------- 36 | 37 | typedef struct LIST_ELEM { 38 | struct LIST_ELEM *next; 39 | struct LIST_ELEM *prev; 40 | } LIST_ELEM; 41 | 42 | typedef struct { 43 | LIST_ELEM *head; 44 | LIST_ELEM *tail; 45 | int count; 46 | #ifdef LIST_WITH_MEMORY_MANAGEMENT 47 | POOL *pool; 48 | int elem_len; 49 | #endif 50 | } LIST; 51 | 52 | //--------------------------------------------------------------------------- 53 | // Macros 54 | //--------------------------------------------------------------------------- 55 | 56 | #ifndef LIST_WITH_MEMORY_MANAGEMENT 57 | #include 58 | /* Initializes list structure */ 59 | #define List_Init(list) (memset((list),0,sizeof(LIST))) 60 | #endif 61 | 62 | /* Return head elem of list LIST */ 63 | #define List_Head(list) ((void *)(((LIST *)(list))->head)) 64 | 65 | /* Return tail elem of list LIST */ 66 | #define List_Tail(list) ((void *)(((LIST *)(list))->tail)) 67 | 68 | /* Return count of elems in list LIST */ 69 | #define List_Count(list) (((LIST *)(list))->count) 70 | 71 | /* Return elem next to elem ELEM */ 72 | #define List_Next(elem) ((void *)(((LIST_ELEM *)(elem))->next)) 73 | 74 | /* Return elem previous to elem ELEM */ 75 | #define List_Prev(elem) ((void *)(((LIST_ELEM *)(elem))->prev)) 76 | 77 | // Deletes the pool allocated to a list 78 | 79 | //--------------------------------------------------------------------------- 80 | // Functions 81 | //--------------------------------------------------------------------------- 82 | 83 | #ifdef LIST_WITH_MEMORY_MANAGEMENT 84 | /* Initializes list structure */ 85 | void List_Init(LIST *list); 86 | #endif 87 | 88 | /* Insert new elem before that pointed to by ELEM*/ 89 | void List_Insert_Before(LIST *list, void *oldelem, void *newelem); 90 | 91 | /* Insert new elem after that pointed to by ELEM*/ 92 | void List_Insert_After(LIST *list, void *elem, void *newelem); 93 | 94 | /* Delete elem pointed to by ELEM */ 95 | void List_Remove(LIST *list, void *elem); 96 | 97 | #ifdef LIST_WITH_MEMORY_MANAGEMENT 98 | /* These also manage memory for the elements */ 99 | void *List_Insert_New_Before(LIST *list, void *elem); 100 | void *List_Insert_After(LIST *list, void *elem); 101 | void List_Delete(LIST *list, void *elem); 102 | #endif 103 | 104 | //--------------------------------------------------------------------------- 105 | 106 | #ifdef __cplusplus 107 | } 108 | #endif 109 | 110 | #endif /* _MY_LIST_H */ 111 | -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/Filehook.cpp: -------------------------------------------------------------------------------- 1 | #include "hook.h" 2 | #include "Common.h" 3 | #include "Filehook.h" 4 | 5 | // ======================================================================================= 6 | typedef NTSTATUS(NTAPI* P_NtClose)(_In_ _Post_ptr_invalid_ HANDLE Handle); 7 | typedef NTSTATUS(NTAPI* P_ZwCreateFile)( 8 | _Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, 9 | _In_ POBJECT_ATTRIBUTES ObjectAttributes, 10 | _Out_ PIO_STATUS_BLOCK IoStatusBlock, 11 | _In_opt_ PLARGE_INTEGER AllocationSize, _In_ ULONG FileAttributes, 12 | _In_ ULONG ShareAccess, _In_ ULONG CreateDisposition, 13 | _In_ ULONG CreateOptions, _In_reads_bytes_opt_(EaLength) PVOID EaBuffer, 14 | _In_ ULONG EaLength); 15 | 16 | // ======================================================================================= 17 | P_NtClose __sys_NtClose = NULL; 18 | P_ZwCreateFile __sys_NtCreateFile = NULL; 19 | 20 | // ======================================================================================= 21 | // Hook_Function 22 | // ======================================================================================= 23 | NTSTATUS hkNtClose(HANDLE handle); 24 | NTSTATUS NTAPI hkNtCreateFile(_Out_ PHANDLE FileHandle, 25 | _In_ ACCESS_MASK DesiredAccess, 26 | _In_ POBJECT_ATTRIBUTES ObjectAttributes, 27 | _Out_ PIO_STATUS_BLOCK IoStatusBlock, 28 | _In_opt_ PLARGE_INTEGER AllocationSize, 29 | _In_ ULONG FileAttributes, _In_ ULONG ShareAccess, 30 | _In_ ULONG CreateDisposition, 31 | _In_ ULONG CreateOptions, 32 | _In_reads_bytes_opt_(EaLength) PVOID EaBuffer, 33 | _In_ ULONG EaLength); 34 | 35 | // Enable Msr hook 36 | NTSTATUS FileMsrHook( 37 | const PSYSTEM_SERVICE_DESCRIPTOR_TABLE pssdt 38 | ) 39 | { 40 | ULONG size = 0; 41 | PVOID pBase = UtilKernelBase(&size); 42 | 43 | if (pssdt && pBase) { 44 | const auto ZwCloseindex = SSDTIndex(&ZwClose); 45 | const auto ZwCreateFileindex = SSDTIndex(&ZwCreateFile); 46 | if (ZwCloseindex > pssdt->NumberOfServices) return NULL; 47 | if (ZwCreateFileindex > pssdt->NumberOfServices) return NULL; 48 | 49 | __sys_NtClose = 50 | (P_NtClose)((PUCHAR)pssdt->ServiceTableBase + 51 | (((PLONG)pssdt->ServiceTableBase)[ZwCloseindex] >> 4)); 52 | __sys_NtCreateFile = (P_ZwCreateFile)( 53 | (PUCHAR)pssdt->ServiceTableBase + 54 | (((PLONG)pssdt->ServiceTableBase)[ZwCreateFileindex] >> 4)); 55 | 56 | AddMsrHook(ZwCloseindex, (PVOID)hkNtClose, 1); 57 | AddMsrHook(ZwCreateFileindex, (PVOID)hkNtCreateFile, 11); 58 | } 59 | return STATUS_SUCCESS; 60 | } 61 | 62 | NTSTATUS hkNtCreateFile(_Out_ PHANDLE FileHandle, 63 | _In_ ACCESS_MASK DesiredAccess, 64 | _In_ POBJECT_ATTRIBUTES ObjectAttributes, 65 | _Out_ PIO_STATUS_BLOCK IoStatusBlock, 66 | _In_opt_ PLARGE_INTEGER AllocationSize, 67 | _In_ ULONG FileAttributes, _In_ ULONG ShareAccess, 68 | _In_ ULONG CreateDisposition, _In_ ULONG CreateOptions, 69 | _In_reads_bytes_opt_(EaLength) PVOID EaBuffer, 70 | _In_ ULONG EaLength) 71 | { 72 | DPRINT("[+]hkNtCreateFile - Processid = %d\r\n", PsGetCurrentProcessId()); 73 | return __sys_NtCreateFile(FileHandle, DesiredAccess, ObjectAttributes, 74 | IoStatusBlock, AllocationSize, FileAttributes, 75 | ShareAccess, CreateDisposition, CreateOptions, 76 | EaBuffer, EaLength); 77 | } 78 | 79 | NTSTATUS hkNtClose( 80 | HANDLE handle 81 | ) 82 | { 83 | // DPRINT("[+]NtClose\r\n"); 84 | return __sys_NtClose(handle); 85 | } -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/vmm.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Declares interfaces to VMM functions. 8 | 9 | #ifndef HYPERPLATFORM_VMM_H_ 10 | #define HYPERPLATFORM_VMM_H_ 11 | 12 | #include 13 | 14 | //////////////////////////////////////////////////////////////////////////////// 15 | // 16 | // macro utilities 17 | // 18 | #define ENABLE_NESTED_EPT 1 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | typedef enum { 25 | ProtectedMode = 0, 26 | VmxMode = 1, 27 | Virtual8086 = 2, 28 | RealMode = 3, 29 | SmmMode = 4, 30 | }CPU_MODE; 31 | 32 | typedef enum { 33 | RootMode = 0, 34 | GuestMode, 35 | }VMX_MODE; 36 | 37 | //////////////////////////////////////////////////////////////////////////////// 38 | // 39 | // types 40 | // 41 | 42 | /// Represents VMM related data shared across all processors 43 | struct SharedProcessorData { 44 | volatile long reference_count; //!< Number of processors sharing this data 45 | void* msr_bitmap; //!< Bitmap to activate MSR I/O VM-exit 46 | void* io_bitmap_a; //!< Bitmap to activate IO VM-exit (~ 0x7FFF) 47 | void* io_bitmap_b; //!< Bitmap to activate IO VM-exit (~ 0xffff) 48 | struct SharedShadowHookData* shared_sh_data; 49 | }; 50 | 51 | typedef struct _VCPU_VMX 52 | { 53 | ULONG64 vmxon_region; 54 | ULONG64 vmcs02_pa; ///VMCS02 , actual VMCS L1 will runs on 55 | ULONG64 vmcs12_pa; ///VMCS12 , for L1's VMREAD and VMWRITE, as a shadow VMCS 56 | ULONG64 vmcs01_pa; ///VMCS01 , Initial VMCS 57 | ULONG InitialCpuNumber; ///VCPU number 58 | BOOLEAN blockINITsignal; ///NOT USED 59 | BOOLEAN blockAndDisableA20M; ///NOT USED 60 | VMX_MODE inRoot; ///is it in root mode 61 | USHORT kVirtualProcessorId; ///NOT USED 62 | ULONG_PTR guest_irql; 63 | ULONG_PTR guest_cr8; 64 | }VCPUVMX, *PVCPUVMX; 65 | 66 | /// Represents VMM related data associated with each processor 67 | struct ProcessorData { 68 | SharedProcessorData* shared_data; //!< Shared data 69 | void* vmm_stack_limit; //!< A head of VA for VMM stack 70 | struct VmControlStructure* vmxon_region; //!< VA of a VMXON region 71 | struct VmControlStructure* vmcs_region; //!< VA of a VMCS region 72 | struct EptData* ept_data; //!< A pointer to EPT related data 73 | void* xsave_area; //!< VA to store state components 74 | ULONG64 xsave_inst_mask; //!< A mask to save state components 75 | UCHAR fxsave_area[512 + 16]; //!< For fxsave (+16 for alignment) 76 | LARGE_INTEGER Ia32FeatureMsr; //!< For Msr Read / Write 77 | LARGE_INTEGER VmxBasicMsr; //!< For Msr Read / Write 78 | LARGE_INTEGER VmxEptMsr; //!< For Msr Read / Write 79 | LARGE_INTEGER HostKernelGsBase; ///guest_gs_kernel_base 80 | LARGE_INTEGER GuestKernelGsBase; ///guest_gs_kernel_base 81 | VCPUVMX* vcpu_vmx; //!< For nested vmx context 82 | CPU_MODE CpuMode; //!< For CPU Mode 83 | // old of msr_lstar 84 | ULONG64 originallstar; 85 | struct ShadowHookData* sh_data; //!< Per-processor shadow hook data 86 | #ifdef ENABLE_NESTED_EPT 87 | EptData* EptDat02; 88 | EptData* EptDat12; 89 | ULONG_PTR LastEptFaultAddr; 90 | #endif 91 | 92 | }; 93 | 94 | 95 | 96 | //////////////////////////////////////////////////////////////////////////////// 97 | // 98 | // prototypes 99 | // 100 | 101 | //////////////////////////////////////////////////////////////////////////////// 102 | // 103 | // variables 104 | // 105 | 106 | //////////////////////////////////////////////////////////////////////////////// 107 | // 108 | // implementations 109 | // 110 | 111 | #endif // HYPERPLATFORM_VMM_H_ 112 | -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/kHypervisor.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | Source Files 30 | 31 | 32 | Source Files 33 | 34 | 35 | Source Files 36 | 37 | 38 | Source Files 39 | 40 | 41 | Source Files 42 | 43 | 44 | Source Files 45 | 46 | 47 | Source Files 48 | 49 | 50 | 51 | 52 | Header Files 53 | 54 | 55 | Header Files 56 | 57 | 58 | Header Files 59 | 60 | 61 | Header Files 62 | 63 | 64 | Header Files 65 | 66 | 67 | Header Files 68 | 69 | 70 | Header Files 71 | 72 | 73 | Header Files 74 | 75 | 76 | Header Files 77 | 78 | 79 | Header Files 80 | 81 | 82 | Header Files 83 | 84 | 85 | Header Files 86 | 87 | 88 | Header Files 89 | 90 | 91 | 92 | 93 | Source Files 94 | 95 | 96 | Source Files 97 | 98 | 99 | 100 | 101 | Driver Files 102 | 103 | 104 | -------------------------------------------------------------------------------- /kHypervisorBasic/include/capstone/platform.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Axel Souchet & Nguyen Anh Quynh, 2014 */ 3 | 4 | #ifndef CAPSTONE_PLATFORM_H 5 | #define CAPSTONE_PLATFORM_H 6 | 7 | 8 | // handle C99 issue (for pre-2013 VisualStudio) 9 | #if !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)) 10 | // MSVC 11 | 12 | // stdbool.h 13 | #if (_MSC_VER < 1800) || defined(_KERNEL_MODE) 14 | // this system does not have stdbool.h 15 | #ifndef __cplusplus 16 | typedef unsigned char bool; 17 | #define false 0 18 | #define true 1 19 | #endif // __cplusplus 20 | 21 | #else 22 | // VisualStudio 2013+ -> C99 is supported 23 | #include 24 | #endif // (_MSC_VER < 1800) || defined(_KERNEL_MODE) 25 | 26 | #else 27 | // not MSVC -> C99 is supported 28 | #include 29 | #endif // !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)) 30 | 31 | 32 | // handle inttypes.h / stdint.h compatibility 33 | #if defined(_WIN32_WCE) && (_WIN32_WCE < 0x800) 34 | #include "windowsce/stdint.h" 35 | #endif // defined(_WIN32_WCE) && (_WIN32_WCE < 0x800) 36 | 37 | #if defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE))) 38 | // this system does not have inttypes.h 39 | 40 | #if defined(_MSC_VER) && (_MSC_VER <= 1600 || defined(_KERNEL_MODE)) 41 | // this system does not have stdint.h 42 | typedef signed char int8_t; 43 | typedef signed short int16_t; 44 | typedef signed int int32_t; 45 | typedef unsigned char uint8_t; 46 | typedef unsigned short uint16_t; 47 | typedef unsigned int uint32_t; 48 | typedef signed long long int64_t; 49 | typedef unsigned long long uint64_t; 50 | #endif // defined(_MSC_VER) && (_MSC_VER <= 1600 || defined(_KERNEL_MODE)) 51 | 52 | #if defined(_MSC_VER) && (_MSC_VER < 1600 || defined(_KERNEL_MODE)) 53 | #define INT8_MIN (-127i8 - 1) 54 | #define INT16_MIN (-32767i16 - 1) 55 | #define INT32_MIN (-2147483647i32 - 1) 56 | #define INT64_MIN (-9223372036854775807i64 - 1) 57 | #define INT8_MAX 127i8 58 | #define INT16_MAX 32767i16 59 | #define INT32_MAX 2147483647i32 60 | #define INT64_MAX 9223372036854775807i64 61 | #define UINT8_MAX 0xffui8 62 | #define UINT16_MAX 0xffffui16 63 | #define UINT32_MAX 0xffffffffui32 64 | #define UINT64_MAX 0xffffffffffffffffui64 65 | #endif // defined(_MSC_VER) && (_MSC_VER < 1600 || defined(_KERNEL_MODE)) 66 | 67 | #ifdef CAPSTONE_HAS_OSXKERNEL 68 | // this system has stdint.h 69 | #include 70 | #endif 71 | 72 | #define __PRI_8_LENGTH_MODIFIER__ "hh" 73 | #define __PRI_64_LENGTH_MODIFIER__ "ll" 74 | 75 | #define PRId8 __PRI_8_LENGTH_MODIFIER__ "d" 76 | #define PRIi8 __PRI_8_LENGTH_MODIFIER__ "i" 77 | #define PRIo8 __PRI_8_LENGTH_MODIFIER__ "o" 78 | #define PRIu8 __PRI_8_LENGTH_MODIFIER__ "u" 79 | #define PRIx8 __PRI_8_LENGTH_MODIFIER__ "x" 80 | #define PRIX8 __PRI_8_LENGTH_MODIFIER__ "X" 81 | 82 | #define PRId16 "hd" 83 | #define PRIi16 "hi" 84 | #define PRIo16 "ho" 85 | #define PRIu16 "hu" 86 | #define PRIx16 "hx" 87 | #define PRIX16 "hX" 88 | 89 | #if defined(_MSC_VER) && _MSC_VER <= 1700 90 | #define PRId32 "ld" 91 | #define PRIi32 "li" 92 | #define PRIo32 "lo" 93 | #define PRIu32 "lu" 94 | #define PRIx32 "lx" 95 | #define PRIX32 "lX" 96 | #else // OSX 97 | #define PRId32 "d" 98 | #define PRIi32 "i" 99 | #define PRIo32 "o" 100 | #define PRIu32 "u" 101 | #define PRIx32 "x" 102 | #define PRIX32 "X" 103 | #endif // defined(_MSC_VER) && _MSC_VER <= 1700 104 | 105 | #if defined(_MSC_VER) && _MSC_VER <= 1700 106 | // redefine functions from inttypes.h used in cstool 107 | #define strtoull _strtoui64 108 | #endif 109 | 110 | #define PRId64 __PRI_64_LENGTH_MODIFIER__ "d" 111 | #define PRIi64 __PRI_64_LENGTH_MODIFIER__ "i" 112 | #define PRIo64 __PRI_64_LENGTH_MODIFIER__ "o" 113 | #define PRIu64 __PRI_64_LENGTH_MODIFIER__ "u" 114 | #define PRIx64 __PRI_64_LENGTH_MODIFIER__ "x" 115 | #define PRIX64 __PRI_64_LENGTH_MODIFIER__ "X" 116 | 117 | #else 118 | // this system has inttypes.h by default 119 | #include 120 | #endif // defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE))) 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/HyperPlatform.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | Source Files 56 | 57 | 58 | Source Files 59 | 60 | 61 | Source Files 62 | 63 | 64 | 65 | 66 | Header Files 67 | 68 | 69 | Header Files 70 | 71 | 72 | Header Files 73 | 74 | 75 | Header Files 76 | 77 | 78 | Header Files 79 | 80 | 81 | Header Files 82 | 83 | 84 | Header Files 85 | 86 | 87 | Header Files 88 | 89 | 90 | Header Files 91 | 92 | 93 | Header Files 94 | 95 | 96 | Header Files 97 | 98 | 99 | Header Files 100 | 101 | 102 | Header Files 103 | 104 | 105 | Header Files 106 | 107 | 108 | Header Files 109 | 110 | 111 | Header Files 112 | 113 | 114 | Header Files 115 | 116 | 117 | 118 | 119 | Source Files 120 | 121 | 122 | Source Files 123 | 124 | 125 | -------------------------------------------------------------------------------- /kHypervisorBasic/kernel_stl.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Provides code to use STL in a driver project 8 | 9 | #ifndef HYPERPLATFORM_KERNEL_STL_H_ 10 | #define HYPERPLATFORM_KERNEL_STL_H_ 11 | 12 | #include 13 | 14 | //////////////////////////////////////////////////////////////////////////////// 15 | // 16 | // macro utilities 17 | // 18 | 19 | //////////////////////////////////////////////////////////////////////////////// 20 | // 21 | // constants and macros 22 | // 23 | 24 | /// Disabling exception in headers included after this file 25 | #ifdef _HAS_EXCEPTIONS 26 | #undef _HAS_EXCEPTIONS 27 | #endif 28 | #define _HAS_EXCEPTIONS 0 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // types 33 | // 34 | 35 | //////////////////////////////////////////////////////////////////////////////// 36 | // 37 | // prototypes 38 | // 39 | 40 | //////////////////////////////////////////////////////////////////////////////// 41 | // 42 | // variables 43 | // 44 | 45 | //////////////////////////////////////////////////////////////////////////////// 46 | // 47 | // implementations 48 | // 49 | 50 | /// An alternative implmentation of a C++ exception handler. Issues a bug check. 51 | /// @param bug_check_code A bug check code 52 | DECLSPEC_NORETURN void KernelStlRaiseException(_In_ ULONG bug_check_code); 53 | 54 | // Followings are definitions of functions needed to link successfully. 55 | 56 | DECLSPEC_NORETURN void __cdecl _invalid_parameter_noinfo_noreturn(); 57 | 58 | namespace std { 59 | 60 | DECLSPEC_NORETURN void __cdecl _Xbad_alloc(); 61 | DECLSPEC_NORETURN void __cdecl _Xinvalid_argument(_In_z_ const char *); 62 | DECLSPEC_NORETURN void __cdecl _Xlength_error(_In_z_ const char *); 63 | DECLSPEC_NORETURN void __cdecl _Xout_of_range(_In_z_ const char *); 64 | DECLSPEC_NORETURN void __cdecl _Xoverflow_error(_In_z_ const char *); 65 | DECLSPEC_NORETURN void __cdecl _Xruntime_error(_In_z_ const char *); 66 | 67 | } // namespace std 68 | 69 | /// An alternative implmentation of the new operator 70 | /// @param size A size to allocate in bytes 71 | /// @return An allocated pointer. The operator delete should be used to free it 72 | void *__cdecl operator new(_In_ size_t size); 73 | 74 | /// An alternative implmentation of the new operator 75 | /// @param p A pointer to delete 76 | void __cdecl operator delete(_In_ void *p); 77 | 78 | /// An alternative implmentation of the new operator 79 | /// @param p A pointer to delete 80 | /// @param size Ignored 81 | void __cdecl operator delete(_In_ void *p, _In_ size_t size); 82 | 83 | /// An alternative implmentation of __stdio_common_vsprintf_s 84 | /// @param _Options Ignored 85 | /// @param _Buffer Storage location for output 86 | /// @param _BufferCount Maximum number of characters to write 87 | /// @param _Format Format specification 88 | /// @param _Locale Ignored 89 | /// @param _ArgList Pointer to list of arguments 90 | /// @return The number of characters written, not including the terminating null 91 | /// character, or a negative value if an output error occurs 92 | _Success_(return >= 0) EXTERN_C inline int __cdecl __stdio_common_vsprintf_s( 93 | _In_ unsigned __int64 _Options, _Out_writes_z_(_BufferCount) char *_Buffer, 94 | _In_ size_t _BufferCount, 95 | _In_z_ _Printf_format_string_params_(2) char const *_Format, 96 | _In_opt_ _locale_t _Locale, va_list _ArgList); 97 | 98 | /// An alternative implmentation of __stdio_common_vswprintf_s 99 | /// @param _Options Ignored 100 | /// @param _Buffer Storage location for output 101 | /// @param _BufferCount Maximum number of characters to write 102 | /// @param _Format Format specification 103 | /// @param _Locale Ignored 104 | /// @param _ArgList Pointer to list of arguments 105 | /// @return The number of characters written, not including the terminating null 106 | /// character, or a negative value if an output error occurs 107 | _Success_(return >= 0) _Check_return_opt_ EXTERN_C 108 | inline int __cdecl __stdio_common_vswprintf_s( 109 | _In_ unsigned __int64 _Options, 110 | _Out_writes_z_(_BufferCount) wchar_t *_Buffer, _In_ size_t _BufferCount, 111 | _In_z_ _Printf_format_string_params_(2) wchar_t const *_Format, 112 | _In_opt_ _locale_t _Locale, va_list _ArgList); 113 | 114 | #endif // HYPERPLATFORM_KERNEL_STL_H_ 115 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/kernel_stl.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Provides code to use STL in a driver project 8 | 9 | #ifndef HYPERPLATFORM_KERNEL_STL_H_ 10 | #define HYPERPLATFORM_KERNEL_STL_H_ 11 | 12 | #include 13 | 14 | //////////////////////////////////////////////////////////////////////////////// 15 | // 16 | // macro utilities 17 | // 18 | 19 | //////////////////////////////////////////////////////////////////////////////// 20 | // 21 | // constants and macros 22 | // 23 | 24 | /// Disabling exception in headers included after this file 25 | #ifdef _HAS_EXCEPTIONS 26 | #undef _HAS_EXCEPTIONS 27 | #endif 28 | #define _HAS_EXCEPTIONS 0 29 | 30 | //////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // types 33 | // 34 | 35 | //////////////////////////////////////////////////////////////////////////////// 36 | // 37 | // prototypes 38 | // 39 | 40 | //////////////////////////////////////////////////////////////////////////////// 41 | // 42 | // variables 43 | // 44 | 45 | //////////////////////////////////////////////////////////////////////////////// 46 | // 47 | // implementations 48 | // 49 | 50 | /// An alternative implmentation of a C++ exception handler. Issues a bug check. 51 | /// @param bug_check_code A bug check code 52 | DECLSPEC_NORETURN void KernelStlRaiseException(_In_ ULONG bug_check_code); 53 | 54 | // Followings are definitions of functions needed to link successfully. 55 | 56 | DECLSPEC_NORETURN void __cdecl _invalid_parameter_noinfo_noreturn(); 57 | 58 | namespace std { 59 | 60 | DECLSPEC_NORETURN void __cdecl _Xbad_alloc(); 61 | DECLSPEC_NORETURN void __cdecl _Xinvalid_argument(_In_z_ const char *); 62 | DECLSPEC_NORETURN void __cdecl _Xlength_error(_In_z_ const char *); 63 | DECLSPEC_NORETURN void __cdecl _Xout_of_range(_In_z_ const char *); 64 | DECLSPEC_NORETURN void __cdecl _Xoverflow_error(_In_z_ const char *); 65 | DECLSPEC_NORETURN void __cdecl _Xruntime_error(_In_z_ const char *); 66 | 67 | } // namespace std 68 | 69 | /// An alternative implmentation of the new operator 70 | /// @param size A size to allocate in bytes 71 | /// @return An allocated pointer. The operator delete should be used to free it 72 | void *__cdecl operator new(_In_ size_t size); 73 | 74 | /// An alternative implmentation of the new operator 75 | /// @param p A pointer to delete 76 | void __cdecl operator delete(_In_ void *p); 77 | 78 | /// An alternative implmentation of the new operator 79 | /// @param p A pointer to delete 80 | /// @param size Ignored 81 | void __cdecl operator delete(_In_ void *p, _In_ size_t size); 82 | 83 | /// An alternative implmentation of __stdio_common_vsprintf_s 84 | /// @param _Options Ignored 85 | /// @param _Buffer Storage location for output 86 | /// @param _BufferCount Maximum number of characters to write 87 | /// @param _Format Format specification 88 | /// @param _Locale Ignored 89 | /// @param _ArgList Pointer to list of arguments 90 | /// @return The number of characters written, not including the terminating null 91 | /// character, or a negative value if an output error occurs 92 | _Success_(return >= 0) EXTERN_C inline int __cdecl __stdio_common_vsprintf_s( 93 | _In_ unsigned __int64 _Options, _Out_writes_z_(_BufferCount) char *_Buffer, 94 | _In_ size_t _BufferCount, 95 | _In_z_ _Printf_format_string_params_(2) char const *_Format, 96 | _In_opt_ _locale_t _Locale, va_list _ArgList); 97 | 98 | /// An alternative implmentation of __stdio_common_vswprintf_s 99 | /// @param _Options Ignored 100 | /// @param _Buffer Storage location for output 101 | /// @param _BufferCount Maximum number of characters to write 102 | /// @param _Format Format specification 103 | /// @param _Locale Ignored 104 | /// @param _ArgList Pointer to list of arguments 105 | /// @return The number of characters written, not including the terminating null 106 | /// character, or a negative value if an output error occurs 107 | _Success_(return >= 0) _Check_return_opt_ EXTERN_C 108 | inline int __cdecl __stdio_common_vswprintf_s( 109 | _In_ unsigned __int64 _Options, 110 | _Out_writes_z_(_BufferCount) wchar_t *_Buffer, _In_ size_t _BufferCount, 111 | _In_z_ _Printf_format_string_params_(2) wchar_t const *_Format, 112 | _In_opt_ _locale_t _Locale, va_list _ArgList); 113 | 114 | #endif // HYPERPLATFORM_KERNEL_STL_H_ 115 | -------------------------------------------------------------------------------- /kHypervisorBasic/vmx_common.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2016 KelvinChan. All rights reserved. 4 | Use of this source code is governed by a MIT-style license that can be 5 | found in the LICENSE file. 6 | 7 | Module Name: 8 | 9 | vmx_common.cpp 10 | 11 | Abstract: 12 | 13 | VMX instruction emulation utilities 14 | 15 | Author: 16 | 17 | Kelvin Chan 18 | 19 | Environment: 20 | 21 | Kernel VMM Mode 22 | 23 | --*/ 24 | #pragma once 25 | #include 26 | #include 27 | #include "vmx_common.h" 28 | #include "vmx.h" 29 | #include "log.h" 30 | #include "vmm.h" 31 | #include "util.h" 32 | #include "vmcs.h" 33 | #include "ept.h" 34 | extern "C" 35 | { 36 | 37 | typedef enum 38 | { 39 | Active = 0, 40 | HLT, 41 | ShutDown, 42 | WaitForSipi 43 | }ActivityState; 44 | 45 | // VMX Instruction Return 46 | VOID 47 | VMSucceed( 48 | _In_ FlagRegister *reg 49 | ); 50 | 51 | VOID 52 | VMfailInvalid( 53 | _In_ FlagRegister *reg 54 | ); 55 | 56 | VOID 57 | VMfailValid( 58 | _In_ FlagRegister *reg, 59 | _In_ VmxInstructionError err 60 | ); 61 | 62 | VOID 63 | VMfail( 64 | _In_ FlagRegister *reg, 65 | _In_ VmxInstructionError err 66 | ); 67 | 68 | //VMX Regular Check 69 | BOOLEAN 70 | IsGuestinPagingMode(); 71 | 72 | BOOLEAN 73 | IsGuestSetNumericErrorBit(); 74 | 75 | BOOLEAN 76 | IsGuestInProtectedMode(); 77 | 78 | BOOLEAN 79 | IsGuestSupportVMX(); 80 | 81 | BOOLEAN 82 | IsGuestInVirtual8086(); 83 | 84 | BOOLEAN 85 | IsGuestinCompatibliltyMode(); 86 | 87 | BOOLEAN 88 | IsGuestInIA32eMode(); 89 | 90 | BOOLEAN 91 | IsLockbitClear(); 92 | 93 | BOOLEAN 94 | IsGuestEnableVMXOnInstruction(); 95 | 96 | BOOLEAN 97 | CheckPhysicalAddress(ULONG64 vmxon_region_pa); 98 | 99 | //Normal Check 100 | BOOLEAN 101 | CheckPageAlgined(_In_ ULONG64 address); 102 | 103 | //Get Guest Information 104 | USHORT 105 | GetGuestCPL(); 106 | 107 | ULONG 108 | GetVMCSRevisionIdentifier(); 109 | 110 | //Interrupt Injection 111 | VOID 112 | FillEventInjection( 113 | _In_ ULONG32 interruption_type, 114 | _In_ ULONG32 exception_vector, 115 | _In_ BOOLEAN isDeliver_error_code, 116 | _In_ BOOLEAN isValid 117 | ); 118 | 119 | VOID 120 | ThrowInvalidCodeException(); 121 | 122 | VOID 123 | ThrowGerneralFaultInterrupt(); 124 | 125 | //Decode for VMCLEAR, VMPTRLD, VMPTRST, VMXON instruction 126 | ULONG64 127 | DecodeVmclearOrVmptrldOrVmptrstOrVmxon( 128 | _In_ GuestContext* guest_context 129 | ); 130 | 131 | 132 | SegmentDescriptor* 133 | GetSegmentDesctiptor( 134 | _In_ SegmentSelector ss, 135 | _In_ ULONG64 gdtBase 136 | ); 137 | 138 | struct ProcessorData; 139 | 140 | VOID 141 | SaveGuestKernelGsBase( 142 | _In_ ProcessorData* vcpu 143 | ); 144 | 145 | VOID 146 | LoadGuestKernelGsBase( 147 | _In_ ProcessorData* vcpu 148 | ); 149 | 150 | VOID 151 | SaveHostKernelGsBase( 152 | _In_ ProcessorData* vcpu 153 | ); 154 | 155 | VOID 156 | LoadHostKernelGsBase( 157 | _In_ ProcessorData* vcpu 158 | ); 159 | 160 | 161 | VOID 162 | VmmSaveCurrentEpt02Pointer( 163 | _In_ GuestContext* guest_context, 164 | _In_ EptData* Ept02 165 | ); 166 | 167 | EptData* 168 | VmmGetCurrentEpt02Pointer( 169 | _In_ GuestContext* guest_context 170 | ); 171 | 172 | EptData* 173 | VmmGetCurrentEpt01Pointer( 174 | _In_ GuestContext* guest_context 175 | ); 176 | 177 | VOID 178 | VmmSaveCurrentEpt12Pointer( 179 | _In_ GuestContext* guest_context, 180 | _In_ EptData* Ept12 181 | ); 182 | 183 | EptData* 184 | VmmGetCurrentEpt12Pointer( 185 | _In_ GuestContext* guest_context 186 | ); 187 | 188 | ULONG 189 | VmpGetSegmentAccessRight( 190 | _In_ USHORT segment_selector 191 | ); 192 | 193 | ULONG_PTR* 194 | VmmpSelectRegister( 195 | _In_ ULONG index, 196 | _In_ GuestContext *guest_context 197 | ); 198 | 199 | GpRegisters* 200 | VmmpGetGpReg( 201 | _In_ GuestContext* guest_context 202 | ); 203 | 204 | FlagRegister* 205 | VmmpGetFlagReg( 206 | _In_ GuestContext* guest_context 207 | ); 208 | 209 | KIRQL 210 | VmmpGetGuestIrql( 211 | _In_ GuestContext* guest_context 212 | ); 213 | 214 | ULONG_PTR 215 | VmmpGetGuestCr8( 216 | _In_ GuestContext* guest_context 217 | ); 218 | 219 | VCPUVMX* 220 | VmmpGetVcpuVmx( 221 | _In_ GuestContext* guest_context 222 | ); 223 | 224 | VOID 225 | VmmpSetvCpuVmx( 226 | _In_ GuestContext* guest_context, 227 | _In_ VCPUVMX* VCPUVMX 228 | ); 229 | 230 | VOID 231 | VmmpEnterVmxMode( 232 | _In_ GuestContext* guest_context 233 | ); 234 | VOID 235 | VmmpLeaveVmxMode( 236 | _In_ GuestContext* guest_context 237 | ); 238 | 239 | ULONG 240 | VmmpGetvCpuMode( 241 | _In_ GuestContext* guest_context 242 | ); 243 | 244 | ProcessorData* 245 | VmmpGetProcessorData( 246 | _In_ GuestContext* guest_context 247 | ); 248 | 249 | 250 | } -------------------------------------------------------------------------------- /kHypervisor/kHypervisor.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.32106.194 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3F4B87F6-9967-4C6F-B1A4-010B6C19ED8D}" 7 | ProjectSection(SolutionItems) = preProject 8 | .clang-format = .clang-format 9 | .gitattributes = .gitattributes 10 | .gitignore = .gitignore 11 | LICENSE.txt = LICENSE.txt 12 | README.md = README.md 13 | EndProjectSection 14 | EndProject 15 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kHypervisor", "kHypervisor\kHypervisor.vcxproj", "{B20D17DD-453E-4420-B691-4EB4B9AE3A15}" 16 | EndProject 17 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kHypervisorBasic", "..\kHypervisorBasic\kHypervisorBasic.vcxproj", "{E34F9C06-9078-4915-BBEF-9FBF94441BCC}" 18 | EndProject 19 | Global 20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 21 | Debug|ARM = Debug|ARM 22 | Debug|ARM64 = Debug|ARM64 23 | Debug|x64 = Debug|x64 24 | Debug|x86 = Debug|x86 25 | Release|ARM = Release|ARM 26 | Release|ARM64 = Release|ARM64 27 | Release|x64 = Release|x64 28 | Release|x86 = Release|x86 29 | EndGlobalSection 30 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 31 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Debug|ARM.ActiveCfg = Debug|Win32 32 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Debug|ARM64.ActiveCfg = Debug|Win32 33 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Debug|x64.ActiveCfg = Debug|x64 34 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Debug|x64.Build.0 = Debug|x64 35 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Debug|x64.Deploy.0 = Debug|x64 36 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Debug|x86.ActiveCfg = Debug|Win32 37 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Debug|x86.Build.0 = Debug|Win32 38 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Debug|x86.Deploy.0 = Debug|Win32 39 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Release|ARM.ActiveCfg = Release|Win32 40 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Release|ARM64.ActiveCfg = Release|Win32 41 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Release|x64.ActiveCfg = Release|x64 42 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Release|x64.Build.0 = Release|x64 43 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Release|x64.Deploy.0 = Release|x64 44 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Release|x86.ActiveCfg = Release|Win32 45 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Release|x86.Build.0 = Release|Win32 46 | {B20D17DD-453E-4420-B691-4EB4B9AE3A15}.Release|x86.Deploy.0 = Release|Win32 47 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Debug|ARM.ActiveCfg = Debug|ARM 48 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Debug|ARM.Build.0 = Debug|ARM 49 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Debug|ARM.Deploy.0 = Debug|ARM 50 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Debug|ARM64.ActiveCfg = Debug|ARM64 51 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Debug|ARM64.Build.0 = Debug|ARM64 52 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Debug|ARM64.Deploy.0 = Debug|ARM64 53 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Debug|x64.ActiveCfg = Debug|x64 54 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Debug|x64.Build.0 = Debug|x64 55 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Debug|x64.Deploy.0 = Debug|x64 56 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Debug|x86.ActiveCfg = Debug|Win32 57 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Debug|x86.Build.0 = Debug|Win32 58 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Debug|x86.Deploy.0 = Debug|Win32 59 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Release|ARM.ActiveCfg = Release|ARM 60 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Release|ARM.Build.0 = Release|ARM 61 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Release|ARM.Deploy.0 = Release|ARM 62 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Release|ARM64.ActiveCfg = Release|ARM64 63 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Release|ARM64.Build.0 = Release|ARM64 64 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Release|ARM64.Deploy.0 = Release|ARM64 65 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Release|x64.ActiveCfg = Release|x64 66 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Release|x64.Build.0 = Release|x64 67 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Release|x64.Deploy.0 = Release|x64 68 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Release|x86.ActiveCfg = Release|Win32 69 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Release|x86.Build.0 = Release|Win32 70 | {E34F9C06-9078-4915-BBEF-9FBF94441BCC}.Release|x86.Deploy.0 = Release|Win32 71 | EndGlobalSection 72 | GlobalSection(SolutionProperties) = preSolution 73 | HideSolutionNode = FALSE 74 | EndGlobalSection 75 | GlobalSection(ExtensibilityGlobals) = postSolution 76 | SolutionGuid = {9F72B71F-3375-4844-8C18-D69223AC7ACA} 77 | EndGlobalSection 78 | EndGlobal 79 | -------------------------------------------------------------------------------- /kHypervisorBasic/include/capstone/mos65xx.h: -------------------------------------------------------------------------------- 1 | #ifndef CAPSTONE_MOS65XX_H 2 | #define CAPSTONE_MOS65XX_H 3 | 4 | /* Capstone Disassembly Engine */ 5 | /* By Sebastian Macke 13 | #include "ia32_type.h" 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | 31 | /// A structure made up of mutual fields across all EPT entry types 32 | union EptCommonEntry { 33 | ULONG64 all; 34 | struct { 35 | ULONG64 read_access : 1; //!< [0] 36 | ULONG64 write_access : 1; //!< [1] 37 | ULONG64 execute_access : 1; //!< [2] 38 | ULONG64 memory_type : 3; //!< [3:5] 39 | ULONG64 reserved1 : 6; //!< [6:11] 40 | ULONG64 physial_address : 36; //!< [12:48-1] 41 | ULONG64 reserved2 : 16; //!< [48:63] 42 | } fields; 43 | }; 44 | static_assert(sizeof(EptCommonEntry) == 8, "Size check"); 45 | 46 | 47 | // EPT related data stored in ProcessorSharedData 48 | typedef struct EptData { 49 | EptPointer *ept_pointer; 50 | EptCommonEntry *ept_pml4; 51 | 52 | EptCommonEntry **preallocated_entries; // An array of pre-allocated entries 53 | volatile long preallocated_entries_count; // # of used pre-allocated entries 54 | }; 55 | 56 | //////////////////////////////////////////////////////////////////////////////// 57 | // 58 | // prototypes 59 | // 60 | 61 | /// Checks if the system supports EPT technology sufficient enough 62 | /// @return true if the system supports EPT 63 | _IRQL_requires_max_(PASSIVE_LEVEL) bool EptIsEptAvailable(); 64 | 65 | /// Returns an EPT pointer from \a ept_data 66 | /// @param ept_data EptData to get an EPT pointer 67 | /// @return An EPT pointer 68 | ULONG64 EptGetEptPointer(_In_ EptData* ept_data); 69 | 70 | /// Builds EPT, allocates pre-allocated entires, initializes and returns EptData 71 | /// @return An allocated EptData on success, or nullptr 72 | /// 73 | /// A driver must call EptTermination() with a returned value when this function 74 | /// succeeded. 75 | _IRQL_requires_max_(PASSIVE_LEVEL) EptData* EptInitialization(); 76 | 77 | /// De-allocates \a ept_data and all resources referenced in it 78 | /// @param ept_data A returned value of EptInitialization() 79 | void EptTermination(_In_ EptData* ept_data); 80 | 81 | /// Handles VM-exit triggered by EPT violation 82 | /// @param ept_data EptData to get an EPT pointer 83 | _IRQL_requires_min_(DISPATCH_LEVEL) void EptHandleEptViolation( 84 | _In_ EptData* ept_data, 85 | _In_ ULONG64 PhysAddr, 86 | _In_ bool is_range_of_ept12); 87 | 88 | /// Returns an EPT entry corresponds to \a physical_address 89 | /// @param ept_data EptData to get an EPT entry 90 | /// @param physical_address Physical address to get an EPT entry 91 | /// @return An EPT entry, or nullptr if not allocated yet 92 | EptCommonEntry* EptGetEptPtEntry(_In_ EptData* ept_data, 93 | _In_ ULONG64 physical_address); 94 | 95 | 96 | EptData* EptBuildEptDataByEptp(); 97 | 98 | 99 | EptCommonEntry *EptpConstructTablesEx( 100 | EptCommonEntry *table, ULONG table_level, ULONG64 physical_address, 101 | EptData *ept_data, EptCommonEntry* reserved); 102 | 103 | 104 | void EptpInvalidateEpt( 105 | EptData* EptData12, 106 | EptData* EptData01 107 | ); 108 | 109 | void EptpValidateEpt( 110 | EptData* EptData12, 111 | EptData* EptData01 112 | ); 113 | 114 | bool EptpIsInRangesOfEpt( 115 | ULONG_PTR PhysicalAddres, 116 | EptCommonEntry *pml4_table 117 | ); 118 | 119 | 120 | NTSTATUS EptpBuildNestedEpt( 121 | ULONG_PTR vmcs12_va, 122 | EptData* ept_data12, 123 | EptData* ept_data02); 124 | 125 | void 126 | EptpRefreshEpt02( 127 | EptData* EptData02, 128 | EptData* EptData12, 129 | EptData* EptData01, 130 | void* LookupEntryPa 131 | ); 132 | 133 | EptCommonEntry* 134 | EptpLookupEntryInEpt( 135 | EptData* EptData, 136 | EptCommonEntry *EntryAddress 137 | ); 138 | 139 | 140 | /// Reads and stores all MTRRs to set a correct memory type for EPT 141 | _IRQL_requires_max_(PASSIVE_LEVEL) void EptInitializeMtrrEntries(); 142 | //////////////////////////////////////////////////////////////////////////////// 143 | // 144 | // variables 145 | // 146 | 147 | //////////////////////////////////////////////////////////////////////////////// 148 | // 149 | // implementations 150 | // 151 | 152 | } // extern "C" 153 | 154 | #endif // HYPERPLATFORM_EPT_H_ 155 | -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/shadow_hook.cpp: -------------------------------------------------------------------------------- 1 | #include "shadow_hook.h" 2 | #include 3 | #define NTSTRSAFE_NO_CB_FUNCTIONS 4 | #include 5 | #include "../HyperPlatform/util.h" 6 | #undef _HAS_EXCEPTIONS 7 | #define _HAS_EXCEPTIONS 0 8 | #include "list.h" 9 | #include "hook.h" 10 | 11 | // Copy of a page seen by a guest as a result of memory shadowing 12 | struct Page { 13 | UCHAR* page; // A page aligned copy of a page 14 | }; 15 | 16 | // Contains a single steal hook information 17 | struct HookInformation { 18 | void* patch_address; // An address where a hook is installed 19 | void* handler; // An address of the handler routine 20 | 21 | // A copy of a pages where patch_address belongs to. shadow_page_base_for_rw 22 | // is exposed to a guest for read and write operation against the page of 23 | // patch_address, and shadow_page_base_for_exec is exposed for execution. 24 | Page* shadow_page_base_for_rw; 25 | Page* shadow_page_base_for_exec; 26 | 27 | // Physical address of the above two copied pages 28 | ULONG64 pa_base_for_rw; 29 | ULONG64 pa_base_for_exec; 30 | }; 31 | 32 | // Data structure shared across all processors 33 | struct SharedShadowHookData { 34 | LIST_ELEM list; 35 | HookInformation* hooks; 36 | }; 37 | 38 | // A structure reflects inline hook code. 39 | #include 40 | #if defined(_AMD64_) 41 | struct TrampolineCode { 42 | UCHAR nop; 43 | UCHAR jmp[6]; 44 | void* address; 45 | }; 46 | static_assert(sizeof(TrampolineCode) == 15, "Size check"); 47 | #else 48 | 49 | struct TrampolineCode { 50 | UCHAR nop; 51 | UCHAR push; 52 | void* address; 53 | UCHAR ret; 54 | }; 55 | static_assert(sizeof(TrampolineCode) == 7, "Size check"); 56 | 57 | #endif 58 | #include 59 | 60 | // Returns code bytes for inline hooking 61 | _Use_decl_annotations_ EXTERN_C static TrampolineCode ShpMakeTrampolineCode( 62 | void* hook_handler 63 | ) 64 | { 65 | PAGED_CODE(); 66 | 67 | #if defined(_AMD64_) 68 | // 90 nop 69 | // ff2500000000 jmp qword ptr cs:jmp_addr 70 | // jmp_addr: 71 | // 0000000000000000 dq 0 72 | return { 73 | 0x90, 74 | { 75 | 0xff, 76 | 0x25, 77 | 0x00, 78 | 0x00, 79 | 0x00, 80 | 0x00, 81 | }, 82 | hook_handler, 83 | }; 84 | #else 85 | // 90 nop 86 | // 6832e30582 push offset nt!ExFreePoolWithTag + 0x2 (8205e332) 87 | // c3 ret 88 | return { 89 | 0x90, 90 | 0x68, 91 | hook_handler, 92 | 0xc3, 93 | }; 94 | #endif 95 | } 96 | 97 | // RW Epage 98 | // sys_functionaddr 99 | // hook_functionaddr 100 | _Use_decl_annotations_ extern "C" bool ShInstallHook( 101 | SharedShadowHookData* shared_sh_data, void* address, 102 | ShadowHookTarget* target) { 103 | // create hook information 104 | HookInformation* info = (HookInformation*)ExAllocatePoolWithTag( 105 | NonPagedPool, sizeof(HookInformation), 'Tag'); 106 | RtlSecureZeroMemory(info, sizeof(HookInformation)); 107 | 108 | HookInformation* reusable_info = nullptr; 109 | // find sys_functionaddress to SharedShadowHookData 110 | SharedShadowHookData* shaobj = 111 | (SharedShadowHookData*)List_Head(shared_sh_data); 112 | while (shaobj) { 113 | if (shaobj->hooks->patch_address == address) { 114 | reusable_info = shaobj->hooks; 115 | break; 116 | } 117 | shaobj = (SharedShadowHookData*)List_Next(shared_sh_data); 118 | } 119 | 120 | // find Success && save old rw exec attr 121 | if (reusable_info) { 122 | info->shadow_page_base_for_rw = reusable_info->shadow_page_base_for_rw; 123 | info->shadow_page_base_for_exec = reusable_info->shadow_page_base_for_exec; 124 | } else { 125 | Page* page = 126 | (Page*)ExAllocatePoolWithTag(NonPagedPool, sizeof(Page), 'Tag'); 127 | Page* page1 = 128 | (Page*)ExAllocatePoolWithTag(NonPagedPool, sizeof(Page), 'Tag'); 129 | RtlSecureZeroMemory(page, sizeof(Page)); 130 | RtlSecureZeroMemory(page1, sizeof(Page)); 131 | info->shadow_page_base_for_rw = page; 132 | info->shadow_page_base_for_exec = page1; 133 | auto page_base = PAGE_ALIGN(address); 134 | RtlCopyMemory(info->shadow_page_base_for_rw->page, page_base, PAGE_SIZE); 135 | RtlCopyMemory(info->shadow_page_base_for_exec->page, page_base, PAGE_SIZE); 136 | } 137 | info->patch_address = address; 138 | info->pa_base_for_rw = UtilPaFromVa(info->shadow_page_base_for_rw->page); 139 | info->pa_base_for_exec = UtilPaFromVa(info->shadow_page_base_for_exec->page); 140 | info->handler = target->handler; 141 | 142 | // analys hook pointer 143 | //SIZE_T patch_size = 0; 144 | //Hook_Tramp_CountBytes(); 145 | //if (!patch_size) { 146 | // return false; 147 | //} 148 | return true; 149 | } -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/vmx_common.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2016 KelvinChan. All rights reserved. 4 | Use of this source code is governed by a MIT-style license that can be 5 | found in the LICENSE file. 6 | 7 | Module Name: 8 | 9 | vmx_common.cpp 10 | 11 | Abstract: 12 | 13 | VMX instruction emulation utilities 14 | 15 | Author: 16 | 17 | Kelvin Chan 18 | 19 | Environment: 20 | 21 | Kernel VMM Mode 22 | 23 | --*/ 24 | #pragma once 25 | #include 26 | #include 27 | #include "vmx_common.h" 28 | #include "vmx.h" 29 | #include "..\HyperPlatform\log.h" 30 | #include "..\HyperPlatform\vmm.h" 31 | #include "..\HyperPlatform\util.h" 32 | #include "vmcs.h" 33 | extern "C" 34 | { 35 | 36 | typedef enum 37 | { 38 | Active = 0, 39 | HLT, 40 | ShutDown, 41 | WaitForSipi 42 | }ActivityState; 43 | 44 | // VMX Instruction Return 45 | VOID 46 | VMSucceed( 47 | _In_ FlagRegister *reg 48 | ); 49 | 50 | VOID 51 | VMfailInvalid( 52 | _In_ FlagRegister *reg 53 | ); 54 | 55 | VOID 56 | VMfailValid( 57 | _In_ FlagRegister *reg, 58 | _In_ VmxInstructionError err 59 | ); 60 | 61 | VOID 62 | VMfail( 63 | _In_ FlagRegister *reg, 64 | _In_ VmxInstructionError err 65 | ); 66 | 67 | //VMX Regular Check 68 | BOOLEAN 69 | IsGuestinPagingMode(); 70 | 71 | BOOLEAN 72 | IsGuestSetNumericErrorBit(); 73 | 74 | BOOLEAN 75 | IsGuestInProtectedMode(); 76 | 77 | BOOLEAN 78 | IsGuestSupportVMX(); 79 | 80 | BOOLEAN 81 | IsGuestInVirtual8086(); 82 | 83 | BOOLEAN 84 | IsGuestinCompatibliltyMode(); 85 | 86 | BOOLEAN 87 | IsGuestInIA32eMode(); 88 | 89 | BOOLEAN 90 | IsLockbitClear(); 91 | 92 | BOOLEAN 93 | IsGuestEnableVMXOnInstruction(); 94 | 95 | BOOLEAN 96 | CheckPhysicalAddress(ULONG64 vmxon_region_pa); 97 | 98 | //Normal Check 99 | BOOLEAN 100 | CheckPageAlgined(_In_ ULONG64 address); 101 | 102 | //Get Guest Information 103 | USHORT 104 | GetGuestCPL(); 105 | 106 | ULONG 107 | GetVMCSRevisionIdentifier(); 108 | 109 | //Interrupt Injection 110 | VOID 111 | FillEventInjection( 112 | _In_ ULONG32 interruption_type, 113 | _In_ ULONG32 exception_vector, 114 | _In_ BOOLEAN isDeliver_error_code, 115 | _In_ BOOLEAN isValid 116 | ); 117 | 118 | VOID 119 | ThrowInvalidCodeException(); 120 | 121 | VOID 122 | ThrowGerneralFaultInterrupt(); 123 | 124 | //Decode for VMCLEAR, VMPTRLD, VMPTRST, VMXON instruction 125 | ULONG64 126 | DecodeVmclearOrVmptrldOrVmptrstOrVmxon( 127 | _In_ GuestContext* guest_context 128 | ); 129 | 130 | 131 | SegmentDescriptor* 132 | GetSegmentDesctiptor( 133 | _In_ SegmentSelector ss, 134 | _In_ ULONG64 gdtBase 135 | ); 136 | 137 | struct ProcessorData; 138 | 139 | VOID 140 | SaveGuestKernelGsBase( 141 | _In_ ProcessorData* vcpu 142 | ); 143 | 144 | VOID 145 | LoadGuestKernelGsBase( 146 | _In_ ProcessorData* vcpu 147 | ); 148 | 149 | VOID 150 | SaveHostKernelGsBase( 151 | _In_ ProcessorData* vcpu 152 | ); 153 | 154 | VOID 155 | LoadHostKernelGsBase( 156 | _In_ ProcessorData* vcpu 157 | ); 158 | 159 | 160 | VOID 161 | VmmSaveCurrentEpt02Pointer( 162 | _In_ GuestContext* guest_context, 163 | _In_ EptData* Ept02 164 | ); 165 | 166 | EptData* 167 | VmmGetCurrentEpt02Pointer( 168 | _In_ GuestContext* guest_context 169 | ); 170 | 171 | EptData* 172 | VmmGetCurrentEpt01Pointer( 173 | _In_ GuestContext* guest_context 174 | ); 175 | 176 | VOID 177 | VmmSaveCurrentEpt12Pointer( 178 | _In_ GuestContext* guest_context, 179 | _In_ EptData* Ept12 180 | ); 181 | 182 | EptData* 183 | VmmGetCurrentEpt12Pointer( 184 | _In_ GuestContext* guest_context 185 | ); 186 | 187 | ULONG 188 | VmpGetSegmentAccessRight( 189 | _In_ USHORT segment_selector 190 | ); 191 | 192 | ULONG_PTR* 193 | VmmpSelectRegister( 194 | _In_ ULONG index, 195 | _In_ GuestContext *guest_context 196 | ); 197 | 198 | GpRegisters* 199 | VmmpGetGpReg( 200 | _In_ GuestContext* guest_context 201 | ); 202 | 203 | FlagRegister* 204 | VmmpGetFlagReg( 205 | _In_ GuestContext* guest_context 206 | ); 207 | 208 | KIRQL 209 | VmmpGetGuestIrql( 210 | _In_ GuestContext* guest_context 211 | ); 212 | 213 | ULONG_PTR 214 | VmmpGetGuestCr8( 215 | _In_ GuestContext* guest_context 216 | ); 217 | 218 | VCPUVMX* 219 | VmmpGetVcpuVmx( 220 | _In_ GuestContext* guest_context 221 | ); 222 | 223 | VOID 224 | VmmpSetvCpuVmx( 225 | _In_ GuestContext* guest_context, 226 | _In_ VCPUVMX* VCPUVMX 227 | ); 228 | 229 | VOID 230 | VmmpEnterVmxMode( 231 | _In_ GuestContext* guest_context 232 | ); 233 | VOID 234 | VmmpLeaveVmxMode( 235 | _In_ GuestContext* guest_context 236 | ); 237 | 238 | ULONG 239 | VmmpGetvCpuMode( 240 | _In_ GuestContext* guest_context 241 | ); 242 | 243 | ProcessorData* 244 | VmmpGetProcessorData( 245 | _In_ GuestContext* guest_context 246 | ); 247 | 248 | 249 | } -------------------------------------------------------------------------------- /kHypervisorBasic/kHypervisorBasic.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | Header Files 56 | 57 | 58 | Header Files 59 | 60 | 61 | Header Files 62 | 63 | 64 | Header Files 65 | 66 | 67 | Header Files 68 | 69 | 70 | Header Files 71 | 72 | 73 | Header Files 74 | 75 | 76 | Header Files 77 | 78 | 79 | Header Files 80 | 81 | 82 | Header Files 83 | 84 | 85 | 86 | 87 | Source Files 88 | 89 | 90 | Source Files 91 | 92 | 93 | Source Files 94 | 95 | 96 | Source Files 97 | 98 | 99 | Source Files 100 | 101 | 102 | Source Files 103 | 104 | 105 | Source Files 106 | 107 | 108 | Source Files 109 | 110 | 111 | Source Files 112 | 113 | 114 | Source Files 115 | 116 | 117 | Source Files 118 | 119 | 120 | Source Files 121 | 122 | 123 | Source Files 124 | 125 | 126 | Source Files 127 | 128 | 129 | 130 | 131 | Source Files 132 | 133 | 134 | Source Files 135 | 136 | 137 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/ept.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Declares interfaces to EPT functions. 8 | 9 | #ifndef HYPERPLATFORM_EPT_H_ 10 | #define HYPERPLATFORM_EPT_H_ 11 | 12 | #include 13 | #include "ia32_type.h" 14 | extern "C" { 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // 17 | // macro utilities 18 | // 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // 22 | // constants and macros 23 | // 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // 27 | // types 28 | // 29 | 30 | 31 | /// A structure made up of mutual fields across all EPT entry types 32 | union EptCommonEntry { 33 | ULONG64 all; 34 | struct { 35 | ULONG64 read_access : 1; //!< [0] 36 | ULONG64 write_access : 1; //!< [1] 37 | ULONG64 execute_access : 1; //!< [2] 38 | ULONG64 memory_type : 3; //!< [3:5] 39 | ULONG64 reserved1 : 6; //!< [6:11] 40 | ULONG64 physial_address : 36; //!< [12:48-1] 41 | ULONG64 reserved2 : 16; //!< [48:63] 42 | } fields; 43 | }; 44 | static_assert(sizeof(EptCommonEntry) == 8, "Size check"); 45 | 46 | 47 | // EPT related data stored in ProcessorSharedData 48 | typedef struct EptData { 49 | EptPointer *ept_pointer; 50 | EptCommonEntry *ept_pml4; 51 | 52 | EptCommonEntry **preallocated_entries; // An array of pre-allocated entries 53 | volatile long preallocated_entries_count; // # of used pre-allocated entries 54 | }; 55 | 56 | struct ShadowHookData; 57 | struct SharedShadowHookData; 58 | 59 | //////////////////////////////////////////////////////////////////////////////// 60 | // 61 | // prototypes 62 | // 63 | 64 | /// Checks if the system supports EPT technology sufficient enough 65 | /// @return true if the system supports EPT 66 | _IRQL_requires_max_(PASSIVE_LEVEL) bool EptIsEptAvailable(); 67 | 68 | /// Returns an EPT pointer from \a ept_data 69 | /// @param ept_data EptData to get an EPT pointer 70 | /// @return An EPT pointer 71 | ULONG64 EptGetEptPointer(_In_ EptData* ept_data); 72 | 73 | /// Builds EPT, allocates pre-allocated entires, initializes and returns EptData 74 | /// @return An allocated EptData on success, or nullptr 75 | /// 76 | /// A driver must call EptTermination() with a returned value when this function 77 | /// succeeded. 78 | _IRQL_requires_max_(PASSIVE_LEVEL) EptData* EptInitialization(); 79 | 80 | /// De-allocates \a ept_data and all resources referenced in it 81 | /// @param ept_data A returned value of EptInitialization() 82 | void EptTermination(_In_ EptData* ept_data); 83 | 84 | /// Handles VM-exit triggered by EPT violation 85 | /// @param ept_data EptData to get an EPT pointer 86 | _IRQL_requires_min_(DISPATCH_LEVEL) void EptHandleEptViolation( 87 | _In_ EptData* ept_data, 88 | _In_ ULONG64 PhysAddr, 89 | _In_ bool is_range_of_ept12, 90 | ShadowHookData* sh_data, 91 | SharedShadowHookData* shared_sh_data); 92 | 93 | /// Returns an EPT entry corresponds to \a physical_address 94 | /// @param ept_data EptData to get an EPT entry 95 | /// @param physical_address Physical address to get an EPT entry 96 | /// @return An EPT entry, or nullptr if not allocated yet 97 | EptCommonEntry* EptGetEptPtEntry(_In_ EptData* ept_data, 98 | _In_ ULONG64 physical_address); 99 | 100 | 101 | EptData* EptBuildEptDataByEptp(); 102 | 103 | 104 | EptCommonEntry *EptpConstructTablesEx( 105 | EptCommonEntry *table, ULONG table_level, ULONG64 physical_address, 106 | EptData *ept_data, EptCommonEntry* reserved); 107 | 108 | 109 | void EptpInvalidateEpt( 110 | EptData* EptData12, 111 | EptData* EptData01 112 | ); 113 | 114 | void EptpValidateEpt( 115 | EptData* EptData12, 116 | EptData* EptData01 117 | ); 118 | 119 | bool EptpIsInRangesOfEpt( 120 | ULONG_PTR PhysicalAddres, 121 | EptCommonEntry *pml4_table 122 | ); 123 | 124 | 125 | NTSTATUS EptpBuildNestedEpt( 126 | ULONG_PTR vmcs12_va, 127 | EptData* ept_data12, 128 | EptData* ept_data02); 129 | 130 | void 131 | EptpRefreshEpt02( 132 | EptData* EptData02, 133 | EptData* EptData12, 134 | EptData* EptData01, 135 | void* LookupEntryPa 136 | ); 137 | 138 | EptCommonEntry* 139 | EptpLookupEntryInEpt( 140 | EptData* EptData, 141 | EptCommonEntry *EntryAddress 142 | ); 143 | 144 | 145 | /// Reads and stores all MTRRs to set a correct memory type for EPT 146 | _IRQL_requires_max_(PASSIVE_LEVEL) void EptInitializeMtrrEntries(); 147 | //////////////////////////////////////////////////////////////////////////////// 148 | // 149 | // variables 150 | // 151 | 152 | //////////////////////////////////////////////////////////////////////////////// 153 | // 154 | // implementations 155 | // 156 | 157 | } // extern "C" 158 | 159 | #endif // HYPERPLATFORM_EPT_H_ 160 | -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/Common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Native.h" 3 | #include 4 | 5 | #define DPRINT(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, __VA_ARGS__) 6 | //#define DPRINT(format, ...) 7 | #define HB_POOL_TAG '0mVZ' 8 | 9 | #define NBP_MAGIC ((ULONG32)'!LTI') 10 | #define HYPERCALL_UNLOAD 0x1 11 | #define HYPERCALL_HOOK_LSTAR 0x2 12 | #define HYPERCALL_UNHOOK_LSTAR 0x3 13 | #define HYPERCALL_HOOK_PAGE 0x4 14 | #define HYPERCALL_UNHOOK_PAGE 0x5 15 | 16 | #define MAX_CPU_PER_GROUP 64 17 | 18 | #define BUG_CHECK_UNSPECIFIED 0 19 | #define BUG_CHECK_INVALID_VM 1 20 | #define BUG_CHECK_TRIPLE_FAULT 2 21 | #define BUG_CHECK_EPT_MISCONFIG 3 22 | #define BUG_CHECK_EPT_VIOLATION 4 23 | #define BUG_CHECK_EPT_NO_PAGES 5 24 | 25 | #define CPU_IDX (KeGetCurrentProcessorNumberEx( NULL )) 26 | #define PFN(addr) (ULONG64)((addr) >> PAGE_SHIFT) 27 | #define SSDTIndex(ptr) *(PULONG)((ULONG_PTR)ptr + 0x15) 28 | 29 | #define PAGES_PER_ENTRY ((PAGE_SIZE - sizeof( LIST_ENTRY ) - sizeof( ULONG64 )) / sizeof( union _EPT_MMPTE* )) 30 | #define EPT_PREALLOC_PAGES 512 31 | 32 | extern "C" { 33 | /// 34 | /// CPU vendor 35 | /// 36 | typedef enum _CPU_VENDOR 37 | { 38 | CPU_Other = 0, 39 | CPU_Intel, 40 | CPU_AMD 41 | } CPU_VENDOR; 42 | 43 | /// 44 | /// Virtual CPU state 45 | /// 46 | typedef enum _VCPU_VMX_STATE 47 | { 48 | VMX_STATE_OFF = 0, // No virtualization 49 | VMX_STATE_TRANSITION = 1, // Virtualized, context not yet restored 50 | VMX_STATE_ON = 2 // Virtualized, running guest 51 | } VCPU_VMX_STATE; 52 | 53 | #pragma warning(disable: 4214) 54 | 55 | /// 56 | /// VMXON and VMCS regions 57 | /// 58 | typedef struct _VMX_VMCS 59 | { 60 | ULONG RevisionId; 61 | ULONG AbortIndicator; 62 | UCHAR Data[PAGE_SIZE - 2 * sizeof( ULONG )]; 63 | } VMX_VMCS, *PVMX_VMCS; 64 | 65 | /// 66 | /// EPT pages storage 67 | /// 68 | typedef struct _EPT_PAGES_ENTRY 69 | { 70 | LIST_ENTRY link; 71 | ULONG64 count; 72 | union _EPT_MMPTE* pages[PAGES_PER_ENTRY]; 73 | } EPT_PAGES_ENTRY, *PEPT_PAGES_ENTRY; 74 | 75 | typedef struct _VMX_FEATURES 76 | { 77 | ULONG64 SecondaryControls : 1; // Secondary controls are enabled 78 | ULONG64 TrueMSRs : 1; // True VMX MSR values are supported 79 | ULONG64 EPT : 1; // EPT supported by CPU 80 | ULONG64 VPID : 1; // VPID supported by CPU 81 | ULONG64 ExecOnlyEPT : 1; // EPT translation with execute-only access is supported 82 | ULONG64 InvSingleAddress : 1; // IVVPID for single address 83 | ULONG64 VMFUNC : 1; // VMFUNC is supported 84 | } VMX_FEATURES, *PVMX_FEATURES; 85 | 86 | /// 87 | /// VCPU EPT info 88 | /// 89 | typedef struct _EPT_DATA 90 | { 91 | union _EPT_MMPTE* PML4Ptr; // EPT PML4 pointer 92 | LIST_ENTRY PageList; // EPT_PAGES_ENTRY list 93 | union _EPT_MMPTE* Pages[EPT_PREALLOC_PAGES]; // Array of preallocated pages 94 | ULONG Preallocations; // Number of used preallocated pages 95 | ULONG TotalPages; // Total number of EPT pages 96 | } EPT_DATA, *PEPT_DATA; 97 | 98 | /// 99 | /// Page hook trace state 100 | /// 101 | typedef struct _PAGE_HOOK_STATE 102 | { 103 | struct _PAGE_HOOK_ENTRY* pEntry; 104 | ULONG64 Rip; 105 | } PAGE_HOOK_STATE, *PPAGE_HOOK_STATE; 106 | 107 | /// 108 | /// Virtual CPU stuff 109 | /// 110 | typedef struct _VCPU 111 | { 112 | KPROCESSOR_STATE HostState; // Host CPU state before virtualization 113 | volatile VCPU_VMX_STATE VmxState; // CPU virtualization state 114 | ULONG64 SystemDirectoryTableBase; // Kernel CR3 115 | LARGE_INTEGER MsrData[18]; // VMX-specific MSR data 116 | PVMX_VMCS VMXON; // VMXON region 117 | PVMX_VMCS VMCS; // VMCS region 118 | PVOID VMMStack; // Host VMM stack memory 119 | EPT_DATA EPT; // EPT mapping data 120 | ULONG64 OriginalLSTAR; // LSTAR MSR value 121 | ULONG64 TscOffset; // TSC VMM offset value 122 | PAGE_HOOK_STATE HookDispatch; // Page hooking trace state 123 | } VCPU, *PVCPU; 124 | 125 | /// 126 | /// Global data 127 | /// 128 | typedef struct _GLOBAL_DATA 129 | { 130 | CPU_VENDOR CPUVendor; // Intel or AMD 131 | VMX_FEATURES Features; // VMX CPU features 132 | PPHYSICAL_MEMORY_DESCRIPTOR Memory; // Used PFN regions 133 | PUCHAR MSRBitmap; // MSR vmexit bitmap 134 | LONG vcpus; // Number of virtualized CPUs 135 | VCPU cpu_data[ANYSIZE_ARRAY]; // Per-CPU data 136 | } GLOBAL_DATA, *PGLOBAL_DATA; 137 | 138 | extern PGLOBAL_DATA g_Data; 139 | #pragma warning(default: 4214) 140 | 141 | } -------------------------------------------------------------------------------- /kHypervisorBasic/include/capstone/evm.h: -------------------------------------------------------------------------------- 1 | #ifndef CAPSTONE_EVM_H 2 | #define CAPSTONE_EVM_H 3 | 4 | /* Capstone Disassembly Engine */ 5 | /* By Nguyen Anh Quynh , 2013-2018 */ 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include "platform.h" 12 | 13 | #ifdef _MSC_VER 14 | #pragma warning(disable:4201) 15 | #endif 16 | 17 | /// Instruction structure 18 | typedef struct cs_evm { 19 | unsigned char pop; ///< number of items popped from the stack 20 | unsigned char push; ///< number of items pushed into the stack 21 | unsigned int fee; ///< gas fee for the instruction 22 | } cs_evm; 23 | 24 | /// EVM instruction 25 | typedef enum evm_insn { 26 | EVM_INS_STOP = 0, 27 | EVM_INS_ADD = 1, 28 | EVM_INS_MUL = 2, 29 | EVM_INS_SUB = 3, 30 | EVM_INS_DIV = 4, 31 | EVM_INS_SDIV = 5, 32 | EVM_INS_MOD = 6, 33 | EVM_INS_SMOD = 7, 34 | EVM_INS_ADDMOD = 8, 35 | EVM_INS_MULMOD = 9, 36 | EVM_INS_EXP = 10, 37 | EVM_INS_SIGNEXTEND = 11, 38 | EVM_INS_LT = 16, 39 | EVM_INS_GT = 17, 40 | EVM_INS_SLT = 18, 41 | EVM_INS_SGT = 19, 42 | EVM_INS_EQ = 20, 43 | EVM_INS_ISZERO = 21, 44 | EVM_INS_AND = 22, 45 | EVM_INS_OR = 23, 46 | EVM_INS_XOR = 24, 47 | EVM_INS_NOT = 25, 48 | EVM_INS_BYTE = 26, 49 | EVM_INS_SHA3 = 32, 50 | EVM_INS_ADDRESS = 48, 51 | EVM_INS_BALANCE = 49, 52 | EVM_INS_ORIGIN = 50, 53 | EVM_INS_CALLER = 51, 54 | EVM_INS_CALLVALUE = 52, 55 | EVM_INS_CALLDATALOAD = 53, 56 | EVM_INS_CALLDATASIZE = 54, 57 | EVM_INS_CALLDATACOPY = 55, 58 | EVM_INS_CODESIZE = 56, 59 | EVM_INS_CODECOPY = 57, 60 | EVM_INS_GASPRICE = 58, 61 | EVM_INS_EXTCODESIZE = 59, 62 | EVM_INS_EXTCODECOPY = 60, 63 | EVM_INS_RETURNDATASIZE = 61, 64 | EVM_INS_RETURNDATACOPY = 62, 65 | EVM_INS_BLOCKHASH = 64, 66 | EVM_INS_COINBASE = 65, 67 | EVM_INS_TIMESTAMP = 66, 68 | EVM_INS_NUMBER = 67, 69 | EVM_INS_DIFFICULTY = 68, 70 | EVM_INS_GASLIMIT = 69, 71 | EVM_INS_POP = 80, 72 | EVM_INS_MLOAD = 81, 73 | EVM_INS_MSTORE = 82, 74 | EVM_INS_MSTORE8 = 83, 75 | EVM_INS_SLOAD = 84, 76 | EVM_INS_SSTORE = 85, 77 | EVM_INS_JUMP = 86, 78 | EVM_INS_JUMPI = 87, 79 | EVM_INS_PC = 88, 80 | EVM_INS_MSIZE = 89, 81 | EVM_INS_GAS = 90, 82 | EVM_INS_JUMPDEST = 91, 83 | EVM_INS_PUSH1 = 96, 84 | EVM_INS_PUSH2 = 97, 85 | EVM_INS_PUSH3 = 98, 86 | EVM_INS_PUSH4 = 99, 87 | EVM_INS_PUSH5 = 100, 88 | EVM_INS_PUSH6 = 101, 89 | EVM_INS_PUSH7 = 102, 90 | EVM_INS_PUSH8 = 103, 91 | EVM_INS_PUSH9 = 104, 92 | EVM_INS_PUSH10 = 105, 93 | EVM_INS_PUSH11 = 106, 94 | EVM_INS_PUSH12 = 107, 95 | EVM_INS_PUSH13 = 108, 96 | EVM_INS_PUSH14 = 109, 97 | EVM_INS_PUSH15 = 110, 98 | EVM_INS_PUSH16 = 111, 99 | EVM_INS_PUSH17 = 112, 100 | EVM_INS_PUSH18 = 113, 101 | EVM_INS_PUSH19 = 114, 102 | EVM_INS_PUSH20 = 115, 103 | EVM_INS_PUSH21 = 116, 104 | EVM_INS_PUSH22 = 117, 105 | EVM_INS_PUSH23 = 118, 106 | EVM_INS_PUSH24 = 119, 107 | EVM_INS_PUSH25 = 120, 108 | EVM_INS_PUSH26 = 121, 109 | EVM_INS_PUSH27 = 122, 110 | EVM_INS_PUSH28 = 123, 111 | EVM_INS_PUSH29 = 124, 112 | EVM_INS_PUSH30 = 125, 113 | EVM_INS_PUSH31 = 126, 114 | EVM_INS_PUSH32 = 127, 115 | EVM_INS_DUP1 = 128, 116 | EVM_INS_DUP2 = 129, 117 | EVM_INS_DUP3 = 130, 118 | EVM_INS_DUP4 = 131, 119 | EVM_INS_DUP5 = 132, 120 | EVM_INS_DUP6 = 133, 121 | EVM_INS_DUP7 = 134, 122 | EVM_INS_DUP8 = 135, 123 | EVM_INS_DUP9 = 136, 124 | EVM_INS_DUP10 = 137, 125 | EVM_INS_DUP11 = 138, 126 | EVM_INS_DUP12 = 139, 127 | EVM_INS_DUP13 = 140, 128 | EVM_INS_DUP14 = 141, 129 | EVM_INS_DUP15 = 142, 130 | EVM_INS_DUP16 = 143, 131 | EVM_INS_SWAP1 = 144, 132 | EVM_INS_SWAP2 = 145, 133 | EVM_INS_SWAP3 = 146, 134 | EVM_INS_SWAP4 = 147, 135 | EVM_INS_SWAP5 = 148, 136 | EVM_INS_SWAP6 = 149, 137 | EVM_INS_SWAP7 = 150, 138 | EVM_INS_SWAP8 = 151, 139 | EVM_INS_SWAP9 = 152, 140 | EVM_INS_SWAP10 = 153, 141 | EVM_INS_SWAP11 = 154, 142 | EVM_INS_SWAP12 = 155, 143 | EVM_INS_SWAP13 = 156, 144 | EVM_INS_SWAP14 = 157, 145 | EVM_INS_SWAP15 = 158, 146 | EVM_INS_SWAP16 = 159, 147 | EVM_INS_LOG0 = 160, 148 | EVM_INS_LOG1 = 161, 149 | EVM_INS_LOG2 = 162, 150 | EVM_INS_LOG3 = 163, 151 | EVM_INS_LOG4 = 164, 152 | EVM_INS_CREATE = 240, 153 | EVM_INS_CALL = 241, 154 | EVM_INS_CALLCODE = 242, 155 | EVM_INS_RETURN = 243, 156 | EVM_INS_DELEGATECALL = 244, 157 | EVM_INS_CALLBLACKBOX = 245, 158 | EVM_INS_STATICCALL = 250, 159 | EVM_INS_REVERT = 253, 160 | EVM_INS_SUICIDE = 255, 161 | 162 | EVM_INS_INVALID = 512, 163 | EVM_INS_ENDING, // <-- mark the end of the list of instructions 164 | } evm_insn; 165 | 166 | /// Group of EVM instructions 167 | typedef enum evm_insn_group { 168 | EVM_GRP_INVALID = 0, ///< = CS_GRP_INVALID 169 | 170 | EVM_GRP_JUMP, ///< all jump instructions 171 | 172 | EVM_GRP_MATH = 8, ///< math instructions 173 | EVM_GRP_STACK_WRITE, ///< instructions write to stack 174 | EVM_GRP_STACK_READ, ///< instructions read from stack 175 | EVM_GRP_MEM_WRITE, ///< instructions write to memory 176 | EVM_GRP_MEM_READ, ///< instructions read from memory 177 | EVM_GRP_STORE_WRITE, ///< instructions write to storage 178 | EVM_GRP_STORE_READ, ///< instructions read from storage 179 | EVM_GRP_HALT, ///< instructions halt execution 180 | 181 | EVM_GRP_ENDING, ///< <-- mark the end of the list of groups 182 | } evm_insn_group; 183 | 184 | #ifdef __cplusplus 185 | } 186 | #endif 187 | 188 | #endif 189 | -------------------------------------------------------------------------------- /kHypervisorBasic/util_page_constants.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Defines page table related constants 8 | /// 9 | /// This file defines platform dependent constants and is included only from a 10 | /// function where initializes g_utilp_p*e_base, g_utilp_p*i_shift and 11 | /// g_utilp_p*i_mask global variables. 12 | 13 | #ifndef HYPERPLATFORM_UTIL_CONSTANT_H_ 14 | #define HYPERPLATFORM_UTIL_CONSTANT_H_ 15 | 16 | // Virtual Address Interpretation For Handling PTEs 17 | // 18 | // -- On x64 19 | // Sign extension 16 bits 20 | // Page map level 4 selector 9 bits 21 | // Page directory pointer selector 9 bits 22 | // Page directory selector 9 bits 23 | // Page table selector 9 bits 24 | // Byte within page 12 bits 25 | // 11111111 11111111 11111000 10000000 00000011 01010011 00001010 00011000 26 | // ^^^^^^^^ ^^^^^^^^ ~~~~~~~~ ~^^^^^^^ ^^~~~~~~ ~~~^^^^^ ^^^^~~~~ ~~~~~~~~ 27 | // Sign extension PML4 PDPT PD PT Offset 28 | // 29 | // -- On x86(PAE) 30 | // Page directory pointer selector 2 bits 31 | // Page directory selector 9 bits 32 | // Page table selector 9 bits 33 | // Byte within page 12 bits 34 | // 10 000011011 000001101 001001110101 35 | // ^^ ~~~~~~~~~ ^^^^^^^^^ ~~~~~~~~~~~~ 36 | // PDPT PD PT Offset 37 | // 38 | // -- On x86 and ARM 39 | // Page directory selector 10 bits 40 | // Page table selector 10 bits 41 | // Byte within page 12 bits 42 | // 1000001101 1000001101 001001110101 43 | // ~~~~~~~~~~ ^^^^^^^^^^ ~~~~~~~~~~~~ 44 | // PD PT Offset 45 | // 46 | // 47 | // x64 x86(PAE) x86 ARM 48 | // Page map level 4 selector 9 - - - 49 | // Page directory pointer selector 9 2 - - 50 | // Page directory selector 9 9 10 10 51 | // Page table selector 9 9 10 10 52 | // Byte within page 12 12 12 12 53 | // 54 | // 6666555555555544444444443333333333222222222211111111110000000000 55 | // 3210987654321098765432109876543210987654321098765432109876543210 56 | // ---------------------------------------------------------------- 57 | // aaaaaaaaaaaaaaaabbbbbbbbbcccccccccdddddddddeeeeeeeeeffffffffffff x64 58 | // ................................ccdddddddddeeeeeeeeeffffffffffff x86(PAE) 59 | // ................................ddddddddddeeeeeeeeeeffffffffffff x86 60 | // ................................ddddddddddeeeeeeeeeeffffffffffff ARM 61 | // 62 | // a = Sign extension, b = PML4, c = PDPT, d = PD, e = PT, f = Offset 63 | 64 | #if defined(_AMD64_) 65 | 66 | // Base addresses of page structures. Use !pte to obtain them. 67 | static auto kUtilpPxeBase = 0xfffff6fb7dbed000ull; 68 | static auto kUtilpPpeBase = 0xfffff6fb7da00000ull; 69 | static auto kUtilpPdeBase = 0xfffff6fb40000000ull; 70 | static auto kUtilpPteBase = 0xfffff68000000000ull; 71 | 72 | // Get the highest 25 bits 73 | static const auto kUtilpPxiShift = 39ull; 74 | 75 | // Get the highest 34 bits 76 | static const auto kUtilpPpiShift = 30ull; 77 | 78 | // Get the highest 43 bits 79 | static const auto kUtilpPdiShift = 21ull; 80 | 81 | // Get the highest 52 bits 82 | static const auto kUtilpPtiShift = 12ull; 83 | 84 | // Use 9 bits; 0b0000_0000_0000_0000_0000_0000_0001_1111_1111 85 | static const auto kUtilpPxiMask = 0x1ffull; 86 | 87 | // Use 18 bits; 0b0000_0000_0000_0000_0011_1111_1111_1111_1111 88 | static const auto kUtilpPpiMask = 0x3ffffull; 89 | 90 | // Use 27 bits; 0b0000_0000_0111_1111_1111_1111_1111_1111_1111 91 | static const auto kUtilpPdiMask = 0x7ffffffull; 92 | 93 | // Use 36 bits; 0b1111_1111_1111_1111_1111_1111_1111_1111_1111 94 | static const auto kUtilpPtiMask = 0xfffffffffull; 95 | 96 | #elif defined(_X86_) 97 | 98 | // Base addresses of page structures. Use !pte to obtain them. 99 | static auto kUtilpPdeBase = 0xc0300000; 100 | static auto kUtilpPteBase = 0xc0000000; 101 | 102 | // Get the highest 10 bits 103 | static const auto kUtilpPdiShift = 22; 104 | 105 | // Get the highest 20 bits 106 | static const auto kUtilpPtiShift = 12; 107 | 108 | // Use 10 bits; 0b0000_0000_0000_0000_0000_0000_0011_1111_1111 109 | static const auto kUtilpPdiMask = 0x3ff; 110 | 111 | // Use 20 bits; 0b0000_0000_0000_0000_1111_1111_1111_1111_1111 112 | static const auto kUtilpPtiMask = 0xfffff; 113 | 114 | // unused but defined to compile without ifdef 115 | 116 | static auto kUtilpPxeBase = 0; 117 | static auto kUtilpPpeBase = 0; 118 | static const auto kUtilpPxiShift = 0; 119 | static const auto kUtilpPpiShift = 0; 120 | static const auto kUtilpPxiMask = 0; 121 | static const auto kUtilpPpiMask = 0; 122 | 123 | #endif 124 | 125 | // Base addresses of page structures. Use !pte to obtain them. 126 | static const auto kUtilpPdeBasePae = 0xc0600000; 127 | static const auto kUtilpPteBasePae = 0xc0000000; 128 | 129 | // Get the highest 11 bits 130 | static const auto kUtilpPdiShiftPae = 21; 131 | 132 | // Get the highest 20 bits 133 | static const auto kUtilpPtiShiftPae = 12; 134 | 135 | // Use 11 bits; 0b0000_0000_0000_0000_0000_0000_0111_1111_1111 136 | static const auto kUtilpPdiMaskPae = 0x7ff; 137 | 138 | // Use 20 bits; 0b0000_0000_0000_0000_1111_1111_1111_1111_1111 139 | static const auto kUtilpPtiMaskPae = 0xfffff; 140 | 141 | #endif // HYPERPLATFORM_UTIL_H_ 142 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/util_page_constants.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Defines page table related constants 8 | /// 9 | /// This file defines platform dependent constants and is included only from a 10 | /// function where initializes g_utilp_p*e_base, g_utilp_p*i_shift and 11 | /// g_utilp_p*i_mask global variables. 12 | 13 | #ifndef HYPERPLATFORM_UTIL_CONSTANT_H_ 14 | #define HYPERPLATFORM_UTIL_CONSTANT_H_ 15 | 16 | // Virtual Address Interpretation For Handling PTEs 17 | // 18 | // -- On x64 19 | // Sign extension 16 bits 20 | // Page map level 4 selector 9 bits 21 | // Page directory pointer selector 9 bits 22 | // Page directory selector 9 bits 23 | // Page table selector 9 bits 24 | // Byte within page 12 bits 25 | // 11111111 11111111 11111000 10000000 00000011 01010011 00001010 00011000 26 | // ^^^^^^^^ ^^^^^^^^ ~~~~~~~~ ~^^^^^^^ ^^~~~~~~ ~~~^^^^^ ^^^^~~~~ ~~~~~~~~ 27 | // Sign extension PML4 PDPT PD PT Offset 28 | // 29 | // -- On x86(PAE) 30 | // Page directory pointer selector 2 bits 31 | // Page directory selector 9 bits 32 | // Page table selector 9 bits 33 | // Byte within page 12 bits 34 | // 10 000011011 000001101 001001110101 35 | // ^^ ~~~~~~~~~ ^^^^^^^^^ ~~~~~~~~~~~~ 36 | // PDPT PD PT Offset 37 | // 38 | // -- On x86 and ARM 39 | // Page directory selector 10 bits 40 | // Page table selector 10 bits 41 | // Byte within page 12 bits 42 | // 1000001101 1000001101 001001110101 43 | // ~~~~~~~~~~ ^^^^^^^^^^ ~~~~~~~~~~~~ 44 | // PD PT Offset 45 | // 46 | // 47 | // x64 x86(PAE) x86 ARM 48 | // Page map level 4 selector 9 - - - 49 | // Page directory pointer selector 9 2 - - 50 | // Page directory selector 9 9 10 10 51 | // Page table selector 9 9 10 10 52 | // Byte within page 12 12 12 12 53 | // 54 | // 6666555555555544444444443333333333222222222211111111110000000000 55 | // 3210987654321098765432109876543210987654321098765432109876543210 56 | // ---------------------------------------------------------------- 57 | // aaaaaaaaaaaaaaaabbbbbbbbbcccccccccdddddddddeeeeeeeeeffffffffffff x64 58 | // ................................ccdddddddddeeeeeeeeeffffffffffff x86(PAE) 59 | // ................................ddddddddddeeeeeeeeeeffffffffffff x86 60 | // ................................ddddddddddeeeeeeeeeeffffffffffff ARM 61 | // 62 | // a = Sign extension, b = PML4, c = PDPT, d = PD, e = PT, f = Offset 63 | 64 | #if defined(_AMD64_) 65 | 66 | // Base addresses of page structures. Use !pte to obtain them. 67 | static auto kUtilpPxeBase = 0xfffff6fb7dbed000ull; 68 | static auto kUtilpPpeBase = 0xfffff6fb7da00000ull; 69 | static auto kUtilpPdeBase = 0xfffff6fb40000000ull; 70 | static auto kUtilpPteBase = 0xfffff68000000000ull; 71 | 72 | // Get the highest 25 bits 73 | static const auto kUtilpPxiShift = 39ull; 74 | 75 | // Get the highest 34 bits 76 | static const auto kUtilpPpiShift = 30ull; 77 | 78 | // Get the highest 43 bits 79 | static const auto kUtilpPdiShift = 21ull; 80 | 81 | // Get the highest 52 bits 82 | static const auto kUtilpPtiShift = 12ull; 83 | 84 | // Use 9 bits; 0b0000_0000_0000_0000_0000_0000_0001_1111_1111 85 | static const auto kUtilpPxiMask = 0x1ffull; 86 | 87 | // Use 18 bits; 0b0000_0000_0000_0000_0011_1111_1111_1111_1111 88 | static const auto kUtilpPpiMask = 0x3ffffull; 89 | 90 | // Use 27 bits; 0b0000_0000_0111_1111_1111_1111_1111_1111_1111 91 | static const auto kUtilpPdiMask = 0x7ffffffull; 92 | 93 | // Use 36 bits; 0b1111_1111_1111_1111_1111_1111_1111_1111_1111 94 | static const auto kUtilpPtiMask = 0xfffffffffull; 95 | 96 | #elif defined(_X86_) 97 | 98 | // Base addresses of page structures. Use !pte to obtain them. 99 | static auto kUtilpPdeBase = 0xc0300000; 100 | static auto kUtilpPteBase = 0xc0000000; 101 | 102 | // Get the highest 10 bits 103 | static const auto kUtilpPdiShift = 22; 104 | 105 | // Get the highest 20 bits 106 | static const auto kUtilpPtiShift = 12; 107 | 108 | // Use 10 bits; 0b0000_0000_0000_0000_0000_0000_0011_1111_1111 109 | static const auto kUtilpPdiMask = 0x3ff; 110 | 111 | // Use 20 bits; 0b0000_0000_0000_0000_1111_1111_1111_1111_1111 112 | static const auto kUtilpPtiMask = 0xfffff; 113 | 114 | // unused but defined to compile without ifdef 115 | 116 | static auto kUtilpPxeBase = 0; 117 | static auto kUtilpPpeBase = 0; 118 | static const auto kUtilpPxiShift = 0; 119 | static const auto kUtilpPpiShift = 0; 120 | static const auto kUtilpPxiMask = 0; 121 | static const auto kUtilpPpiMask = 0; 122 | 123 | #endif 124 | 125 | // Base addresses of page structures. Use !pte to obtain them. 126 | static const auto kUtilpPdeBasePae = 0xc0600000; 127 | static const auto kUtilpPteBasePae = 0xc0000000; 128 | 129 | // Get the highest 11 bits 130 | static const auto kUtilpPdiShiftPae = 21; 131 | 132 | // Get the highest 20 bits 133 | static const auto kUtilpPtiShiftPae = 12; 134 | 135 | // Use 11 bits; 0b0000_0000_0000_0000_0000_0000_0111_1111_1111 136 | static const auto kUtilpPdiMaskPae = 0x7ff; 137 | 138 | // Use 20 bits; 0b0000_0000_0000_0000_1111_1111_1111_1111_1111 139 | static const auto kUtilpPtiMaskPae = 0xfffff; 140 | 141 | #endif // HYPERPLATFORM_UTIL_H_ 142 | -------------------------------------------------------------------------------- /kHypervisorBasic/kernel_stl.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Implements code to use STL in a driver project 8 | 9 | #include 10 | #undef _HAS_EXCEPTIONS 11 | #define _HAS_EXCEPTIONS 0 12 | 13 | // See common.h for details 14 | #pragma prefast(disable : 30030) 15 | 16 | //////////////////////////////////////////////////////////////////////////////// 17 | // 18 | // macro utilities 19 | // 20 | 21 | //////////////////////////////////////////////////////////////////////////////// 22 | // 23 | // constants and macros 24 | // 25 | 26 | /// A pool tag for this module 27 | static const ULONG kKstlpPoolTag = 'LTSK'; 28 | 29 | //////////////////////////////////////////////////////////////////////////////// 30 | // 31 | // types 32 | // 33 | 34 | //////////////////////////////////////////////////////////////////////////////// 35 | // 36 | // prototypes 37 | // 38 | 39 | //////////////////////////////////////////////////////////////////////////////// 40 | // 41 | // variables 42 | // 43 | 44 | //////////////////////////////////////////////////////////////////////////////// 45 | // 46 | // implementations 47 | // 48 | 49 | // An alternative implementation of a C++ exception handler. Issues a bug check. 50 | DECLSPEC_NORETURN static void KernelStlpRaiseException( 51 | _In_ ULONG bug_check_code) { 52 | KdBreakPoint(); 53 | #pragma warning(push) 54 | #pragma warning(disable : 28159) 55 | KeBugCheck(bug_check_code); 56 | #pragma warning(pop) 57 | } 58 | 59 | DECLSPEC_NORETURN void __cdecl _invalid_parameter_noinfo_noreturn() { 60 | KernelStlpRaiseException(KMODE_EXCEPTION_NOT_HANDLED); 61 | } 62 | 63 | namespace std { 64 | 65 | DECLSPEC_NORETURN void __cdecl _Xbad_alloc() { 66 | KernelStlpRaiseException(KMODE_EXCEPTION_NOT_HANDLED); 67 | } 68 | DECLSPEC_NORETURN void __cdecl _Xinvalid_argument(_In_z_ const char *) { 69 | KernelStlpRaiseException(KMODE_EXCEPTION_NOT_HANDLED); 70 | } 71 | DECLSPEC_NORETURN void __cdecl _Xlength_error(_In_z_ const char *) { 72 | KernelStlpRaiseException(KMODE_EXCEPTION_NOT_HANDLED); 73 | } 74 | DECLSPEC_NORETURN void __cdecl _Xout_of_range(_In_z_ const char *) { 75 | KernelStlpRaiseException(KMODE_EXCEPTION_NOT_HANDLED); 76 | } 77 | DECLSPEC_NORETURN void __cdecl _Xoverflow_error(_In_z_ const char *) { 78 | KernelStlpRaiseException(KMODE_EXCEPTION_NOT_HANDLED); 79 | } 80 | DECLSPEC_NORETURN void __cdecl _Xruntime_error(_In_z_ const char *) { 81 | KernelStlpRaiseException(KMODE_EXCEPTION_NOT_HANDLED); 82 | } 83 | 84 | } // namespace std 85 | 86 | // An alternative implementation of the new operator 87 | _IRQL_requires_max_(DISPATCH_LEVEL) void *__cdecl operator new( 88 | _In_ size_t size) { 89 | if (size == 0) { 90 | size = 1; 91 | } 92 | 93 | const auto p = ExAllocatePoolWithTag(NonPagedPool, size, kKstlpPoolTag); 94 | if (!p) { 95 | KernelStlpRaiseException(MUST_SUCCEED_POOL_EMPTY); 96 | } 97 | return p; 98 | } 99 | 100 | // An alternative implementation of the new operator 101 | _IRQL_requires_max_(DISPATCH_LEVEL) void __cdecl operator delete(_In_ void *p) { 102 | if (p) { 103 | ExFreePoolWithTag(p, kKstlpPoolTag); 104 | } 105 | } 106 | 107 | // An alternative implementation of the new operator 108 | _IRQL_requires_max_(DISPATCH_LEVEL) void __cdecl operator delete( 109 | _In_ void *p, _In_ size_t size) { 110 | UNREFERENCED_PARAMETER(size); 111 | if (p) { 112 | ExFreePoolWithTag(p, kKstlpPoolTag); 113 | } 114 | } 115 | 116 | // An alternative implementation of __stdio_common_vsprintf_s 117 | _Success_(return >= 0) EXTERN_C inline int __cdecl __stdio_common_vsprintf_s( 118 | _In_ unsigned __int64 _Options, _Out_writes_z_(_BufferCount) char *_Buffer, 119 | _In_ size_t _BufferCount, 120 | _In_z_ _Printf_format_string_params_(2) char const *_Format, 121 | _In_opt_ _locale_t _Locale, va_list _ArgList) { 122 | UNREFERENCED_PARAMETER(_Options); 123 | UNREFERENCED_PARAMETER(_Locale); 124 | 125 | // Calls _vsnprintf exported by ntoskrnl 126 | using _vsnprintf_type = int __cdecl(char *, size_t, const char *, va_list); 127 | static _vsnprintf_type *local__vsnprintf = nullptr; 128 | if (!local__vsnprintf) { 129 | UNICODE_STRING proc_name_U = {}; 130 | RtlInitUnicodeString(&proc_name_U, L"_vsnprintf"); 131 | local__vsnprintf = reinterpret_cast<_vsnprintf_type *>( 132 | MmGetSystemRoutineAddress(&proc_name_U)); 133 | } 134 | 135 | return local__vsnprintf(_Buffer, _BufferCount, _Format, _ArgList); 136 | } 137 | 138 | // An alternative implementation of __stdio_common_vswprintf_s 139 | _Success_(return >= 0) _Check_return_opt_ EXTERN_C 140 | inline int __cdecl __stdio_common_vswprintf_s( 141 | _In_ unsigned __int64 _Options, 142 | _Out_writes_z_(_BufferCount) wchar_t *_Buffer, _In_ size_t _BufferCount, 143 | _In_z_ _Printf_format_string_params_(2) wchar_t const *_Format, 144 | _In_opt_ _locale_t _Locale, va_list _ArgList) { 145 | UNREFERENCED_PARAMETER(_Options); 146 | UNREFERENCED_PARAMETER(_Locale); 147 | 148 | // Calls _vsnwprintf exported by ntoskrnl 149 | using _vsnwprintf_type = 150 | int __cdecl(wchar_t *, size_t, const wchar_t *, va_list); 151 | static _vsnwprintf_type *local__vsnwprintf = nullptr; 152 | if (!local__vsnwprintf) { 153 | UNICODE_STRING proc_name_U = {}; 154 | RtlInitUnicodeString(&proc_name_U, L"_vsnwprintf"); 155 | local__vsnwprintf = reinterpret_cast<_vsnwprintf_type *>( 156 | MmGetSystemRoutineAddress(&proc_name_U)); 157 | } 158 | 159 | return local__vsnwprintf(_Buffer, _BufferCount, _Format, _ArgList); 160 | } 161 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/kernel_stl.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Implements code to use STL in a driver project 8 | 9 | #include 10 | #undef _HAS_EXCEPTIONS 11 | #define _HAS_EXCEPTIONS 0 12 | 13 | // See common.h for details 14 | #pragma prefast(disable : 30030) 15 | 16 | //////////////////////////////////////////////////////////////////////////////// 17 | // 18 | // macro utilities 19 | // 20 | 21 | //////////////////////////////////////////////////////////////////////////////// 22 | // 23 | // constants and macros 24 | // 25 | 26 | /// A pool tag for this module 27 | static const ULONG kKstlpPoolTag = 'LTSK'; 28 | 29 | //////////////////////////////////////////////////////////////////////////////// 30 | // 31 | // types 32 | // 33 | 34 | //////////////////////////////////////////////////////////////////////////////// 35 | // 36 | // prototypes 37 | // 38 | 39 | //////////////////////////////////////////////////////////////////////////////// 40 | // 41 | // variables 42 | // 43 | 44 | //////////////////////////////////////////////////////////////////////////////// 45 | // 46 | // implementations 47 | // 48 | 49 | // An alternative implementation of a C++ exception handler. Issues a bug check. 50 | DECLSPEC_NORETURN static void KernelStlpRaiseException( 51 | _In_ ULONG bug_check_code) { 52 | KdBreakPoint(); 53 | #pragma warning(push) 54 | #pragma warning(disable : 28159) 55 | KeBugCheck(bug_check_code); 56 | #pragma warning(pop) 57 | } 58 | 59 | DECLSPEC_NORETURN void __cdecl _invalid_parameter_noinfo_noreturn() { 60 | KernelStlpRaiseException(KMODE_EXCEPTION_NOT_HANDLED); 61 | } 62 | 63 | namespace std { 64 | 65 | DECLSPEC_NORETURN void __cdecl _Xbad_alloc() { 66 | KernelStlpRaiseException(KMODE_EXCEPTION_NOT_HANDLED); 67 | } 68 | DECLSPEC_NORETURN void __cdecl _Xinvalid_argument(_In_z_ const char *) { 69 | KernelStlpRaiseException(KMODE_EXCEPTION_NOT_HANDLED); 70 | } 71 | DECLSPEC_NORETURN void __cdecl _Xlength_error(_In_z_ const char *) { 72 | KernelStlpRaiseException(KMODE_EXCEPTION_NOT_HANDLED); 73 | } 74 | DECLSPEC_NORETURN void __cdecl _Xout_of_range(_In_z_ const char *) { 75 | KernelStlpRaiseException(KMODE_EXCEPTION_NOT_HANDLED); 76 | } 77 | DECLSPEC_NORETURN void __cdecl _Xoverflow_error(_In_z_ const char *) { 78 | KernelStlpRaiseException(KMODE_EXCEPTION_NOT_HANDLED); 79 | } 80 | DECLSPEC_NORETURN void __cdecl _Xruntime_error(_In_z_ const char *) { 81 | KernelStlpRaiseException(KMODE_EXCEPTION_NOT_HANDLED); 82 | } 83 | 84 | } // namespace std 85 | 86 | // An alternative implementation of the new operator 87 | _IRQL_requires_max_(DISPATCH_LEVEL) void *__cdecl operator new( 88 | _In_ size_t size) { 89 | if (size == 0) { 90 | size = 1; 91 | } 92 | 93 | const auto p = ExAllocatePoolWithTag(NonPagedPool, size, kKstlpPoolTag); 94 | if (!p) { 95 | KernelStlpRaiseException(MUST_SUCCEED_POOL_EMPTY); 96 | } 97 | return p; 98 | } 99 | 100 | // An alternative implementation of the new operator 101 | _IRQL_requires_max_(DISPATCH_LEVEL) void __cdecl operator delete(_In_ void *p) { 102 | if (p) { 103 | ExFreePoolWithTag(p, kKstlpPoolTag); 104 | } 105 | } 106 | 107 | // An alternative implementation of the new operator 108 | _IRQL_requires_max_(DISPATCH_LEVEL) void __cdecl operator delete( 109 | _In_ void *p, _In_ size_t size) { 110 | UNREFERENCED_PARAMETER(size); 111 | if (p) { 112 | ExFreePoolWithTag(p, kKstlpPoolTag); 113 | } 114 | } 115 | 116 | // An alternative implementation of __stdio_common_vsprintf_s 117 | _Success_(return >= 0) EXTERN_C inline int __cdecl __stdio_common_vsprintf_s( 118 | _In_ unsigned __int64 _Options, _Out_writes_z_(_BufferCount) char *_Buffer, 119 | _In_ size_t _BufferCount, 120 | _In_z_ _Printf_format_string_params_(2) char const *_Format, 121 | _In_opt_ _locale_t _Locale, va_list _ArgList) { 122 | UNREFERENCED_PARAMETER(_Options); 123 | UNREFERENCED_PARAMETER(_Locale); 124 | 125 | // Calls _vsnprintf exported by ntoskrnl 126 | using _vsnprintf_type = int __cdecl(char *, size_t, const char *, va_list); 127 | static _vsnprintf_type *local__vsnprintf = nullptr; 128 | if (!local__vsnprintf) { 129 | UNICODE_STRING proc_name_U = {}; 130 | RtlInitUnicodeString(&proc_name_U, L"_vsnprintf"); 131 | local__vsnprintf = reinterpret_cast<_vsnprintf_type *>( 132 | MmGetSystemRoutineAddress(&proc_name_U)); 133 | } 134 | 135 | return local__vsnprintf(_Buffer, _BufferCount, _Format, _ArgList); 136 | } 137 | 138 | // An alternative implementation of __stdio_common_vswprintf_s 139 | _Success_(return >= 0) _Check_return_opt_ EXTERN_C 140 | inline int __cdecl __stdio_common_vswprintf_s( 141 | _In_ unsigned __int64 _Options, 142 | _Out_writes_z_(_BufferCount) wchar_t *_Buffer, _In_ size_t _BufferCount, 143 | _In_z_ _Printf_format_string_params_(2) wchar_t const *_Format, 144 | _In_opt_ _locale_t _Locale, va_list _ArgList) { 145 | UNREFERENCED_PARAMETER(_Options); 146 | UNREFERENCED_PARAMETER(_Locale); 147 | 148 | // Calls _vsnwprintf exported by ntoskrnl 149 | using _vsnwprintf_type = 150 | int __cdecl(wchar_t *, size_t, const wchar_t *, va_list); 151 | static _vsnwprintf_type *local__vsnwprintf = nullptr; 152 | if (!local__vsnwprintf) { 153 | UNICODE_STRING proc_name_U = {}; 154 | RtlInitUnicodeString(&proc_name_U, L"_vsnwprintf"); 155 | local__vsnwprintf = reinterpret_cast<_vsnwprintf_type *>( 156 | MmGetSystemRoutineAddress(&proc_name_U)); 157 | } 158 | 159 | return local__vsnwprintf(_Buffer, _BufferCount, _Format, _ArgList); 160 | } 161 | -------------------------------------------------------------------------------- /kHypervisorBasic/common.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Declares and implements common things across the project 8 | 9 | /// @mainpage 10 | /// @section whats About 11 | /// These pages serve as a programmer's reference manual for HyperPlatform and 12 | /// were automatically generated from the source using Doxygen. 13 | /// 14 | /// For compilation and installation of HyperPlatform, see the HyperPlatform 15 | /// project page. For more general information about development using 16 | /// HyperPlatform, see User's Documents in the project page. 17 | /// @li https://github.com/tandasat/HyperPlatform 18 | /// 19 | /// Some of good places to start are the files page that provides a brief 20 | /// description of each files, the DriverEntry() function where is an entry 21 | /// point 22 | /// of HyperPlatform, and the VmmVmExitHandler() function, a high-level entry 23 | /// point of VM-exit handlers. 24 | /// 25 | /// @subsection links External Document 26 | /// This document often refers to the Intel 64 and IA-32 Architectures Software 27 | /// Developer Manuals (Intel SDM). Any descriptions like 28 | /// "See: CONTROL REGISTERS" implies that details are explained in a page or a 29 | /// table titled as "CONTROL REGISTERS" in the Intel SDM. 30 | /// @li 31 | /// http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html 32 | /// 33 | /// @copyright Use of this source code is governed by a MIT-style license that 34 | /// can be found in the LICENSE file. 35 | 36 | #ifndef HYPERPLATFORM_COMMON_H_ 37 | #define HYPERPLATFORM_COMMON_H_ 38 | 39 | #include 40 | 41 | // C30030: Calling a memory allocating function and passing a parameter that 42 | // indicates executable memory 43 | // 44 | // Disable C30030 since POOL_NX_OPTIN + ExInitializeDriverRuntime is in place. 45 | // This warning is false positive and can be seen when Target Platform Version 46 | // equals to 10.0.14393.0. 47 | #pragma prefast(disable : 30030) 48 | 49 | //////////////////////////////////////////////////////////////////////////////// 50 | // 51 | // macro utilities 52 | // 53 | 54 | /// Sets a break point that works only when a debugger is present 55 | #if !defined(HYPERPLATFORM_COMMON_DBG_BREAK) 56 | #define HYPERPLATFORM_COMMON_DBG_BREAK() \ 57 | if (KD_DEBUGGER_NOT_PRESENT) { \ 58 | } else { \ 59 | __debugbreak(); \ 60 | } \ 61 | reinterpret_cast(0) 62 | #endif 63 | 64 | /// Issues a bug check 65 | /// @param hp_bug_check_code Type of a bug 66 | /// @param param1 1st parameter for KeBugCheckEx() 67 | /// @param param2 2nd parameter for KeBugCheckEx() 68 | /// @param param3 3rd parameter for KeBugCheckEx() 69 | #if !defined(HYPERPLATFORM_COMMON_BUG_CHECK) 70 | #define HYPERPLATFORM_COMMON_BUG_CHECK(hp_bug_check_code, param1, param2, \ 71 | param3) \ 72 | HYPERPLATFORM_COMMON_DBG_BREAK(); \ 73 | const HyperPlatformBugCheck code = (hp_bug_check_code); \ 74 | KeBugCheckEx(MANUALLY_INITIATED_CRASH, static_cast(code), (param1), \ 75 | (param2), (param3)) 76 | #endif 77 | 78 | //////////////////////////////////////////////////////////////////////////////// 79 | // 80 | // constants and macros 81 | // 82 | 83 | /// Enable or disable performance monitoring globally 84 | /// 85 | /// Enables #HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE() which measures 86 | /// an elapsed time of the scope when set to non 0. Enabling it introduces 87 | /// negative performance impact. 88 | #define HYPERPLATFORM_PERFORMANCE_ENABLE_PERFCOUNTER 1 89 | 90 | /// A pool tag 91 | static const ULONG kHyperPlatformCommonPoolTag = 'PpyH'; 92 | 93 | //////////////////////////////////////////////////////////////////////////////// 94 | // 95 | // types 96 | // 97 | 98 | /// BugCheck codes for #HYPERPLATFORM_COMMON_BUG_CHECK(). 99 | enum class HyperPlatformBugCheck : ULONG { 100 | kUnspecified, //!< An unspecified bug occurred 101 | kUnexpectedVmExit, //!< An unexpected VM-exit occurred 102 | kTripleFaultVmExit, //!< A triple fault VM-exit occurred 103 | kExhaustedPreallocatedEntries, //!< All pre-allocated entries are used 104 | kCriticalVmxInstructionFailure, //!< VMRESUME or VMXOFF has failed 105 | kEptMisconfigVmExit, //!< EPT misconfiguration VM-exit occurred 106 | kCritialPoolAllocationFailure, //!< Critical pool allocation failed 107 | kUnexpectedVmEptExit, //!< 108 | kUnexpectedVmEptExit2, //!< 109 | kUnexpectedVmEptExit3, //!< 110 | }; 111 | 112 | //////////////////////////////////////////////////////////////////////////////// 113 | // 114 | // prototypes 115 | // 116 | 117 | //////////////////////////////////////////////////////////////////////////////// 118 | // 119 | // variables 120 | // 121 | 122 | //////////////////////////////////////////////////////////////////////////////// 123 | // 124 | // implementations 125 | // 126 | 127 | /// Checks if a system is x64 128 | /// @return true if a system is x64 129 | constexpr bool IsX64() { 130 | #if defined(_AMD64_) 131 | return true; 132 | #else 133 | return false; 134 | #endif 135 | } 136 | 137 | /// Checks if the project is compiled as Release 138 | /// @return true if the project is compiled as Release 139 | constexpr bool IsReleaseBuild() { 140 | #if defined(DBG) 141 | return false; 142 | #else 143 | return true; 144 | #endif 145 | } 146 | 147 | #endif // HYPERPLATFORM_COMMON_H_ 148 | -------------------------------------------------------------------------------- /kHypervisor/HyperPlatform/common.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016, tandasat. All rights reserved. 2 | // Copyright (c) 2016-2017, KelvinChan. All rights reserved. 3 | // Use of this source code is governed by a MIT-style license that can be 4 | // found in the LICENSE file. 5 | 6 | /// @file 7 | /// Declares and implements common things across the project 8 | 9 | /// @mainpage 10 | /// @section whats About 11 | /// These pages serve as a programmer's reference manual for HyperPlatform and 12 | /// were automatically generated from the source using Doxygen. 13 | /// 14 | /// For compilation and installation of HyperPlatform, see the HyperPlatform 15 | /// project page. For more general information about development using 16 | /// HyperPlatform, see User's Documents in the project page. 17 | /// @li https://github.com/tandasat/HyperPlatform 18 | /// 19 | /// Some of good places to start are the files page that provides a brief 20 | /// description of each files, the DriverEntry() function where is an entry 21 | /// point 22 | /// of HyperPlatform, and the VmmVmExitHandler() function, a high-level entry 23 | /// point of VM-exit handlers. 24 | /// 25 | /// @subsection links External Document 26 | /// This document often refers to the Intel 64 and IA-32 Architectures Software 27 | /// Developer Manuals (Intel SDM). Any descriptions like 28 | /// "See: CONTROL REGISTERS" implies that details are explained in a page or a 29 | /// table titled as "CONTROL REGISTERS" in the Intel SDM. 30 | /// @li 31 | /// http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html 32 | /// 33 | /// @copyright Use of this source code is governed by a MIT-style license that 34 | /// can be found in the LICENSE file. 35 | 36 | #ifndef HYPERPLATFORM_COMMON_H_ 37 | #define HYPERPLATFORM_COMMON_H_ 38 | 39 | #include 40 | 41 | // C30030: Calling a memory allocating function and passing a parameter that 42 | // indicates executable memory 43 | // 44 | // Disable C30030 since POOL_NX_OPTIN + ExInitializeDriverRuntime is in place. 45 | // This warning is false positive and can be seen when Target Platform Version 46 | // equals to 10.0.14393.0. 47 | #pragma prefast(disable : 30030) 48 | 49 | //////////////////////////////////////////////////////////////////////////////// 50 | // 51 | // macro utilities 52 | // 53 | 54 | /// Sets a break point that works only when a debugger is present 55 | #if !defined(HYPERPLATFORM_COMMON_DBG_BREAK) 56 | #define HYPERPLATFORM_COMMON_DBG_BREAK() \ 57 | if (KD_DEBUGGER_NOT_PRESENT) { \ 58 | } else { \ 59 | __debugbreak(); \ 60 | } \ 61 | reinterpret_cast(0) 62 | #endif 63 | 64 | /// Issues a bug check 65 | /// @param hp_bug_check_code Type of a bug 66 | /// @param param1 1st parameter for KeBugCheckEx() 67 | /// @param param2 2nd parameter for KeBugCheckEx() 68 | /// @param param3 3rd parameter for KeBugCheckEx() 69 | #if !defined(HYPERPLATFORM_COMMON_BUG_CHECK) 70 | #define HYPERPLATFORM_COMMON_BUG_CHECK(hp_bug_check_code, param1, param2, \ 71 | param3) \ 72 | HYPERPLATFORM_COMMON_DBG_BREAK(); \ 73 | const HyperPlatformBugCheck code = (hp_bug_check_code); \ 74 | KeBugCheckEx(MANUALLY_INITIATED_CRASH, static_cast(code), (param1), \ 75 | (param2), (param3)) 76 | #endif 77 | 78 | //////////////////////////////////////////////////////////////////////////////// 79 | // 80 | // constants and macros 81 | // 82 | 83 | /// Enable or disable performance monitoring globally 84 | /// 85 | /// Enables #HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE() which measures 86 | /// an elapsed time of the scope when set to non 0. Enabling it introduces 87 | /// negative performance impact. 88 | #define HYPERPLATFORM_PERFORMANCE_ENABLE_PERFCOUNTER 1 89 | 90 | /// A pool tag 91 | static const ULONG kHyperPlatformCommonPoolTag = 'PpyH'; 92 | 93 | //////////////////////////////////////////////////////////////////////////////// 94 | // 95 | // types 96 | // 97 | 98 | /// BugCheck codes for #HYPERPLATFORM_COMMON_BUG_CHECK(). 99 | enum class HyperPlatformBugCheck : ULONG { 100 | kUnspecified, //!< An unspecified bug occurred 101 | kUnexpectedVmExit, //!< An unexpected VM-exit occurred 102 | kTripleFaultVmExit, //!< A triple fault VM-exit occurred 103 | kExhaustedPreallocatedEntries, //!< All pre-allocated entries are used 104 | kCriticalVmxInstructionFailure, //!< VMRESUME or VMXOFF has failed 105 | kEptMisconfigVmExit, //!< EPT misconfiguration VM-exit occurred 106 | kCritialPoolAllocationFailure, //!< Critical pool allocation failed 107 | kUnexpectedVmEptExit, //!< 108 | kUnexpectedVmEptExit2, //!< 109 | kUnexpectedVmEptExit3, //!< 110 | }; 111 | 112 | //////////////////////////////////////////////////////////////////////////////// 113 | // 114 | // prototypes 115 | // 116 | 117 | //////////////////////////////////////////////////////////////////////////////// 118 | // 119 | // variables 120 | // 121 | 122 | //////////////////////////////////////////////////////////////////////////////// 123 | // 124 | // implementations 125 | // 126 | 127 | /// Checks if a system is x64 128 | /// @return true if a system is x64 129 | constexpr bool IsX64() { 130 | #if defined(_AMD64_) 131 | return true; 132 | #else 133 | return false; 134 | #endif 135 | } 136 | 137 | /// Checks if the project is compiled as Release 138 | /// @return true if the project is compiled as Release 139 | constexpr bool IsReleaseBuild() { 140 | #if defined(DBG) 141 | return false; 142 | #else 143 | return true; 144 | #endif 145 | } 146 | 147 | #endif // HYPERPLATFORM_COMMON_H_ 148 | -------------------------------------------------------------------------------- /kHypervisor/kHypervisor/list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2004-2020 Sandboxie Holdings, LLC 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | //--------------------------------------------------------------------------- 19 | // Double-linked List 20 | //--------------------------------------------------------------------------- 21 | 22 | #include "list.h" 23 | 24 | #ifndef NULL 25 | #define NULL (void *)0 26 | #endif 27 | 28 | //--------------------------------------------------------------------------- 29 | // List_Init 30 | //--------------------------------------------------------------------------- 31 | 32 | #ifdef LIST_WITH_MEMORY_MANAGEMENT 33 | void List_Init(LIST *list) 34 | { 35 | list->head = NULL; 36 | list->tail = NULL; 37 | list->count = 0; 38 | #ifdef LIST_WITH_MEMORY_MANAGEMENT 39 | list->pool = pool; 40 | list->elem_len = elemlen; 41 | #endif 42 | } 43 | #endif 44 | 45 | //--------------------------------------------------------------------------- 46 | // List_Insert_Before 47 | //--------------------------------------------------------------------------- 48 | 49 | void List_Insert_Before(LIST *list, void *oldelem, void *newelem) 50 | { 51 | LIST_ELEM *prev, *curr, *next, *nelm; 52 | 53 | curr = (LIST_ELEM *)oldelem; 54 | nelm = (LIST_ELEM *)newelem; 55 | ++list->count; 56 | 57 | if (curr == list->head || curr == NULL) { /* Insert head elem */ 58 | next = list->head; 59 | list->head = nelm; 60 | nelm->prev = NULL; 61 | nelm->next = next; 62 | if (next == NULL) /* Old head is NULL? */ 63 | list->tail = nelm; 64 | else 65 | next->prev = nelm; 66 | 67 | } else { /* Insert non-head elem */ 68 | prev = curr->prev; 69 | prev->next = nelm; 70 | nelm->prev = prev; 71 | curr->prev = nelm; 72 | nelm->next = curr; 73 | } 74 | } 75 | 76 | //--------------------------------------------------------------------------- 77 | // List_Insert_After 78 | //--------------------------------------------------------------------------- 79 | 80 | void List_Insert_After(LIST *list, void *elem, void *newelem) 81 | { 82 | LIST_ELEM *prev, *curr, *next, *nelm; 83 | 84 | curr = (LIST_ELEM *)elem; 85 | nelm = (LIST_ELEM *)newelem; 86 | ++list->count; 87 | 88 | if (curr == list->tail || curr == NULL) { /* Insert tail elem */ 89 | prev = list->tail; 90 | list->tail = nelm; 91 | nelm->prev = prev; 92 | nelm->next = NULL; 93 | if (prev == NULL) /* Old tail is NULL? */ 94 | list->head = nelm; 95 | else 96 | prev->next = nelm; 97 | 98 | } else { /* Insert non-tail elem */ 99 | next = curr->next; 100 | next->prev = nelm; 101 | nelm->next = next; 102 | curr->next = nelm; 103 | nelm->prev = curr; 104 | } 105 | } 106 | 107 | //--------------------------------------------------------------------------- 108 | // List_Remove 109 | //--------------------------------------------------------------------------- 110 | 111 | void List_Remove(LIST *list, void *elem) 112 | { 113 | LIST_ELEM *prev, *curr, *next; 114 | 115 | curr = (LIST_ELEM *)elem; 116 | prev = curr->prev; 117 | next = curr->next; 118 | --list->count; 119 | 120 | if (prev == NULL && next == NULL) { /* Last elem in list? */ 121 | list->tail = NULL; 122 | list->head = NULL; 123 | 124 | } else if (prev == NULL) { /* Elem is head? */ 125 | list->head = next; 126 | next->prev = NULL; 127 | 128 | } else if (next == NULL) { /* Elem is tail? */ 129 | list->tail = prev; 130 | prev->next = NULL; 131 | 132 | } else { 133 | prev->next = next; /* Elem is non-head, non-tail */ 134 | next->prev = prev; 135 | } 136 | } 137 | 138 | #ifdef LIST_WITH_MEMORY_MANAGEMENT 139 | 140 | //--------------------------------------------------------------------------- 141 | // List_Insert_New_Before 142 | //--------------------------------------------------------------------------- 143 | 144 | void List_Insert_New_Before(LIST *list, void *oldelem) 145 | { 146 | LIST_ELEM *newelem = Pool_Get_Bytes(list->pool, list->elem_len); 147 | return List_Insert_Before(list, oldelem, newelem); 148 | } 149 | 150 | //--------------------------------------------------------------------------- 151 | // List_Insert_New_After 152 | //--------------------------------------------------------------------------- 153 | 154 | void List_Insert_New_After(LIST *list, void *oldelem) 155 | { 156 | LIST_ELEM *newelem = Pool_Get_Bytes(list->pool, list->elem_len); 157 | return List_Insert_After(list, oldelem, newelem); 158 | } 159 | 160 | //--------------------------------------------------------------------------- 161 | // List_Delete 162 | //--------------------------------------------------------------------------- 163 | 164 | void List_Delete(LIST *list, void *elem) 165 | { 166 | List_Remove(list, elem); 167 | Pool_Free_Bytes(elem, list->elem_len); 168 | } 169 | 170 | #endif 171 | -------------------------------------------------------------------------------- /kHypervisorBasic/include/capstone/xcore.h: -------------------------------------------------------------------------------- 1 | #ifndef CAPSTONE_XCORE_H 2 | #define CAPSTONE_XCORE_H 3 | 4 | /* Capstone Disassembly Engine */ 5 | /* By Nguyen Anh Quynh , 2014-2015 */ 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include "platform.h" 12 | 13 | #ifdef _MSC_VER 14 | #pragma warning(disable:4201) 15 | #endif 16 | 17 | /// Operand type for instruction's operands 18 | typedef enum xcore_op_type { 19 | XCORE_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized). 20 | XCORE_OP_REG, ///< = CS_OP_REG (Register operand). 21 | XCORE_OP_IMM, ///< = CS_OP_IMM (Immediate operand). 22 | XCORE_OP_MEM, ///< = CS_OP_MEM (Memory operand). 23 | } xcore_op_type; 24 | 25 | /// XCore registers 26 | typedef enum xcore_reg { 27 | XCORE_REG_INVALID = 0, 28 | 29 | XCORE_REG_CP, 30 | XCORE_REG_DP, 31 | XCORE_REG_LR, 32 | XCORE_REG_SP, 33 | XCORE_REG_R0, 34 | XCORE_REG_R1, 35 | XCORE_REG_R2, 36 | XCORE_REG_R3, 37 | XCORE_REG_R4, 38 | XCORE_REG_R5, 39 | XCORE_REG_R6, 40 | XCORE_REG_R7, 41 | XCORE_REG_R8, 42 | XCORE_REG_R9, 43 | XCORE_REG_R10, 44 | XCORE_REG_R11, 45 | 46 | // pseudo registers 47 | XCORE_REG_PC, ///< pc 48 | 49 | // internal thread registers 50 | // see The-XMOS-XS1-Architecture(X7879A).pdf 51 | XCORE_REG_SCP, ///< save pc 52 | XCORE_REG_SSR, //< save status 53 | XCORE_REG_ET, //< exception type 54 | XCORE_REG_ED, //< exception data 55 | XCORE_REG_SED, //< save exception data 56 | XCORE_REG_KEP, //< kernel entry pointer 57 | XCORE_REG_KSP, //< kernel stack pointer 58 | XCORE_REG_ID, //< thread ID 59 | 60 | XCORE_REG_ENDING, // <-- mark the end of the list of registers 61 | } xcore_reg; 62 | 63 | /// Instruction's operand referring to memory 64 | /// This is associated with XCORE_OP_MEM operand type above 65 | typedef struct xcore_op_mem { 66 | uint8_t base; ///< base register, can be safely interpreted as 67 | ///< a value of type `xcore_reg`, but it is only 68 | ///< one byte wide 69 | uint8_t index; ///< index register, same conditions apply here 70 | int32_t disp; ///< displacement/offset value 71 | int direct; ///< +1: forward, -1: backward 72 | } xcore_op_mem; 73 | 74 | /// Instruction operand 75 | typedef struct cs_xcore_op { 76 | xcore_op_type type; ///< operand type 77 | union { 78 | xcore_reg reg; ///< register value for REG operand 79 | int32_t imm; ///< immediate value for IMM operand 80 | xcore_op_mem mem; ///< base/disp value for MEM operand 81 | }; 82 | } cs_xcore_op; 83 | 84 | /// Instruction structure 85 | typedef struct cs_xcore { 86 | /// Number of operands of this instruction, 87 | /// or 0 when instruction has no operand. 88 | uint8_t op_count; 89 | cs_xcore_op operands[8]; ///< operands for this instruction. 90 | } cs_xcore; 91 | 92 | /// XCore instruction 93 | typedef enum xcore_insn { 94 | XCORE_INS_INVALID = 0, 95 | 96 | XCORE_INS_ADD, 97 | XCORE_INS_ANDNOT, 98 | XCORE_INS_AND, 99 | XCORE_INS_ASHR, 100 | XCORE_INS_BAU, 101 | XCORE_INS_BITREV, 102 | XCORE_INS_BLA, 103 | XCORE_INS_BLAT, 104 | XCORE_INS_BL, 105 | XCORE_INS_BF, 106 | XCORE_INS_BT, 107 | XCORE_INS_BU, 108 | XCORE_INS_BRU, 109 | XCORE_INS_BYTEREV, 110 | XCORE_INS_CHKCT, 111 | XCORE_INS_CLRE, 112 | XCORE_INS_CLRPT, 113 | XCORE_INS_CLRSR, 114 | XCORE_INS_CLZ, 115 | XCORE_INS_CRC8, 116 | XCORE_INS_CRC32, 117 | XCORE_INS_DCALL, 118 | XCORE_INS_DENTSP, 119 | XCORE_INS_DGETREG, 120 | XCORE_INS_DIVS, 121 | XCORE_INS_DIVU, 122 | XCORE_INS_DRESTSP, 123 | XCORE_INS_DRET, 124 | XCORE_INS_ECALLF, 125 | XCORE_INS_ECALLT, 126 | XCORE_INS_EDU, 127 | XCORE_INS_EEF, 128 | XCORE_INS_EET, 129 | XCORE_INS_EEU, 130 | XCORE_INS_ENDIN, 131 | XCORE_INS_ENTSP, 132 | XCORE_INS_EQ, 133 | XCORE_INS_EXTDP, 134 | XCORE_INS_EXTSP, 135 | XCORE_INS_FREER, 136 | XCORE_INS_FREET, 137 | XCORE_INS_GETD, 138 | XCORE_INS_GET, 139 | XCORE_INS_GETN, 140 | XCORE_INS_GETR, 141 | XCORE_INS_GETSR, 142 | XCORE_INS_GETST, 143 | XCORE_INS_GETTS, 144 | XCORE_INS_INCT, 145 | XCORE_INS_INIT, 146 | XCORE_INS_INPW, 147 | XCORE_INS_INSHR, 148 | XCORE_INS_INT, 149 | XCORE_INS_IN, 150 | XCORE_INS_KCALL, 151 | XCORE_INS_KENTSP, 152 | XCORE_INS_KRESTSP, 153 | XCORE_INS_KRET, 154 | XCORE_INS_LADD, 155 | XCORE_INS_LD16S, 156 | XCORE_INS_LD8U, 157 | XCORE_INS_LDA16, 158 | XCORE_INS_LDAP, 159 | XCORE_INS_LDAW, 160 | XCORE_INS_LDC, 161 | XCORE_INS_LDW, 162 | XCORE_INS_LDIVU, 163 | XCORE_INS_LMUL, 164 | XCORE_INS_LSS, 165 | XCORE_INS_LSUB, 166 | XCORE_INS_LSU, 167 | XCORE_INS_MACCS, 168 | XCORE_INS_MACCU, 169 | XCORE_INS_MJOIN, 170 | XCORE_INS_MKMSK, 171 | XCORE_INS_MSYNC, 172 | XCORE_INS_MUL, 173 | XCORE_INS_NEG, 174 | XCORE_INS_NOT, 175 | XCORE_INS_OR, 176 | XCORE_INS_OUTCT, 177 | XCORE_INS_OUTPW, 178 | XCORE_INS_OUTSHR, 179 | XCORE_INS_OUTT, 180 | XCORE_INS_OUT, 181 | XCORE_INS_PEEK, 182 | XCORE_INS_REMS, 183 | XCORE_INS_REMU, 184 | XCORE_INS_RETSP, 185 | XCORE_INS_SETCLK, 186 | XCORE_INS_SET, 187 | XCORE_INS_SETC, 188 | XCORE_INS_SETD, 189 | XCORE_INS_SETEV, 190 | XCORE_INS_SETN, 191 | XCORE_INS_SETPSC, 192 | XCORE_INS_SETPT, 193 | XCORE_INS_SETRDY, 194 | XCORE_INS_SETSR, 195 | XCORE_INS_SETTW, 196 | XCORE_INS_SETV, 197 | XCORE_INS_SEXT, 198 | XCORE_INS_SHL, 199 | XCORE_INS_SHR, 200 | XCORE_INS_SSYNC, 201 | XCORE_INS_ST16, 202 | XCORE_INS_ST8, 203 | XCORE_INS_STW, 204 | XCORE_INS_SUB, 205 | XCORE_INS_SYNCR, 206 | XCORE_INS_TESTCT, 207 | XCORE_INS_TESTLCL, 208 | XCORE_INS_TESTWCT, 209 | XCORE_INS_TSETMR, 210 | XCORE_INS_START, 211 | XCORE_INS_WAITEF, 212 | XCORE_INS_WAITET, 213 | XCORE_INS_WAITEU, 214 | XCORE_INS_XOR, 215 | XCORE_INS_ZEXT, 216 | 217 | XCORE_INS_ENDING, // <-- mark the end of the list of instructions 218 | } xcore_insn; 219 | 220 | /// Group of XCore instructions 221 | typedef enum xcore_insn_group { 222 | XCORE_GRP_INVALID = 0, ///< = CS_GRP_INVALID 223 | 224 | // Generic groups 225 | // all jump instructions (conditional+direct+indirect jumps) 226 | XCORE_GRP_JUMP, ///< = CS_GRP_JUMP 227 | 228 | XCORE_GRP_ENDING, // <-- mark the end of the list of groups 229 | } xcore_insn_group; 230 | 231 | #ifdef __cplusplus 232 | } 233 | #endif 234 | 235 | #endif 236 | --------------------------------------------------------------------------------