Skip to content

Commit a864804

Browse files
authored
Merge pull request #247 from NotRequiem/dev
re-added sensors technique
2 parents 2225bd1 + 0fd788b commit a864804

File tree

4 files changed

+88
-54
lines changed

4 files changed

+88
-54
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
The library is:
1515
- Very easy to use
1616
- Cross-platform (Windows + MacOS + Linux)
17-
- Features up to 120+ unique VM detection techniques [[list](https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#flag-table)]
17+
- Features up to 130+ unique VM detection techniques [[list](https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#flag-table)]
1818
- Features the most cutting-edge techniques
19-
- Able to detect 60+ VM brands including VMware, VirtualBox, QEMU, Hyper-V, and much more [[list](https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#brand-table)]
19+
- Able to detect 65+ VM brands including VMware, VirtualBox, QEMU, Hyper-V, and much more [[list](https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#brand-table)]
2020
- Able to beat VM hardeners
2121
- Compatible with x86 and ARM, with backwards compatibility for 32-bit systems
2222
- Very flexible, with total fine-grained control over which techniques get executed

docs/documentation.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
396396
| `VM::SMSW` | Check for SMSW assembly instruction technique | Windows | 30% | | | 32-bit | |
397397
| `VM::MUTEX` | Check for mutex strings of VM brands | Windows | 85% | | | | |
398398
| `VM::ODD_CPU_THREADS` | Check for odd CPU threads, usually a sign of modification through VM setting because 99% of CPUs have even numbers of threads | | 80% | | | | |
399-
| `VM::INTEL_THREAD_MISMATCH` | Check for Intel CPU thread count database if it matches the system's thread count | | 100% | | | | |
399+
| `VM::INTEL_THREAD_MISMATCH` | Check for Intel CPU thread count database if it matches the system's thread count | | 150% | | | | |
400400
| `VM::XEON_THREAD_MISMATCH` | Same as above, but for Xeon Intel CPUs | | 100% | | | | |
401401
| `VM::NETTITUDE_VM_MEMORY` | Check for memory regions to detect VM-specific brands | Windows | 100% | | | | |
402402
| `VM::CPUID_BITSET` | Check for CPUID technique by checking whether all the bits equate to more than 4000 | | 25% | | | | |
@@ -445,7 +445,6 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
445445
| `VM::WMI_MANUFACTURER` | Check for device's manufacturer using WMI | Windows | 100% | | | | |
446446
| `VM::WMI_TEMPERATURE` | Check for device's temperature | Windows | 25% | Admin | | | |
447447
| `VM::PROCESSOR_ID` | Check for empty processor ids using WMI | Windows | 25% | | | | |
448-
| `VM::CPU_FANS` | Check for CPU Fans | Windows | 35% | | | | |
449448
| `VM::VMWARE_HARDENER` | Checks for VMwareHardenerLoader's method of patching firmware detection by setting its signatures with "7" | Windows | 60% | | | | |
450449
| `VM::SYS_QEMU` | Check for existence of "qemu_fw_cfg" directories within /sys/module and /sys/firmware | Linux | 70% | | | | |
451450
| `VM::LSHW_QEMU` | Check for QEMU string instances with lshw command | Linux | 80% | | | | |
@@ -463,6 +462,7 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
463462
| `VM::FILE_ACCESS_HISTORY` | Check if the number of accessed files are too low for a human-managed environment | Linux | 15% | | | | |
464463
| `VM::AUDIO` | Check if audio device is present | Windows | 25% | | | | |
465464
| `VM::UNKNOWN_MANUFACTURER` | Check if the CPU manufacturer is not known | | 50% | | | | |
465+
| `VM::SENSORS` | Check if the system reports any information from hardware sensors | Windows | 35% | | | | |
466466

467467

468468
<br>

src/cli.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,6 @@ bool is_unsupported(VM::enum_flags flag) {
472472
case VM::WMI_MANUFACTURER:
473473
case VM::WMI_TEMPERATURE:
474474
case VM::PROCESSOR_ID:
475-
case VM::CPU_FANS:
476475
case VM::POWER_CAPABILITIES:
477476
case VM::SETUPAPI_DISK:
478477
case VM::VMWARE_HARDENER:
@@ -486,6 +485,7 @@ bool is_unsupported(VM::enum_flags flag) {
486485
case VM::FIRMWARE_SCAN:
487486
case VM::NX_BIT:
488487
case VM::UNKNOWN_MANUFACTURER:
488+
case VM::SENSORS:
489489
// ADD WINDOWS FLAG
490490
return false;
491491
default: return true;
@@ -1003,7 +1003,6 @@ void general() {
10031003
checker(VM::WMI_MANUFACTURER, "hardware manufacturer");
10041004
checker(VM::WMI_TEMPERATURE, "WMI temperature");
10051005
checker(VM::PROCESSOR_ID, "processor ID");
1006-
checker(VM::CPU_FANS, "CPU fans");
10071006
checker(VM::POWER_CAPABILITIES, "Power capabilities");
10081007
checker(VM::SETUPAPI_DISK, "SETUPDI diskdrive");
10091008
checker(VM::VMWARE_HARDENER, "VMware hardener");
@@ -1021,6 +1020,7 @@ void general() {
10211020
checker(VM::NX_BIT, "NX/XD anomalies");
10221021
checker(VM::FILE_ACCESS_HISTORY, "low file access count");
10231022
checker(VM::UNKNOWN_MANUFACTURER, "unknown manufacturer ids");
1023+
checker(VM::SENSORS, "sensors");
10241024

10251025
// ADD NEW TECHNIQUE CHECKER HERE
10261026

src/vmaware.hpp

Lines changed: 82 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,6 @@ struct VM {
582582
WMI_MANUFACTURER,
583583
WMI_TEMPERATURE,
584584
PROCESSOR_ID,
585-
CPU_FANS,
586585
VMWARE_HARDENER,
587586
SYS_QEMU,
588587
LSHW_QEMU,
@@ -599,6 +598,7 @@ struct VM {
599598
FILE_ACCESS_HISTORY,
600599
AUDIO,
601600
UNKNOWN_MANUFACTURER,
601+
SENSORS,
602602
// ADD NEW TECHNIQUE ENUM NAME HERE
603603

604604
// start of settings technique flags (THE ORDERING IS VERY SPECIFIC HERE AND MIGHT BREAK SOMETHING IF RE-ORDERED)
@@ -1402,10 +1402,10 @@ struct VM {
14021402
new (&strValue) std::string(other.strValue);
14031403
break;
14041404
case result_type::Integer:
1405-
intValue = other.intValue;
1405+
new (&intValue) int(other.intValue);
14061406
break;
14071407
case result_type::Double:
1408-
doubleValue = other.doubleValue;
1408+
new (&doubleValue) double(other.doubleValue);
14091409
break;
14101410
default:
14111411
break;
@@ -1449,6 +1449,7 @@ struct VM {
14491449
if (results.empty()) {
14501450
std::cout << "No results\n";
14511451
}
1452+
14521453
for (const auto& res : results) {
14531454
switch (res.type) {
14541455
case result_type::String:
@@ -1563,7 +1564,8 @@ struct VM {
15631564
return true;
15641565
}
15651566

1566-
// Execute a WQL query. The caller can choose which namespace to use via the optional 'cim' parameter.
1567+
// Execute a WQL query. The caller can choose which namespace to use via the optional 'cim' parameter.
1568+
// If no property is specified, the wmi wrapper will execute the query and count the number of entries.
15671569
static std::vector<result> execute(const std::wstring& query,
15681570
const std::vector<std::wstring>& properties,
15691571
bool cim = true) {
@@ -1603,35 +1605,54 @@ struct VM {
16031605

16041606
IWbemClassObject* pclsObj = nullptr;
16051607
ULONG uReturn = 0;
1606-
while (pEnumerator) {
1607-
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
1608-
if (0 == uReturn || FAILED(hr)) {
1609-
break;
1608+
1609+
if (properties.empty()) {
1610+
int count = 0;
1611+
while (true) {
1612+
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
1613+
if (FAILED(hr) || uReturn == 0) {
1614+
break;
1615+
}
1616+
count++;
1617+
pclsObj->Release();
1618+
pclsObj = nullptr;
16101619
}
1620+
results.emplace_back(count);
1621+
}
1622+
else {
1623+
while (true) {
1624+
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
1625+
if (FAILED(hr) || uReturn == 0) {
1626+
break;
1627+
}
16111628

1612-
for (const auto& prop : properties) {
1613-
VARIANT vtProp;
1614-
VariantInit(&vtProp);
1615-
hr = pclsObj->Get(prop.c_str(), 0, &vtProp, 0, 0);
1616-
if (SUCCEEDED(hr)) {
1617-
if (vtProp.vt == VT_BSTR) {
1618-
results.emplace_back(_com_util::ConvertBSTRToString(vtProp.bstrVal));
1619-
}
1620-
else if (vtProp.vt == VT_I4) {
1621-
results.emplace_back(vtProp.intVal);
1622-
}
1623-
else if (vtProp.vt == VT_R8) {
1624-
results.emplace_back(vtProp.dblVal);
1629+
for (const auto& prop : properties) {
1630+
VARIANT vtProp;
1631+
VariantInit(&vtProp);
1632+
hr = pclsObj->Get(prop.c_str(), 0, &vtProp, 0, 0);
1633+
if (SUCCEEDED(hr)) {
1634+
if (vtProp.vt == VT_BSTR) {
1635+
results.emplace_back(_com_util::ConvertBSTRToString(vtProp.bstrVal));
1636+
}
1637+
else if (vtProp.vt == VT_I4) {
1638+
results.emplace_back(vtProp.intVal);
1639+
}
1640+
else if (vtProp.vt == VT_R8) {
1641+
results.emplace_back(vtProp.dblVal);
1642+
}
16251643
}
1644+
VariantClear(&vtProp);
16261645
}
1627-
VariantClear(&vtProp);
1646+
pclsObj->Release();
1647+
pclsObj = nullptr;
16281648
}
1629-
pclsObj->Release();
16301649
}
1650+
16311651
pEnumerator->Release();
16321652
return results;
16331653
}
16341654

1655+
16351656
static void cleanup() noexcept {
16361657
if (pSvc) {
16371658
pSvc->Release();
@@ -9593,25 +9614,6 @@ struct VM {
95939614
}
95949615

95959616

9596-
/**
9597-
* @brief Check for CPU Fans
9598-
* @category Windows
9599-
* @author idea from Al-Khaser project
9600-
* @implements VM::CPU_FANS
9601-
*/
9602-
[[nodiscard]] static bool cpu_fans() {
9603-
#if (!WINDOWS)
9604-
return false;
9605-
#else
9606-
std::wstring query = L"SELECT * FROM Win32_Fan";
9607-
std::vector<std::wstring> properties = { };
9608-
wmi_result results = wmi::execute(query, properties);
9609-
9610-
return !results.empty();
9611-
#endif
9612-
}
9613-
9614-
96159617
/**
96169618
* @brief Check RDTSC
96179619
* @category Windows
@@ -11323,17 +11325,18 @@ static bool rdtsc() {
1132311325

1132411326
/* @brief Check if the CPU manufacturer is not known
1132511327
* @category x86
11328+
* @implements VM::UNKNOWN_MANUFACTURER
1132611329
*/
1132711330
[[nodiscard]] static bool unknown_manufacturer() {
11328-
constexpr std::array<const char*, 21> known_ids = {
11331+
constexpr std::array<const char*, 21> known_ids = {{
1132911332
"AuthenticAMD", "CentaurHauls", "CyrixInstead",
1133011333
"GenuineIntel", "GenuineIotel", "TransmetaCPU",
1133111334
"GenuineTMx86", "Geode by NSC", "NexGenDriven",
1133211335
"RiseRiseRise", "SiS SiS SiS ", "UMC UMC UMC ",
1133311336
"Vortex86 SoC", " Shanghai ", "HygonGenuine",
1133411337
"Genuine RDC", "E2K MACHINE", "VIA VIA VIA ",
1133511338
"AMD ISBETTER", "GenuineAO486", "MiSTer AO486"
11336-
};
11339+
}};
1133711340

1133811341
const auto brands = cpu::cpu_manufacturer(0);
1133911342
const std::string& brand1 = brands[0];
@@ -11346,10 +11349,41 @@ static bool rdtsc() {
1134611349
return s == id;
1134711350
}
1134811351
);
11349-
};
11352+
};
1135011353

1135111354
return !matches(brand1) && !matches(brand2);
1135211355
}
11356+
11357+
11358+
/*
11359+
* @brief Check if the system reports any information from hardware sensors
11360+
* @category Windows
11361+
* @implements VM::SENSORS
11362+
*/
11363+
[[nodiscard]] static bool sensors() {
11364+
#if (!WINDOWS)
11365+
return false;
11366+
#else
11367+
const std::vector<std::wstring> queries = {
11368+
L"SELECT * FROM Win32_VoltageProbe",
11369+
L"SELECT * FROM Win32_PerfFormattedData_Counters_ThermalZoneInformation",
11370+
// L"SELECT * FROM CIM_Sensor",
11371+
L"SELECT * FROM CIM_NumericSensor",
11372+
L"SELECT * FROM CIM_TemperatureSensor",
11373+
L"SELECT * FROM CIM_VoltageSensor",
11374+
L"SELECT * FROM Win32_Fan"
11375+
};
11376+
11377+
for (const auto& query : queries) {
11378+
const auto results = wmi::execute(query, {});
11379+
if (results.empty()) {
11380+
return true;
11381+
}
11382+
}
11383+
11384+
return false;
11385+
#endif
11386+
}
1135311387
// ADD NEW TECHNIQUE FUNCTION HERE
1135411388

1135511389

@@ -12372,7 +12406,6 @@ static bool rdtsc() {
1237212406
case WMI_MANUFACTURER: return "WMI_MANUFACTURER";
1237312407
case WMI_TEMPERATURE: return "WMI_TEMPERATURE";
1237412408
case PROCESSOR_ID: return "PROCESSOR_ID";
12375-
case CPU_FANS: return "CPU_FANS";
1237612409
case POWER_CAPABILITIES: return "POWER_CAPABILITIES";
1237712410
case SETUPAPI_DISK: return "SETUPAPI_DISK";
1237812411
case VMWARE_HARDENER: return "VMWARE_HARDENER";
@@ -12391,6 +12424,7 @@ static bool rdtsc() {
1239112424
case FILE_ACCESS_HISTORY: return "FILE_ACCESS_HISTORY";
1239212425
case AUDIO: return "AUDIO";
1239312426
case UNKNOWN_MANUFACTURER: return "UNKNOWN_MANUFACTURER";
12427+
case SENSORS: return "SENSORS";
1239412428
// ADD NEW CASE HERE FOR NEW TECHNIQUE
1239512429
default: return "Unknown flag";
1239612430
}
@@ -12900,7 +12934,7 @@ std::pair<VM::enum_flags, VM::core::technique> VM::core::technique_list[] = {
1290012934
{ VM::SMSW, { 30, VM::smsw } },
1290112935
{ VM::MUTEX, { 85, VM::mutex } },
1290212936
{ VM::ODD_CPU_THREADS, { 80, VM::odd_cpu_threads } },
12903-
{ VM::INTEL_THREAD_MISMATCH, { 100, VM::intel_thread_mismatch } },
12937+
{ VM::INTEL_THREAD_MISMATCH, { 150, VM::intel_thread_mismatch } },
1290412938
{ VM::XEON_THREAD_MISMATCH, { 100, VM::xeon_thread_mismatch } },
1290512939
{ VM::NETTITUDE_VM_MEMORY, { 100, VM::nettitude_vm_memory } },
1290612940
{ VM::CPUID_BITSET, { 25, VM::cpuid_bitset } },
@@ -12947,7 +12981,6 @@ std::pair<VM::enum_flags, VM::core::technique> VM::core::technique_list[] = {
1294712981
{ VM::WMI_MANUFACTURER, { 100, VM::wmi_manufacturer } },
1294812982
{ VM::WMI_TEMPERATURE, { 25, VM::wmi_temperature } },
1294912983
{ VM::PROCESSOR_ID, { 25, VM::processor_id } },
12950-
{ VM::CPU_FANS, { 35, VM::cpu_fans } },
1295112984
{ VM::VMWARE_HARDENER, { 60, VM::vmware_hardener } },
1295212985
{ VM::SYS_QEMU, { 70, VM::sys_qemu_dir } },
1295312986
{ VM::LSHW_QEMU, { 80, VM::lshw_qemu } },
@@ -12964,6 +12997,7 @@ std::pair<VM::enum_flags, VM::core::technique> VM::core::technique_list[] = {
1296412997
{ VM::FILE_ACCESS_HISTORY, { 15, VM::file_access_history } },
1296512998
{ VM::AUDIO, { 25, VM::check_audio } },
1296612999
{ VM::UNKNOWN_MANUFACTURER, { 50, VM::unknown_manufacturer } },
13000+
{ VM::SENSORS, { 35, VM::sensors } },
1296713001
// ADD NEW TECHNIQUE STRUCTURE HERE
1296813002
};
1296913003

0 commit comments

Comments
 (0)