Skip to content

Commit 5e26b50

Browse files
authored
Merge pull request #115 from kernelwernel/dev
Dev
2 parents b48846a + 7e7660a commit 5e26b50

3 files changed

Lines changed: 105 additions & 95 deletions

File tree

docs/documentation.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,8 @@ VM::add_custom(50, new_technique);
311311
VMAware provides a convenient way to not only check for VMs, but also have the flexibility and freedom for the end-user to choose what techniques are used with complete control over what gets executed or not. This is handled with a flag system.
312312
313313
314-
| ID | Flag alias | Description | Cross-platform? (empty = yes) | Certainty | Admin? | GPL-3.0? | 32-bit? |
315-
| -- | ---------- | ----------- | --------------- | --------- | ------ | -------- | ------- |
314+
| Flag alias | Description | Cross-platform? (empty = yes) | Certainty | Admin? | GPL-3.0? | 32-bit? |
315+
| ---------- | ----------- | --------------- | --------- | ------ | -------- | ------- |
316316
| `VM::VMID` | Check CPUID output of manufacturer ID for known VMs/hypervisors at leaf 0 | | 100% | | | |
317317
| `VM::CPU_BRAND` | Check if CPU brand model contains any VM-specific string snippets | | 50% | | | |
318318
| `VM::HYPERVISOR_BIT` | Check if hypervisor feature bit in CPUID eax bit 31 is enabled (always false for physical CPUs) | | 100% | | | |

src/cli.cpp

Lines changed: 97 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ R"(Usage:
108108
-c | --conclusion returns the conclusion message string
109109
-l | --brand-list returns all the possible VM brand string values
110110
-n | --number returns the number of VM detection techniques it performs
111+
-t | --type returns the VM type (if a VM was found)
111112
112113
Extra:
113114
--disable-hyperv-host disable the possibility of Hyper-V default virtualisation result on host OS
@@ -223,6 +224,76 @@ SimpleVisor
223224
std::exit(0);
224225
}
225226

227+
std::string type(const std::string &brand_str) {
228+
if (brand_str.find(" or ") != std::string::npos) {
229+
return "Unknown";
230+
}
231+
232+
const std::map<const char*, const char*> type_table {
233+
{ "Xen HVM", "Hypervisor (type 1)" },
234+
{ "VMware ESX", "Hypervisor (type 1)" },
235+
{ "ACRN", "Hypervisor (type 1)" },
236+
{ "QNX hypervisor", "Hypervisor (type 1)" },
237+
{ "Microsoft Hyper-V", "Hypervisor (type 1)" },
238+
{ "Microsoft Azure Hyper-V", "Hypervisor (type 1)" },
239+
{ "Xbox NanoVisor (Hyper-V)", "Hypervisor (type 1)" },
240+
{ "KVM ", "Hypervisor (type 1)" },
241+
{ "bhyve", "Hypervisor (type 1)" },
242+
{ "KVM Hyper-V Enlightenment", "Hypervisor (type 1)" },
243+
{ "QEMU+KVM", "Hypervisor (type 1)" },
244+
{ "Intel HAXM", "Hypervisor (type 1)" },
245+
{ "Intel KGT (Trusty)", "Hypervisor (type 1)" },
246+
{ "SimpleVisor", "Hypervisor (type 1)" },
247+
248+
{ "VirtualBox", "Hypervisor (type 2)" },
249+
{ "VMware", "Hypervisor (type 2)" },
250+
{ "VMware Express", "Hypervisor (type 2)" },
251+
{ "VMware GSX", "Hypervisor (type 2)" },
252+
{ "VMware Workstation", "Hypervisor (type 2)" },
253+
{ "VMware Fusion", "Hypervisor (type 2)" },
254+
{ "Parallels", "Hypervisor (type 2)" },
255+
{ "Virtual PC", "Hypervisor (type 2)" },
256+
{ "Virtual Apple", "Hypervisor (type 2)" },
257+
{ "NetBSD NVMM", "Hypervisor (type 2)" },
258+
{ "OpenBSD VMM", "Hypervisor (type 2)" },
259+
260+
{ "Cuckoo", "Sandbox" },
261+
{ "Sandboxie", "Sandbox" },
262+
{ "Hybrid Analysis", "Sandbox" },
263+
{ "CWSandbox", "Sandbox" },
264+
{ "JoeBox", "Sandbox" },
265+
{ "Anubis", "Sandbox" },
266+
{ "Comodo", "Sandbox" },
267+
{ "ThreatExpert", "Sandbox" },
268+
269+
{ "Bochs", "Emulator" },
270+
{ "BlueStacks", "Emulator" },
271+
{ "Microsoft x86-to-ARM", "Emulator" },
272+
{ "QEMU", "Emulator" },
273+
274+
{ "Jailhouse", "Partitioning Hypervisor" },
275+
{ "Unisys s-Par", "Partitioning Hypervisor" },
276+
277+
{ "Docker", "Container" },
278+
279+
{ "Microsoft Virtual PC/Hyper-V", "Hypervisor (either type 1 or 2)" },
280+
281+
{ "Lockheed Martin LMHS", "Hypervisor (unknown type)" },
282+
283+
{ "Wine", "Compatibility layer" },
284+
285+
{ "Apple VZ", "Unknown" }
286+
};
287+
288+
auto it = type_table.find(brand_str.c_str());
289+
290+
if (it != type_table.end()) {
291+
return it->second;
292+
}
293+
294+
return "Unknown";
295+
}
296+
226297
void general(const bool hyperv_setting, const bool enable_notes) {
227298
const std::string detected = ("[ " + std::string(green) + "DETECTED" + std::string(ansi_exit) + " ]");
228299
const std::string not_detected = ("[" + std::string(red) + "NOT DETECTED" + std::string(ansi_exit) + "]");
@@ -363,6 +434,19 @@ void general(const bool hyperv_setting, const bool enable_notes) {
363434

364435
std::cout << "VM brand: " << (brand == "Unknown" ? red : green) << brand << ansi_exit << "\n";
365436

437+
if (brand.find(" or ") == std::string::npos) {
438+
const std::string brand = VM::brand(VM::MULTIPLE);
439+
const std::string type_value = type(brand);
440+
441+
std::cout << "VM type: ";
442+
443+
if (type_value == "Unknown") {
444+
std::cout << red << "Unknown" << ansi_exit << "\n";
445+
} else {
446+
std::cout << green << type_value << ansi_exit << "\n";
447+
}
448+
}
449+
366450
const char* percent_color = "";
367451
const std::uint8_t percent = (hyperv_setting ? VM::percentage(VM::ENABLE_HYPERV_HOST) : VM::percentage());
368452

@@ -443,95 +527,6 @@ void general(const bool hyperv_setting, const bool enable_notes) {
443527
return false;
444528
};
445529

446-
447-
448-
449-
450-
451-
452-
453-
454-
455-
456-
457-
458-
459-
/*
460-
461-
// container
462-
Docker
463-
464-
465-
// Either type 1 or 2
466-
Microsoft Virtual PC/Hyper-V
467-
468-
// hypervisor (unknown type)
469-
Lockheed Martin LMHS
470-
471-
472-
// type 1:
473-
VMWare vSphere, Citrix
474-
Xen Server, Microsoft Hyper-V…
475-
VMware ESXI
476-
ACRN
477-
QNX hypervisor
478-
Microsoft Hyper-V
479-
Microsoft Azure Hyper-V
480-
Xbox NanoVisor (Hyper-V)
481-
KVM
482-
bhyve
483-
KVM Hyper-V Enlightenment
484-
KVM
485-
QEMU+KVM
486-
Intel HAXM
487-
Intel KGT (Trusty)
488-
SimpleVisor
489-
490-
491-
// type 2:
492-
VirtualBox
493-
VMware
494-
VMware Express
495-
VMware GSX
496-
VMware Workstation
497-
VMware Fusion
498-
Parallels
499-
Virtual PC
500-
Virtual Apple
501-
NVMM
502-
OpenBSD VMM
503-
504-
505-
// compatibility layer
506-
Wine
507-
508-
509-
// emulator:
510-
bochs
511-
BlueStacks
512-
Microsoft x86-to-ARM
513-
QEMU
514-
515-
// sandbox
516-
Cuckoo
517-
Sandboxie
518-
Hybrid Analysis
519-
CWSandbox
520-
JoeBox
521-
Anubis (discontinued)
522-
Comodo
523-
ThreatExpert
524-
525-
// partitioning hypervisor
526-
Jailhouse
527-
Unisys s-Par
528-
529-
// unknown
530-
Apple VZ
531-
*/
532-
533-
534-
535530
const char* conclusion_color = color(percent);
536531
std::string conclusion_message = message(percent, brand);
537532

@@ -547,7 +542,7 @@ Apple VZ
547542

548543
if (hyperv_setting && diff_brand_check() && brand_vec() && enable_notes) {
549544
std::cout << note <<
550-
" If you know you are running on host, Hyper-V virtualises all applications by default within the host system. This result is in fact correct and NOT a false positive. If you do not want Hyper-V's default virtualisation in the result, run with the \"--discard-hyperv-host\" argument, or disable Hyper-V in your system. See here for more information https://github.com/kernelwernel/VMAware/issues/75\n\n";
545+
" If you know you are running on host, Hyper-V virtualises all applications by default within the host system. This result is in fact correct and NOT a false positive. If you do not want Hyper-V's default virtualisation in the result, run with the \"--disable-hyperv-host\" argument, or disable Hyper-V in your system. See here for more information https://github.com/kernelwernel/VMAware/issues/75\n\n";
551546
} else if (enable_notes) {
552547
std::cout << note <<
553548
" If you found a false positive, please make sure to create an issue at https://github.com/kernelwernel/VMAware/issues\n\n";
@@ -578,12 +573,13 @@ int main(int argc, char* argv[]) {
578573
PERCENT,
579574
CONCLUSION,
580575
NUMBER,
576+
TYPE,
581577
HYPERV,
582578
NOTES,
583579
NULL_ARG
584580
};
585581

586-
static constexpr std::array<std::pair<const char*, arg_enum>, 20> table {{
582+
static constexpr std::array<std::pair<const char*, arg_enum>, 22> table {{
587583
{ "-h", HELP },
588584
{ "-v", VERSION },
589585
{ "-d", DETECT },
@@ -593,6 +589,7 @@ int main(int argc, char* argv[]) {
593589
{ "-c", CONCLUSION },
594590
{ "-l", BRAND_LIST },
595591
{ "-n", NUMBER },
592+
{ "-t", TYPE },
596593
{ "--help", HELP },
597594
{ "--version", VERSION },
598595
{ "--detect", DETECT },
@@ -602,6 +599,7 @@ int main(int argc, char* argv[]) {
602599
{ "--conclusion", CONCLUSION },
603600
{ "--brand-list", BRAND_LIST },
604601
{ "--number", NUMBER },
602+
{ "--type", TYPE },
605603
{ "--disable-hyperv-host", HYPERV },
606604
{ "--disable-notes", NOTES }
607605
}};
@@ -669,12 +667,13 @@ int main(int argc, char* argv[]) {
669667
static_cast<std::uint8_t>(arg_bitset.test(PERCENT)) +
670668
static_cast<std::uint8_t>(arg_bitset.test(DETECT)) +
671669
static_cast<std::uint8_t>(arg_bitset.test(BRAND)) +
670+
static_cast<std::uint8_t>(arg_bitset.test(TYPE)) +
672671
static_cast<std::uint8_t>(arg_bitset.test(CONCLUSION))
673672
);
674673

675674
if (returners > 0) { // at least one of the options are set
676675
if (returners > 1) { // more than 2 options are set
677-
std::cerr << "--stdout, --percent, --detect, and --conclusion must NOT be a combination, choose only a single one\n";
676+
std::cerr << "--stdout, --percent, --detect, --brand, --type, and --conclusion must NOT be a combination, choose only a single one\n";
678677
return 1;
679678
}
680679

@@ -713,6 +712,12 @@ int main(int argc, char* argv[]) {
713712
return 0;
714713
}
715714

715+
if (arg_bitset.test(TYPE)) {
716+
const std::string brand = VM::brand(VM::MULTIPLE);
717+
std::cout << type(brand) << "\n";
718+
return 0;
719+
}
720+
716721
if (arg_bitset.test(CONCLUSION)) {
717722
std::uint8_t percent = 0;
718723

src/vmaware.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3608,7 +3608,9 @@ struct VM {
36083608
if (check_proc(_T("vmsrvc.exe")) || check_proc(_T("vmusrvc.exe"))) {
36093609
return core::add(VPC);
36103610
}
3611-
3611+
/*
3612+
removed due to potential false positives
3613+
36123614
if (
36133615
check_proc(_T("vmtoolsd.exe")) ||
36143616
check_proc(_T("vmwaretrat.exe")) ||
@@ -3620,6 +3622,7 @@ struct VM {
36203622
) {
36213623
return core::add(VMWARE);
36223624
}
3625+
*/
36233626

36243627
if (check_proc(_T("xenservice.exe")) || check_proc(_T("xsvc_depriv.exe"))) {
36253628
return core::add(XEN);
@@ -7758,6 +7761,8 @@ struct VM {
77587761
constexpr u32 nanovisor = 0x766E6258; // "Xbnv"
77597762
constexpr u32 simplevisor = 0x00766853; // " vhS"
77607763

7764+
debug("CPUID_SIGNATURE: eax = ", eax);
7765+
77617766
switch (eax) {
77627767
case hyperv: return core::add(HYPERV);
77637768
case nanovisor: return core::add(NANOVISOR);

0 commit comments

Comments
 (0)