Skip to content

Commit 7e1ca37

Browse files
committed
Merge branch 'dev' of https://github.com/kernelwernel/VMAware into dev
2 parents 19dd901 + ba8abcc commit 7e1ca37

2 files changed

Lines changed: 111 additions & 21 deletions

File tree

docs/documentation.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
522522
| `VM::VM_DEVICES` | Check for VM-specific devices | 🪟 | 50% | | | | | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L7848) |
523523
| `VM::PROCESSOR_NUMBER` | Check for number of processors | 🪟 | 50% | | | | | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L7999) |
524524
| `VM::NUMBER_OF_CORES` | Check for number of cores | 🪟 | 50% | | | | | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L8024) |
525-
| `VM::ACPI_TEMPERATURE` | Check for device's temperature | 🪟 | 25% | | | | | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L8057) |
525+
| `VM::ACPI_TEMPERATURE` | Check for device's temperature | 🪟 | 25% | | | | Disabled by default | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L8057) |
526526
| `VM::SYS_QEMU` | Check for existence of "qemu_fw_cfg" directories within /sys/module and /sys/firmware | 🐧 | 70% | | | | | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L8330) |
527527
| `VM::LSHW_QEMU` | Check for QEMU string instances with lshw command | 🐧 | 80% | | | | | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L8364) |
528528
| `VM::VIRTUAL_PROCESSORS` | Check if the number of virtual and logical processors are reported correctly by the system | 🪟 | 50% | | | | | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L8411) |
@@ -532,7 +532,7 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
532532
| `VM::AMD_THREAD_MISMATCH` | Check for AMD CPU thread count database if it matches the system's thread count | 🐧🪟🍏 | 95% | | | | | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L8871) |
533533
| `VM::NATIVE_VHD` | Check for OS being booted from a VHD container | 🪟 | 100% | | | | | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L9482) |
534534
| `VM::VIRTUAL_REGISTRY` | Check for particular object directory which is present in Sandboxie virtual environment but not in usual host systems | 🪟 | 65% | | | | Admin only needed for Linux | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L9505) |
535-
| `VM::FIRMWARE` | Check for VM signatures and patched strings by hardeners in firmware, while ensuring the BIOS serial is valid | 🐧🪟 | 100% | | | | | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L9601) |
535+
| `VM::FIRMWARE` | Check for VM signatures and patched strings by hardeners in firmware | 🐧🪟 | 100% | | | | | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L9601) |
536536
| `VM::FILE_ACCESS_HISTORY` | Check if the number of accessed files are too low for a human-managed environment | 🐧 | 15% | | | | | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L9950) |
537537
| `VM::AUDIO` | Check if any waveform-audio output devices are present in the system | 🪟 | 25% | | | | | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L9980) |
538538
| `VM::UNKNOWN_MANUFACTURER` | Check if the CPU manufacturer is not known | 🐧🪟🍏 | 50% | | | | | [link](https://github.com/kernelwernel/VMAware/blob/8cb2491b1c7d2cb7300d1d698b7c64c953b4ae75/src/vmaware.hpp#L10016) |

src/vmaware.hpp

Lines changed: 109 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7377,7 +7377,7 @@ struct VM {
73777377
* @brief Check for physical connection ports
73787378
* @category Windows
73797379
* @note original idea of using physical ports to detect VMs was suggested by @unusual-aspect (https://github.com/unusual-aspect).
7380-
* This technique is known to false flag on devices like Surface Pro.
7380+
* This technique is known to flag on devices like Surface Pro.
73817381
* @implements VM::PORT_CONNECTORS
73827382
*/
73837383
[[nodiscard]] static bool port_connectors() {
@@ -7402,6 +7402,7 @@ struct VM {
74027402
#endif
74037403
}
74047404

7405+
74057406
/**
74067407
* @brief Check for IVSHMEM device absense
74077408
* @category Windows
@@ -7430,6 +7431,7 @@ struct VM {
74307431
#endif
74317432
}
74327433

7434+
74337435
/**
74347436
* @brief Check for specific GPU string signatures related to VMs
74357437
* @category Windows
@@ -9271,7 +9273,6 @@ struct VM {
92719273
#endif
92729274
}
92739275

9274-
92759276
/**
92769277
* @brief Checks for VM signatures in firmware
92779278
* @category Windows
@@ -9411,7 +9412,7 @@ struct VM {
94119412
}
94129413
free(info);
94139414
return false;
9414-
};
9415+
};
94159416

94169417
// Check RSMB table
94179418
if (check_firmware_table(RSMB_SIG, 0UL))
@@ -9428,55 +9429,144 @@ struct VM {
94289429
(PSYSTEM_FIRMWARE_TABLE_INFORMATION)malloc(sizeof(SYSTEM_FIRMWARE_TABLE_INFORMATION));
94299430
if (!acpiEnum)
94309431
return false;
9431-
acpiEnum->ProviderSignature = ACPI_SIG;
9432+
9433+
acpiEnum->ProviderSignature = ACPI_SIG; // 'ACPI'
94329434
acpiEnum->Action = 0;
94339435
acpiEnum->TableID = 0;
94349436
acpiEnum->TableBufferLength = 0;
9437+
94359438
ULONG retLen = 0;
9436-
NTSTATUS status = ntqsi(SystemFirmwareTableInformation,
9439+
NTSTATUS status = ntqsi(
9440+
SystemFirmwareTableInformation,
94379441
acpiEnum,
94389442
sizeof(SYSTEM_FIRMWARE_TABLE_INFORMATION),
9439-
&retLen);
9443+
&retLen
9444+
);
9445+
94409446
if (status == STATUS_BUFFER_TOO_SMALL)
94419447
{
94429448
free(acpiEnum);
94439449
acpiEnum = (PSYSTEM_FIRMWARE_TABLE_INFORMATION)malloc(retLen);
94449450
if (!acpiEnum)
94459451
return false;
9452+
94469453
acpiEnum->ProviderSignature = ACPI_SIG;
94479454
acpiEnum->Action = 0;
94489455
acpiEnum->TableID = 0;
94499456
acpiEnum->TableBufferLength = retLen - sizeof(SYSTEM_FIRMWARE_TABLE_INFORMATION);
9450-
status = ntqsi(SystemFirmwareTableInformation,
9457+
9458+
status = ntqsi(
9459+
SystemFirmwareTableInformation,
94519460
acpiEnum,
94529461
retLen,
9453-
&retLen);
9462+
&retLen
9463+
);
9464+
9465+
if (NT_SUCCESS(status))
9466+
{
9467+
const DWORD* tables = (const DWORD*)acpiEnum->TableBuffer;
9468+
ULONG tableCount = acpiEnum->TableBufferLength / sizeof(DWORD);
9469+
9470+
for (ULONG i = 0; i < tableCount; ++i)
9471+
{
9472+
if (tables[i] == 'FACP')
9473+
{
9474+
PSYSTEM_FIRMWARE_TABLE_INFORMATION fadtEnum =
9475+
(PSYSTEM_FIRMWARE_TABLE_INFORMATION)malloc(sizeof(SYSTEM_FIRMWARE_TABLE_INFORMATION));
9476+
if (!fadtEnum)
9477+
break;
94549478

9455-
const PDWORD table_names = (PDWORD)calloc(0x1000, 1);
9456-
if (!table_names) {
9479+
fadtEnum->ProviderSignature = ACPI_SIG;
9480+
fadtEnum->Action = 0;
9481+
fadtEnum->TableID = tables[i];
9482+
fadtEnum->TableBufferLength = 0;
9483+
9484+
ULONG fadtLen = 0;
9485+
NTSTATUS st2 = ntqsi(
9486+
SystemFirmwareTableInformation,
9487+
fadtEnum,
9488+
sizeof(SYSTEM_FIRMWARE_TABLE_INFORMATION),
9489+
&fadtLen
9490+
);
9491+
9492+
if (st2 == STATUS_BUFFER_TOO_SMALL)
9493+
{
9494+
free(fadtEnum);
9495+
fadtEnum = (PSYSTEM_FIRMWARE_TABLE_INFORMATION)malloc(fadtLen);
9496+
if (fadtEnum)
9497+
{
9498+
fadtEnum->ProviderSignature = ACPI_SIG;
9499+
fadtEnum->Action = 0;
9500+
fadtEnum->TableID = tables[i];
9501+
fadtEnum->TableBufferLength = fadtLen - sizeof(SYSTEM_FIRMWARE_TABLE_INFORMATION);
9502+
9503+
if (NT_SUCCESS(ntqsi(
9504+
SystemFirmwareTableInformation,
9505+
fadtEnum,
9506+
fadtLen,
9507+
&fadtLen
9508+
)))
9509+
{
9510+
// https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#preferred-pm-profile-system-types
9511+
BYTE* fadtBuf = (BYTE*)fadtEnum->TableBuffer;
9512+
if (fadtBuf[45] == 0) {
9513+
debug("FIRMWARE: Preferred_PM_Profile == 0 (Unspecified)");
9514+
free(fadtEnum);
9515+
free(acpiEnum);
9516+
return true;
9517+
}
9518+
}
9519+
}
9520+
}
9521+
9522+
if (fadtEnum) free(fadtEnum);
9523+
break;
9524+
}
9525+
}
9526+
}
9527+
9528+
const PDWORD tableNames = (PDWORD)calloc(0x1000, 1);
9529+
if (!tableNames) {
94579530
free(acpiEnum);
94589531
return false;
94599532
}
94609533
const DWORD sig = 'ACPI';
9461-
const DWORD table_size = EnumSystemFirmwareTables(sig, table_names, 0x1000);
9462-
if (table_size < 4) { // Check made by dmfrpro
9534+
const DWORD bytes = EnumSystemFirmwareTables(sig, tableNames, 0x1000);
9535+
const ULONG tCount = bytes / sizeof(DWORD);
9536+
9537+
const DWORD ssdtSig = 'SSDT';
9538+
ULONG ssdtCount = 0;
9539+
for (ULONG i = 0; i < tCount; ++i) {
9540+
if (tableNames[i] == ssdtSig) ++ssdtCount;
9541+
}
9542+
if (ssdtCount == 1) {
9543+
debug("FIRMWARE: Only one SSDT table found");
9544+
free(tableNames);
9545+
free(acpiEnum);
9546+
return true;
9547+
}
9548+
9549+
// RSDT/XSDT, FADT, DSDT and RSDP (this one since it’s required as a pointer althought not being a true table)
9550+
if (tCount < 4) { // by dmfrpro
94639551
debug("FIRMWARE: not enough ACPI tables found");
9464-
free(table_names);
9552+
free(tableNames);
94659553
free(acpiEnum);
94669554
return true;
94679555
}
9556+
94689557
if (NT_SUCCESS(status)) {
9469-
const DWORD* tables = reinterpret_cast<const DWORD*>(acpiEnum->TableBuffer);
9470-
ULONG tableCount = acpiEnum->TableBufferLength / sizeof(DWORD);
9471-
for (ULONG t = 0; t < tableCount; ++t) {
9472-
if (check_firmware_table(ACPI_SIG, tables[t])) {
9473-
free(table_names);
9558+
const DWORD* tables2 = reinterpret_cast<const DWORD*>(acpiEnum->TableBuffer);
9559+
ULONG bufTableCnt = acpiEnum->TableBufferLength / sizeof(DWORD);
9560+
for (ULONG t = 0; t < bufTableCnt; ++t) {
9561+
if (check_firmware_table(ACPI_SIG, tables2[t])) {
9562+
free(tableNames);
94749563
free(acpiEnum);
94759564
return true;
94769565
}
94779566
}
94789567
}
9479-
free(table_names);
9568+
9569+
free(tableNames);
94809570
}
94819571
free(acpiEnum);
94829572

0 commit comments

Comments
 (0)