├── README.md
├── HypervisorCheckR0
├── HypervisorCheckR0.vcxproj.user
├── Struct.h
├── DriverEntry.cpp
├── HypervisorCheckR0.vcxproj.filters
├── HypervisorCheckR0.inf
├── HypervisorDetect.hpp
└── HypervisorCheckR0.vcxproj
├── LICENSE
└── HypervisorCheckR0.sln
/README.md:
--------------------------------------------------------------------------------
1 | # Hypervisor_detect_ring_0
2 | Check hypervisor in ring 0
3 | Some check in hypervisor.Code based on Secret Club articles (How anti-cheat detect system emulation)
4 | Code was written for manual map driver
5 |
--------------------------------------------------------------------------------
/HypervisorCheckR0/HypervisorCheckR0.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/HypervisorCheckR0/Struct.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #define IA32_P5_MC_ADDR_MSR 0x00000000
11 | #define DEBUGCTL_LBR 0x01
12 | #define DEBUGCTL_BTF 0x02
13 | #define IA32_TIME_STAMP_COUNTER 0x00000010
14 | #define SMI_COUNT_MSR 0x00000034
15 | #define IA32_MPERF_MSR 0x000000E7
16 | #define IA32_APERF_MSR 0x000000E8
17 | #define MSR_P6M_LBSTK_TOS 0x1c9
18 | #define MSR_DEBUGCTL 0x1d9
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/HypervisorCheckR0/DriverEntry.cpp:
--------------------------------------------------------------------------------
1 | #include "HypervisorDetect.hpp"
2 |
3 |
4 |
5 | NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
6 | {
7 | UNREFERENCED_PARAMETER(pRegistryPath);
8 |
9 |
10 |
11 | DbgPrint("[Bad lev1oto] Cpuid is hypervisor ->\t 0x%p\n", DetectHyp::cpuid_is_hypervisor());
12 | DbgPrint("[Bad lev1oto] Compare cpuid list ->\t 0x%p\n", DetectHyp::compare_list_cpuid());
13 | DbgPrint("[Bad lev1oto] Time attack with rdtsc ->\t 0x%p\n", DetectHyp::time_attack_rdtsc());
14 | DbgPrint("[Bad lev1oto] Time attack with APERF ->\t 0x%p\n", DetectHyp::time_attack_APERF());
15 | DbgPrint("[Bad lev1oto] Time attack with MPERF->\t 0x%p\n", DetectHyp::time_attack_MPERF());
16 | DbgPrint("[Bad lev1oto] LBR is virtualizate ->\t 0x%p\n", DetectHyp::lbr_is_virtulazed());
17 | DbgPrint("[Bad lev1oto] LBR stack check ->\t 0x%p\n", DetectHyp::lbr_stask_is_virtulazed());
18 |
19 | return STATUS_SUCCESS;
20 | }
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Ahora57
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/HypervisorCheckR0/HypervisorCheckR0.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 | {99a54c3d-b1a4-4d0e-bb2c-feb38413f6d1}
22 |
23 |
24 |
25 |
26 | Driver Files
27 |
28 |
29 |
30 |
31 | Driver Files
32 |
33 |
34 |
35 |
36 | Header Files
37 |
38 |
39 | HypDetect
40 |
41 |
42 | Header Files
43 |
44 |
45 |
--------------------------------------------------------------------------------
/HypervisorCheckR0.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31624.102
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HypervisorCheckR0", "HypervisorCheckR0\HypervisorCheckR0.vcxproj", "{164DF69B-E119-41A4-A578-49663695145F}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|ARM = Debug|ARM
11 | Debug|ARM64 = Debug|ARM64
12 | Debug|x64 = Debug|x64
13 | Debug|x86 = Debug|x86
14 | Release|ARM = Release|ARM
15 | Release|ARM64 = Release|ARM64
16 | Release|x64 = Release|x64
17 | Release|x86 = Release|x86
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {164DF69B-E119-41A4-A578-49663695145F}.Debug|ARM.ActiveCfg = Debug|ARM
21 | {164DF69B-E119-41A4-A578-49663695145F}.Debug|ARM.Build.0 = Debug|ARM
22 | {164DF69B-E119-41A4-A578-49663695145F}.Debug|ARM.Deploy.0 = Debug|ARM
23 | {164DF69B-E119-41A4-A578-49663695145F}.Debug|ARM64.ActiveCfg = Debug|ARM64
24 | {164DF69B-E119-41A4-A578-49663695145F}.Debug|ARM64.Build.0 = Debug|ARM64
25 | {164DF69B-E119-41A4-A578-49663695145F}.Debug|ARM64.Deploy.0 = Debug|ARM64
26 | {164DF69B-E119-41A4-A578-49663695145F}.Debug|x64.ActiveCfg = Debug|x64
27 | {164DF69B-E119-41A4-A578-49663695145F}.Debug|x64.Build.0 = Debug|x64
28 | {164DF69B-E119-41A4-A578-49663695145F}.Debug|x64.Deploy.0 = Debug|x64
29 | {164DF69B-E119-41A4-A578-49663695145F}.Debug|x86.ActiveCfg = Debug|Win32
30 | {164DF69B-E119-41A4-A578-49663695145F}.Debug|x86.Build.0 = Debug|Win32
31 | {164DF69B-E119-41A4-A578-49663695145F}.Debug|x86.Deploy.0 = Debug|Win32
32 | {164DF69B-E119-41A4-A578-49663695145F}.Release|ARM.ActiveCfg = Release|ARM
33 | {164DF69B-E119-41A4-A578-49663695145F}.Release|ARM.Build.0 = Release|ARM
34 | {164DF69B-E119-41A4-A578-49663695145F}.Release|ARM.Deploy.0 = Release|ARM
35 | {164DF69B-E119-41A4-A578-49663695145F}.Release|ARM64.ActiveCfg = Release|ARM64
36 | {164DF69B-E119-41A4-A578-49663695145F}.Release|ARM64.Build.0 = Release|ARM64
37 | {164DF69B-E119-41A4-A578-49663695145F}.Release|ARM64.Deploy.0 = Release|ARM64
38 | {164DF69B-E119-41A4-A578-49663695145F}.Release|x64.ActiveCfg = Release|x64
39 | {164DF69B-E119-41A4-A578-49663695145F}.Release|x64.Build.0 = Release|x64
40 | {164DF69B-E119-41A4-A578-49663695145F}.Release|x64.Deploy.0 = Release|x64
41 | {164DF69B-E119-41A4-A578-49663695145F}.Release|x86.ActiveCfg = Release|Win32
42 | {164DF69B-E119-41A4-A578-49663695145F}.Release|x86.Build.0 = Release|Win32
43 | {164DF69B-E119-41A4-A578-49663695145F}.Release|x86.Deploy.0 = Release|Win32
44 | EndGlobalSection
45 | GlobalSection(SolutionProperties) = preSolution
46 | HideSolutionNode = FALSE
47 | EndGlobalSection
48 | GlobalSection(ExtensibilityGlobals) = postSolution
49 | SolutionGuid = {1E147BB8-3C81-4B3F-BD61-ABDDD68854F7}
50 | EndGlobalSection
51 | EndGlobal
52 |
--------------------------------------------------------------------------------
/HypervisorCheckR0/HypervisorCheckR0.inf:
--------------------------------------------------------------------------------
1 | ;
2 | ; HypervisorCheckR0.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=HypervisorCheckR0.cat
11 | DriverVer= ; TODO: set DriverVer in stampinf property pages
12 | PnpLockDown=1
13 |
14 | [DestinationDirs]
15 | DefaultDestDir = 12
16 | HypervisorCheckR0_Device_CoInstaller_CopyFiles = 11
17 |
18 | ; ================= Class section =====================
19 |
20 | [ClassInstall32]
21 | Addreg=SampleClassReg
22 |
23 | [SampleClassReg]
24 | HKR,,,0,%ClassName%
25 | HKR,,Icon,,-5
26 |
27 | [SourceDisksNames]
28 | 1 = %DiskName%,,,""
29 |
30 | [SourceDisksFiles]
31 | HypervisorCheckR0.sys = 1,,
32 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames
33 |
34 | ;*****************************************
35 | ; Install Section
36 | ;*****************************************
37 |
38 | [Manufacturer]
39 | %ManufacturerName%=Standard,NT$ARCH$
40 |
41 | [Standard.NT$ARCH$]
42 | %HypervisorCheckR0.DeviceDesc%=HypervisorCheckR0_Device, Root\HypervisorCheckR0 ; TODO: edit hw-id
43 |
44 | [HypervisorCheckR0_Device.NT]
45 | CopyFiles=Drivers_Dir
46 |
47 | [Drivers_Dir]
48 | HypervisorCheckR0.sys
49 |
50 | ;-------------- Service installation
51 | [HypervisorCheckR0_Device.NT.Services]
52 | AddService = HypervisorCheckR0,%SPSVCINST_ASSOCSERVICE%, HypervisorCheckR0_Service_Inst
53 |
54 | ; -------------- HypervisorCheckR0 driver install sections
55 | [HypervisorCheckR0_Service_Inst]
56 | DisplayName = %HypervisorCheckR0.SVCDESC%
57 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER
58 | StartType = 3 ; SERVICE_DEMAND_START
59 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL
60 | ServiceBinary = %12%\HypervisorCheckR0.sys
61 |
62 | ;
63 | ;--- HypervisorCheckR0_Device Coinstaller installation ------
64 | ;
65 |
66 | [HypervisorCheckR0_Device.NT.CoInstallers]
67 | AddReg=HypervisorCheckR0_Device_CoInstaller_AddReg
68 | CopyFiles=HypervisorCheckR0_Device_CoInstaller_CopyFiles
69 |
70 | [HypervisorCheckR0_Device_CoInstaller_AddReg]
71 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"
72 |
73 | [HypervisorCheckR0_Device_CoInstaller_CopyFiles]
74 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll
75 |
76 | [HypervisorCheckR0_Device.NT.Wdf]
77 | KmdfService = HypervisorCheckR0, HypervisorCheckR0_wdfsect
78 | [HypervisorCheckR0_wdfsect]
79 | KmdfLibraryVersion = $KMDFVERSION$
80 |
81 | [Strings]
82 | SPSVCINST_ASSOCSERVICE= 0x00000002
83 | ManufacturerName="" ;TODO: Replace with your manufacturer name
84 | ClassName="Samples" ; TODO: edit ClassName
85 | DiskName = "HypervisorCheckR0 Installation Disk"
86 | HypervisorCheckR0.DeviceDesc = "HypervisorCheckR0 Device"
87 | HypervisorCheckR0.SVCDESC = "HypervisorCheckR0 Service"
88 |
--------------------------------------------------------------------------------
/HypervisorCheckR0/HypervisorDetect.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Struct.h"
3 |
4 |
5 | /*
6 | We can't use SEH for manual map driver's
7 |
8 | */
9 |
10 | namespace DetectHyp
11 | {
12 | bool ProcIsIntel()
13 | {
14 | int cpuid[4]{ -1 };
15 | __cpuid(cpuid, 0);
16 | if (cpuid[2] == 'letn')
17 | {
18 | return TRUE;
19 | }
20 | return FALSE;
21 | }
22 |
23 | bool compare_list_cpuid()
24 | {
25 | //compare cpuid list
26 | int invalid_cpuid_list[4] = { -1 };
27 | int valid_cpuid_list[4] = { -1 };
28 |
29 | __cpuid(invalid_cpuid_list, 0x13371337);
30 | __cpuid(valid_cpuid_list, 0x40000000);
31 |
32 | if ((invalid_cpuid_list[0] != valid_cpuid_list[0]) ||
33 | (invalid_cpuid_list[1] != valid_cpuid_list[1]) ||
34 | (invalid_cpuid_list[2] != valid_cpuid_list[2]) ||
35 | (invalid_cpuid_list[3] != valid_cpuid_list[3]))
36 | return TRUE;
37 |
38 | return FALSE;
39 |
40 |
41 |
42 | }
43 |
44 | bool cpuid_is_hypervisor()
45 | {
46 | int cpuid[4] = { 0 };
47 | __cpuid(cpuid, 1);
48 | return ((cpuid[2] >> 31) & 1);
49 | }
50 |
51 |
52 |
53 | bool time_attack_rdtsc()
54 | {
55 | uint64_t avg = 0;
56 | int cpuInfo[4] = {};
57 | for (int i = 0; i < 2500; i++)
58 | {
59 |
60 | auto currentIrql = __readcr8();
61 | __writecr8(HIGH_LEVEL);
62 |
63 | _disable();
64 | auto tick1 = __readmsr(IA32_TIME_STAMP_COUNTER);
65 | __cpuid(cpuInfo, 0);// vm-exit
66 | auto tick2 = __readmsr(IA32_TIME_STAMP_COUNTER);
67 | _enable();
68 |
69 | __writecr8(currentIrql);
70 |
71 | avg += (tick2 - tick1);
72 | }
73 | avg /= 2500;
74 | return (avg > 500) || (25 > avg) ;
75 | }
76 |
77 |
78 |
79 |
80 |
81 | bool time_attack_MPERF()
82 | {
83 | // Some hypervisor just return 0(like:VMware)
84 |
85 | int cpuid[4]{ -1 };
86 | uint64_t avg{ 0 };
87 | for (int i = 0; i < 100; i++)
88 | {
89 | auto currentIrql = __readcr8();
90 | __writecr8(HIGH_LEVEL);
91 |
92 | _disable();
93 | auto tick1 = __readmsr(IA32_MPERF_MSR);
94 | __cpuid(cpuid, 0);//call vm-exit
95 | auto tick2 = __readmsr(IA32_MPERF_MSR);
96 | _enable();
97 |
98 | __writecr8(currentIrql);
99 |
100 | if ( (!tick1 && !tick2 ) || (tick1 == tick2))
101 | {
102 | return true;
103 | }
104 |
105 | avg += (tick2 - tick1);
106 | }
107 | avg /= 100;
108 | return (0x4ff < avg) || (0xc > avg);
109 | }
110 |
111 |
112 |
113 | bool time_attack_APERF()
114 | {
115 | uint64_t avg{ 0 };
116 | int data[4]{ -1 };
117 | for (size_t i = 0; i < 100; i++)
118 | {
119 | auto currentIrql = __readcr8();
120 | __writecr8(HIGH_LEVEL);
121 |
122 |
123 | _disable();
124 | auto tick1 = __readmsr(IA32_APERF_MSR);
125 | __cpuid(data, 0); //call vm-exit
126 | auto tick2 = __readmsr(IA32_APERF_MSR);
127 | _enable();
128 |
129 | __writecr8(currentIrql);
130 |
131 | if ( (!tick1 && !tick2) || (tick1 == tick2))
132 | {
133 | return true;
134 | }
135 | avg += (tick2 - tick1);
136 | }
137 | avg /= 100;
138 | return (0x4ff < avg) || (0x33 > avg);
139 | }
140 |
141 | bool lbr_is_virtulazed()
142 | {
143 | if (ProcIsIntel())
144 | {
145 | auto current_value = __readmsr(MSR_DEBUGCTL);//safe current value
146 | __writemsr(MSR_DEBUGCTL, DEBUGCTL_LBR | DEBUGCTL_BTF);
147 | auto whatch_write = __readmsr(MSR_DEBUGCTL);
148 | __writemsr(MSR_DEBUGCTL, current_value);
149 | return (!(whatch_write & DEBUGCTL_LBR));
150 | }
151 | return FALSE;
152 | }
153 |
154 | bool lbr_stask_is_virtulazed()
155 | {
156 | int cpuid[4]{ -1 };
157 | auto currentLBR = __readmsr(MSR_P6M_LBSTK_TOS);
158 | __cpuid(cpuid, 0);//call vm-exit
159 | auto exitLBR = __readmsr(MSR_P6M_LBSTK_TOS);
160 | return currentLBR != exitLBR;
161 |
162 | }
163 |
164 |
165 |
166 |
167 |
168 | }
169 |
--------------------------------------------------------------------------------
/HypervisorCheckR0/HypervisorCheckR0.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 | Debug
22 | ARM
23 |
24 |
25 | Release
26 | ARM
27 |
28 |
29 | Debug
30 | ARM64
31 |
32 |
33 | Release
34 | ARM64
35 |
36 |
37 |
38 | {164DF69B-E119-41A4-A578-49663695145F}
39 | {1bc93793-694f-48fe-9372-81e2b05556fd}
40 | v4.5
41 | 12.0
42 | Debug
43 | Win32
44 | HypervisorCheckR0
45 | $(LatestTargetPlatformVersion)
46 |
47 |
48 |
49 | Windows10
50 | true
51 | WindowsKernelModeDriver10.0
52 | Driver
53 | KMDF
54 | Universal
55 |
56 |
57 | Windows10
58 | false
59 | WindowsKernelModeDriver10.0
60 | Driver
61 | KMDF
62 | Universal
63 |
64 |
65 | Windows10
66 | true
67 | WindowsKernelModeDriver10.0
68 | Driver
69 | KMDF
70 | Universal
71 |
72 |
73 | Windows10
74 | false
75 | WindowsKernelModeDriver10.0
76 | Driver
77 | KMDF
78 | Universal
79 | false
80 | 1
81 |
82 |
83 | Windows10
84 | true
85 | WindowsKernelModeDriver10.0
86 | Driver
87 | KMDF
88 | Universal
89 |
90 |
91 | Windows10
92 | false
93 | WindowsKernelModeDriver10.0
94 | Driver
95 | KMDF
96 | Universal
97 |
98 |
99 | Windows10
100 | true
101 | WindowsKernelModeDriver10.0
102 | Driver
103 | KMDF
104 | Universal
105 |
106 |
107 | Windows10
108 | false
109 | WindowsKernelModeDriver10.0
110 | Driver
111 | KMDF
112 | Universal
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 | DbgengKernelDebugger
125 |
126 |
127 | DbgengKernelDebugger
128 |
129 |
130 | DbgengKernelDebugger
131 |
132 |
133 | DbgengKernelDebugger
134 |
135 |
136 |
137 |
138 | DbgengKernelDebugger
139 |
140 |
141 | DbgengKernelDebugger
142 |
143 |
144 | DbgengKernelDebugger
145 |
146 |
147 | DbgengKernelDebugger
148 |
149 |
150 |
151 | stdcpp17
152 |
153 |
154 |
155 |
156 | stdc17
157 |
158 |
159 |
160 |
161 | stdcpp17
162 |
163 |
164 |
165 |
166 | stdc17
167 | Level2
168 | false
169 | SyncCThrow
170 | false
171 | false
172 |
173 |
174 | false
175 | DriverEntry
176 | %(AdditionalDependencies)
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
--------------------------------------------------------------------------------