Skip to content

Commit 4a3a446

Browse files
diseanbinarymaster
authored andcommitted
[KMTESTS] Add the ability to detect a virtual machine
This allows the tests to interact directly with hardware CORE-20078
1 parent 18290a7 commit 4a3a446

File tree

6 files changed

+129
-0
lines changed

6 files changed

+129
-0
lines changed

modules/rostests/kmtests/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ list(APPEND KMTEST_DRV_SOURCE
4444
kmtest_drv/kmtest_drv.c
4545
kmtest_drv/structs.c
4646
kmtest_drv/testlist.c
47+
kmtest_drv/vm_detect.c
4748

4849
example/Example.c
4950
example/KernelType.c
@@ -119,6 +120,13 @@ list(APPEND KMTEST_DRV_SOURCE
119120

120121
kmtest_drv/kmtest_drv.rc)
121122

123+
if(ARCH STREQUAL "i386" OR ARCH STREQUAL "amd64")
124+
add_asm_files(KMTEST_DRV_ASM
125+
kmtest_drv/vm_detect.S)
126+
list(APPEND KMTEST_DRV_SOURCE
127+
${KMTEST_DRV_ASM})
128+
endif()
129+
122130
add_library(kmtest_drv MODULE ${KMTEST_DRV_SOURCE})
123131
set_module_type(kmtest_drv kernelmodedriver)
124132
target_link_libraries(kmtest_drv kmtest_printf chkstk memcmp ntoskrnl_vista ${PSEH_LIB})

modules/rostests/kmtests/include/kmt_test.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ typedef struct
156156

157157
extern BOOLEAN KmtIsCheckedBuild;
158158
extern BOOLEAN KmtIsMultiProcessorBuild;
159+
extern BOOLEAN KmtIsVirtualMachine;
159160
extern PCSTR KmtMajorFunctionNames[];
160161
extern PDRIVER_OBJECT KmtDriverObject;
161162

modules/rostests/kmtests/include/kmt_test_kernel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
BOOLEAN KmtIsCheckedBuild;
1616
BOOLEAN KmtIsMultiProcessorBuild;
17+
BOOLEAN KmtIsVirtualMachine;
1718
PCSTR KmtMajorFunctionNames[] =
1819
{
1920
"Create",

modules/rostests/kmtests/kmtest_drv/kmtest_drv.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ typedef struct _KMT_USER_WORK_LIST
3636
KEVENT NewWorkEvent;
3737
} KMT_USER_WORK_LIST, *PKMT_USER_WORK_LIST;
3838

39+
extern
40+
BOOLEAN
41+
KmtDetectVirtualMachine(VOID);
42+
3943
/* Prototypes */
4044
DRIVER_INITIALIZE DriverEntry;
4145
static DRIVER_UNLOAD DriverUnload;
@@ -88,6 +92,7 @@ DriverEntry(
8892
Prcb = KeGetCurrentPrcb();
8993
KmtIsCheckedBuild = (Prcb->BuildType & PRCB_BUILD_DEBUG) != 0;
9094
KmtIsMultiProcessorBuild = (Prcb->BuildType & PRCB_BUILD_UNIPROCESSOR) == 0;
95+
KmtIsVirtualMachine = KmtDetectVirtualMachine();
9196
KmtDriverObject = DriverObject;
9297

9398
RtlInitUnicodeString(&DeviceName, KMTEST_DEVICE_DRIVER_PATH);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* PROJECT: ReactOS Kernel-Mode Tests
3+
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4+
* PURPOSE: ASM helper functions for VM detection
5+
* COPYRIGHT: Copyright 2025 Dmitry Borisov <di[email protected]>
6+
*/
7+
8+
#include <asm.inc>
9+
10+
#define VMWARE_SIGNATURE HEX(564D5868) // 'VMXh'
11+
#define VMWARE_PORT HEX(5658) // 'VX'
12+
13+
.code
14+
15+
/*
16+
* BOOLEAN
17+
* VmIsVMware(VOID);
18+
*/
19+
#ifdef _M_IX86
20+
PUBLIC _VmIsVMware
21+
_VmIsVMware:
22+
push ebx
23+
push ecx
24+
push edx
25+
#else
26+
PUBLIC VmIsVMware
27+
VmIsVMware:
28+
push rbx
29+
push rcx
30+
push rdx
31+
#endif
32+
33+
mov eax, VMWARE_SIGNATURE
34+
mov ebx, 0
35+
mov ecx, 10
36+
mov edx, VMWARE_PORT
37+
in eax, dx
38+
cmp ebx, VMWARE_SIGNATURE
39+
sete al
40+
41+
#ifdef _M_IX86
42+
pop edx
43+
pop ecx
44+
pop ebx
45+
#else
46+
pop rdx
47+
pop rcx
48+
pop rbx
49+
#endif
50+
51+
ret
52+
53+
END
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* PROJECT: ReactOS Kernel-Mode Tests
3+
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4+
* PURPOSE: VM detection code
5+
* COPYRIGHT: Copyright 2025 Dmitry Borisov <[email protected]>
6+
*/
7+
8+
/* INCLUDES *******************************************************************/
9+
10+
#include <kmt_test.h>
11+
12+
/* FUNCTIONS ******************************************************************/
13+
14+
#if defined(_M_IX86) || defined(_M_AMD64)
15+
extern BOOLEAN VmIsVMware(VOID);
16+
17+
static
18+
BOOLEAN
19+
VmIsHypervisorPresent(VOID)
20+
{
21+
INT CpuInfo[4];
22+
23+
__cpuid(CpuInfo, 1);
24+
25+
return !!(CpuInfo[2] & 0x80000000);
26+
}
27+
28+
static
29+
BOOLEAN
30+
VmIsVbox(VOID)
31+
{
32+
ULONG PciId, BytesRead;
33+
PCI_SLOT_NUMBER Slot;
34+
35+
Slot.u.AsULONG = 0;
36+
Slot.u.bits.DeviceNumber = 4;
37+
Slot.u.bits.FunctionNumber = 0;
38+
39+
BytesRead = HalGetBusDataByOffset(PCIConfiguration,
40+
0,
41+
Slot.u.AsULONG,
42+
&PciId,
43+
FIELD_OFFSET(PCI_COMMON_HEADER, VendorID),
44+
sizeof(PciId));
45+
return (BytesRead == sizeof(PciId)) && (PciId == 0xCAFE80EE);
46+
}
47+
#endif // defined(_M_IX86) || defined(_M_AMD64)
48+
49+
/*
50+
* NOTE: We make no attempt to support every software in existence.
51+
* Only VMs used by Testman are checked.
52+
*/
53+
BOOLEAN
54+
KmtDetectVirtualMachine(VOID)
55+
{
56+
#if defined(_M_IX86) || defined(_M_AMD64)
57+
return VmIsHypervisorPresent() || VmIsVbox() || VmIsVMware();
58+
#else
59+
return FALSE;
60+
#endif
61+
}

0 commit comments

Comments
 (0)