diff --git a/SafeExamBrowser.SystemComponents.Contracts/ISystemInfo.cs b/SafeExamBrowser.SystemComponents.Contracts/ISystemInfo.cs
index 194bb969..c328f921 100644
--- a/SafeExamBrowser.SystemComponents.Contracts/ISystemInfo.cs
+++ b/SafeExamBrowser.SystemComponents.Contracts/ISystemInfo.cs
@@ -18,6 +18,11 @@ namespace SafeExamBrowser.SystemComponents.Contracts
///
string BiosInfo { get; }
+ ///
+ /// The name of the CPU.
+ ///
+ string CpuName { get; }
+
///
/// Reveals whether the computer system contains a battery.
///
diff --git a/SafeExamBrowser.SystemComponents/Registry/Registry.cs b/SafeExamBrowser.SystemComponents/Registry/Registry.cs
index 43b67ddd..f70185a6 100644
--- a/SafeExamBrowser.SystemComponents/Registry/Registry.cs
+++ b/SafeExamBrowser.SystemComponents/Registry/Registry.cs
@@ -229,7 +229,6 @@ namespace SafeExamBrowser.SystemComponents.Registry
try
{
- logger.Info($"default(RegistryKey) == null: {key == null}");
if (TryGetBaseKeyFromKeyName(keyName, out var baseKey, out var subKey))
{
key = baseKey.OpenSubKey(subKey);
diff --git a/SafeExamBrowser.SystemComponents/SystemInfo.cs b/SafeExamBrowser.SystemComponents/SystemInfo.cs
index 207a2fab..476c45d3 100644
--- a/SafeExamBrowser.SystemComponents/SystemInfo.cs
+++ b/SafeExamBrowser.SystemComponents/SystemInfo.cs
@@ -20,6 +20,7 @@ namespace SafeExamBrowser.SystemComponents
public class SystemInfo : ISystemInfo
{
public string BiosInfo { get; private set; }
+ public string CpuName { get; private set; }
public bool HasBattery { get; private set; }
public string MacAddress { get; private set; }
public string Manufacturer { get; private set; }
@@ -33,6 +34,7 @@ namespace SafeExamBrowser.SystemComponents
{
InitializeBattery();
InitializeBiosInfo();
+ InitializeCpuName();
InitializeMacAddress();
InitializeMachineInfo();
InitializeOperatingSystem();
@@ -79,6 +81,34 @@ namespace SafeExamBrowser.SystemComponents
}
}
+ private void InitializeCpuName()
+ {
+ try
+ {
+ using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Processor"))
+ using (var results = searcher.Get())
+ {
+ foreach (var cpu in results)
+ {
+ using (cpu)
+ {
+ foreach (var property in cpu.Properties)
+ {
+ if (property.Name.Equals("Name"))
+ {
+ CpuName = Convert.ToString(property.Value);
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception)
+ {
+ CpuName = "";
+ }
+ }
+
private void InitializeMachineInfo()
{
var model = default(string);
@@ -192,7 +222,7 @@ namespace SafeExamBrowser.SystemComponents
using (var searcher = new ManagementObjectSearcher("SELECT MACAddress FROM Win32_NetworkAdapterConfiguration WHERE DNSDomain IS NOT NULL"))
using (var results = searcher.Get())
{
- if (results != null && results.Count > 0)
+ if (results != default && results.Count > 0)
{
using (var networkAdapter = results.Cast().First())
{
@@ -226,11 +256,11 @@ namespace SafeExamBrowser.SystemComponents
using (var searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT DeviceID FROM Win32_PnPEntity"))
using (var results = searcher.Get())
{
- foreach (ManagementObject queryObj in results)
+ foreach (var device in results.Cast())
{
- using (queryObj)
+ using (device)
{
- foreach (var property in queryObj.Properties)
+ foreach (var property in device.Properties)
{
if (property.Name.Equals("DeviceID"))
{
diff --git a/SafeExamBrowser.SystemComponents/VirtualMachineDetector.cs b/SafeExamBrowser.SystemComponents/VirtualMachineDetector.cs
index 94306633..7e49711c 100644
--- a/SafeExamBrowser.SystemComponents/VirtualMachineDetector.cs
+++ b/SafeExamBrowser.SystemComponents/VirtualMachineDetector.cs
@@ -7,7 +7,6 @@
*/
using System.Linq;
-using System.Management;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.SystemComponents.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.Registry;
@@ -16,6 +15,7 @@ namespace SafeExamBrowser.SystemComponents
{
public class VirtualMachineDetector : IVirtualMachineDetector
{
+ private const string MANIPULATED = "000000000000";
private const string QEMU_MAC_PREFIX = "525400";
private const string VIRTUALBOX_MAC_PREFIX = "080027";
@@ -52,176 +52,161 @@ namespace SafeExamBrowser.SystemComponents
public bool IsVirtualMachine()
{
- var biosInfo = systemInfo.BiosInfo;
- var devices = systemInfo.PlugAndPlayDeviceIds;
var isVirtualMachine = false;
- var macAddress = systemInfo.MacAddress;
- var manufacturer = systemInfo.Manufacturer;
- var model = systemInfo.Model;
+ isVirtualMachine |= HasVirtualDevice();
+ isVirtualMachine |= HasVirtualMacAddress();
+ isVirtualMachine |= IsVirtualCpu();
isVirtualMachine |= IsVirtualRegistry();
- isVirtualMachine |= IsVirtualSystemInfo(biosInfo, manufacturer, model);
- isVirtualMachine |= IsVirtualWmi();
-
- if (macAddress != null && macAddress.Count() > 2)
- {
- isVirtualMachine |= macAddress.StartsWith(QEMU_MAC_PREFIX);
- isVirtualMachine |= macAddress.StartsWith(VIRTUALBOX_MAC_PREFIX);
- isVirtualMachine |= macAddress.StartsWith("000000000000");
- }
-
- foreach (var device in devices)
- {
- isVirtualMachine |= DeviceBlacklist.Any(d => device.ToLower().Contains(d.ToLower())) && DeviceWhitelist.All(d => !device.ToLower().Contains(d.ToLower()));
- }
+ isVirtualMachine |= IsVirtualSystem(systemInfo.BiosInfo, systemInfo.Manufacturer, systemInfo.Model);
logger.Debug($"Computer '{systemInfo.Name}' appears {(isVirtualMachine ? "" : "not ")}to be a virtual machine.");
return isVirtualMachine;
}
- private bool IsVirtualSystemInfo(string biosInfo, string manufacturer, string model)
+ private bool HasVirtualDevice()
{
- var isVirtualMachine = false;
+ var hasVirtualDevice = false;
+
+ foreach (var device in systemInfo.PlugAndPlayDeviceIds)
+ {
+ hasVirtualDevice |= DeviceBlacklist.Any(d => device.ToLower().Contains(d.ToLower())) && DeviceWhitelist.All(d => !device.ToLower().Contains(d.ToLower()));
+ }
+
+ return hasVirtualDevice;
+ }
+
+ private bool HasVirtualMacAddress()
+ {
+ var hasVirtualMacAddress = false;
+ var macAddress = systemInfo.MacAddress;
+
+ if (macAddress != null && macAddress.Length > 2)
+ {
+ hasVirtualMacAddress |= macAddress.StartsWith(MANIPULATED);
+ hasVirtualMacAddress |= macAddress.StartsWith(QEMU_MAC_PREFIX);
+ hasVirtualMacAddress |= macAddress.StartsWith(VIRTUALBOX_MAC_PREFIX);
+ }
+
+ return hasVirtualMacAddress;
+ }
+
+ private bool IsVirtualCpu()
+ {
+ var isVirtualCpu = false;
+
+ isVirtualCpu |= systemInfo.CpuName.ToLower().Contains(" kvm ");
+
+ return isVirtualCpu;
+ }
+
+ private bool IsVirtualRegistry()
+ {
+ var isVirtualRegistry = false;
+
+ isVirtualRegistry |= HasHistoricVirtualMachineHardwareConfiguration();
+ isVirtualRegistry |= HasLocalVirtualMachineDeviceCache();
+
+ return isVirtualRegistry;
+ }
+
+ private bool IsVirtualSystem(string biosInfo, string manufacturer, string model)
+ {
+ var isVirtualSystem = false;
biosInfo = biosInfo.ToLower();
manufacturer = manufacturer.ToLower();
model = model.ToLower();
- isVirtualMachine |= biosInfo.Contains("hyper-v");
- isVirtualMachine |= biosInfo.Contains("virtualbox");
- isVirtualMachine |= biosInfo.Contains("vmware");
- isVirtualMachine |= biosInfo.Contains("ovmf");
- isVirtualMachine |= biosInfo.Contains("edk ii unknown");
- isVirtualMachine |= manufacturer.Contains("microsoft corporation") && !model.Contains("surface");
- isVirtualMachine |= manufacturer.Contains("parallels software");
- isVirtualMachine |= manufacturer.Contains("qemu");
- isVirtualMachine |= manufacturer.Contains("vmware");
- isVirtualMachine |= model.Contains("virtualbox");
- isVirtualMachine |= model.Contains("Q35 +");
+ isVirtualSystem |= biosInfo.Contains("hyper-v");
+ isVirtualSystem |= biosInfo.Contains("virtualbox");
+ isVirtualSystem |= biosInfo.Contains("vmware");
+ isVirtualSystem |= biosInfo.Contains("ovmf");
+ isVirtualSystem |= biosInfo.Contains("edk ii unknown");
+ isVirtualSystem |= manufacturer.Contains("microsoft corporation") && !model.Contains("surface");
+ isVirtualSystem |= manufacturer.Contains("parallels software");
+ isVirtualSystem |= manufacturer.Contains("qemu");
+ isVirtualSystem |= manufacturer.Contains("vmware");
+ isVirtualSystem |= model.Contains("virtualbox");
+ isVirtualSystem |= model.Contains("Q35 +");
- return isVirtualMachine;
- }
-
- private bool IsVirtualRegistry()
- {
- var isVirtualMachine = false;
-
- isVirtualMachine |= HasHistoricVirtualMachineHardwareConfiguration();
- isVirtualMachine |= HasLocalVirtualMachineDeviceCache();
-
- return isVirtualMachine;
+ return isVirtualSystem;
}
private bool HasHistoricVirtualMachineHardwareConfiguration()
{
- /**
- * scanned registry format:
- *
- * HKLM\SYSTEM\HardwareConfig\{configId=uuid}
- * - BIOSVendor
- * - SystemManufacturer
- * - ...
- * \ComputerIds
- * - {computerId=uuid}: {computerSummary=hardwareInfo}
- *
- */
- const string HARDWARE_ROOT_KEY = "HKEY_LOCAL_MACHINE\\SYSTEM\\HardwareConfig";
+ const string HARDWARE_ROOT_KEY = @"HKEY_LOCAL_MACHINE\SYSTEM\HardwareConfig";
- var isVirtualMachine = false;
+ var hasHistoricConfiguration = false;
- if (!registry.TryGetSubKeys(HARDWARE_ROOT_KEY, out var hardwareConfigSubkeys))
+ if (registry.TryGetSubKeys(HARDWARE_ROOT_KEY, out var hardwareConfigSubkeys))
{
- return false;
- }
-
- foreach (var configId in hardwareConfigSubkeys)
- {
- var hardwareConfigKey = $"{HARDWARE_ROOT_KEY}\\{configId}";
- var didReadKeys = true;
-
- didReadKeys &= registry.TryRead(hardwareConfigKey, "BIOSVendor", out var biosVendor);
- didReadKeys &= registry.TryRead(hardwareConfigKey, "BIOSVersion", out var biosVersion);
- didReadKeys &= registry.TryRead(hardwareConfigKey, "SystemManufacturer", out var systemManufacturer);
- didReadKeys &= registry.TryRead(hardwareConfigKey, "SystemProductName", out var systemProductName);
-
- if (!didReadKeys)
+ foreach (var configId in hardwareConfigSubkeys)
{
- continue;
- }
+ var hardwareConfigKey = $"{HARDWARE_ROOT_KEY}\\{configId}";
+ var computerIdsKey = $"{hardwareConfigKey}\\ComputerIds";
+ var success = true;
- var biosInfo = $"{(string) biosVendor} {(string) biosVersion}";
+ success &= registry.TryRead(hardwareConfigKey, "BIOSVendor", out var biosVendor);
+ success &= registry.TryRead(hardwareConfigKey, "BIOSVersion", out var biosVersion);
+ success &= registry.TryRead(hardwareConfigKey, "SystemManufacturer", out var systemManufacturer);
+ success &= registry.TryRead(hardwareConfigKey, "SystemProductName", out var systemProductName);
- isVirtualMachine |= IsVirtualSystemInfo(biosInfo, (string) systemManufacturer, (string) systemProductName);
-
- var computerIdsKey = $"{hardwareConfigKey}\\ComputerIds";
- if (!registry.TryGetNames(computerIdsKey, out var computerIdNames))
- {
- continue;
- }
-
- foreach (var computerIdName in computerIdNames)
- {
- if (!registry.TryRead(computerIdsKey, computerIdName, out var computerSummary))
+ if (success)
{
- continue;
- }
+ var biosInfo = $"{(string) biosVendor} {(string) biosVersion}";
- isVirtualMachine |= IsVirtualSystemInfo((string) computerSummary, (string) systemManufacturer, (string) systemProductName);
+ hasHistoricConfiguration |= IsVirtualSystem(biosInfo, (string) systemManufacturer, (string) systemProductName);
+
+ if (registry.TryGetNames(computerIdsKey, out var computerIdNames))
+ {
+ foreach (var computerIdName in computerIdNames)
+ {
+ if (registry.TryRead(computerIdsKey, computerIdName, out var computerSummary))
+ {
+ hasHistoricConfiguration |= IsVirtualSystem((string) computerSummary, (string) systemManufacturer, (string) systemProductName);
+ }
+ }
+ }
+ }
}
}
- return isVirtualMachine;
+ return hasHistoricConfiguration;
}
private bool HasLocalVirtualMachineDeviceCache()
{
- const string DEVICE_CACHE_PARENT_KEY = "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\TaskFlow\\DeviceCache";
+ const string DEVICE_CACHE_PARENT_KEY = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\TaskFlow\DeviceCache";
- var isVirtualMachine = false;
var deviceName = System.Environment.GetEnvironmentVariable("COMPUTERNAME");
+ var hasDeviceCache = false;
var hasDeviceCacheKeys = registry.TryGetSubKeys(DEVICE_CACHE_PARENT_KEY, out var deviceCacheKeys);
- if (deviceName != null && hasDeviceCacheKeys)
+ if (deviceName != default && hasDeviceCacheKeys)
{
foreach (var cacheId in deviceCacheKeys)
{
- var cacheIdKey = $"{DEVICE_CACHE_PARENT_KEY}\\{cacheId}";
+ var cacheIdKey = $@"{DEVICE_CACHE_PARENT_KEY}\{cacheId}";
var didReadKeys = true;
didReadKeys &= registry.TryRead(cacheIdKey, "DeviceName", out var cacheDeviceName);
- if (!didReadKeys || deviceName.ToLower() != ((string) cacheDeviceName).ToLower())
+ if (didReadKeys && deviceName.ToLower() == ((string) cacheDeviceName).ToLower())
{
- continue;
+ didReadKeys &= registry.TryRead(cacheIdKey, "DeviceMake", out var cacheDeviceManufacturer);
+ didReadKeys &= registry.TryRead(cacheIdKey, "DeviceModel", out var cacheDeviceModel);
+
+ if (didReadKeys)
+ {
+ hasDeviceCache |= IsVirtualSystem("", (string) cacheDeviceManufacturer, (string) cacheDeviceModel);
+ }
}
-
- didReadKeys &= registry.TryRead(cacheIdKey, "DeviceMake", out var cacheDeviceManufacturer);
- didReadKeys &= registry.TryRead(cacheIdKey, "DeviceModel", out var cacheDeviceModel);
-
- if (!didReadKeys)
- {
- continue;
- }
-
- isVirtualMachine |= IsVirtualSystemInfo("", (string) cacheDeviceManufacturer, (string) cacheDeviceModel);
}
}
- return isVirtualMachine;
- }
-
- private bool IsVirtualWmi()
- {
- var isVirtualMachine = false;
- var cpuObjSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_Processor");
-
- foreach (var cpuObj in cpuObjSearcher.Get())
- {
- isVirtualMachine |= ((string) cpuObj["Name"]).ToLower().Contains(" kvm ");
- }
-
- return isVirtualMachine;
+ return hasDeviceCache;
}
}
}