Skip to content

Commit

Permalink
Merge pull request #115 from kernelwernel/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
kernelwernel authored Aug 1, 2024
2 parents b48846a + 7e7660a commit 5e26b50
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 95 deletions.
4 changes: 2 additions & 2 deletions docs/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ VM::add_custom(50, new_technique);
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.
| ID | Flag alias | Description | Cross-platform? (empty = yes) | Certainty | Admin? | GPL-3.0? | 32-bit? |
| -- | ---------- | ----------- | --------------- | --------- | ------ | -------- | ------- |
| Flag alias | Description | Cross-platform? (empty = yes) | Certainty | Admin? | GPL-3.0? | 32-bit? |
| ---------- | ----------- | --------------- | --------- | ------ | -------- | ------- |
| `VM::VMID` | Check CPUID output of manufacturer ID for known VMs/hypervisors at leaf 0 | | 100% | | | |
| `VM::CPU_BRAND` | Check if CPU brand model contains any VM-specific string snippets | | 50% | | | |
| `VM::HYPERVISOR_BIT` | Check if hypervisor feature bit in CPUID eax bit 31 is enabled (always false for physical CPUs) | | 100% | | | |
Expand Down
189 changes: 97 additions & 92 deletions src/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ R"(Usage:
-c | --conclusion returns the conclusion message string
-l | --brand-list returns all the possible VM brand string values
-n | --number returns the number of VM detection techniques it performs
-t | --type returns the VM type (if a VM was found)
Extra:
--disable-hyperv-host disable the possibility of Hyper-V default virtualisation result on host OS
Expand Down Expand Up @@ -223,6 +224,76 @@ SimpleVisor
std::exit(0);
}

std::string type(const std::string &brand_str) {
if (brand_str.find(" or ") != std::string::npos) {
return "Unknown";
}

const std::map<const char*, const char*> type_table {
{ "Xen HVM", "Hypervisor (type 1)" },
{ "VMware ESX", "Hypervisor (type 1)" },
{ "ACRN", "Hypervisor (type 1)" },
{ "QNX hypervisor", "Hypervisor (type 1)" },
{ "Microsoft Hyper-V", "Hypervisor (type 1)" },
{ "Microsoft Azure Hyper-V", "Hypervisor (type 1)" },
{ "Xbox NanoVisor (Hyper-V)", "Hypervisor (type 1)" },
{ "KVM ", "Hypervisor (type 1)" },
{ "bhyve", "Hypervisor (type 1)" },
{ "KVM Hyper-V Enlightenment", "Hypervisor (type 1)" },
{ "QEMU+KVM", "Hypervisor (type 1)" },
{ "Intel HAXM", "Hypervisor (type 1)" },
{ "Intel KGT (Trusty)", "Hypervisor (type 1)" },
{ "SimpleVisor", "Hypervisor (type 1)" },

{ "VirtualBox", "Hypervisor (type 2)" },
{ "VMware", "Hypervisor (type 2)" },
{ "VMware Express", "Hypervisor (type 2)" },
{ "VMware GSX", "Hypervisor (type 2)" },
{ "VMware Workstation", "Hypervisor (type 2)" },
{ "VMware Fusion", "Hypervisor (type 2)" },
{ "Parallels", "Hypervisor (type 2)" },
{ "Virtual PC", "Hypervisor (type 2)" },
{ "Virtual Apple", "Hypervisor (type 2)" },
{ "NetBSD NVMM", "Hypervisor (type 2)" },
{ "OpenBSD VMM", "Hypervisor (type 2)" },

{ "Cuckoo", "Sandbox" },
{ "Sandboxie", "Sandbox" },
{ "Hybrid Analysis", "Sandbox" },
{ "CWSandbox", "Sandbox" },
{ "JoeBox", "Sandbox" },
{ "Anubis", "Sandbox" },
{ "Comodo", "Sandbox" },
{ "ThreatExpert", "Sandbox" },

{ "Bochs", "Emulator" },
{ "BlueStacks", "Emulator" },
{ "Microsoft x86-to-ARM", "Emulator" },
{ "QEMU", "Emulator" },

{ "Jailhouse", "Partitioning Hypervisor" },
{ "Unisys s-Par", "Partitioning Hypervisor" },

{ "Docker", "Container" },

{ "Microsoft Virtual PC/Hyper-V", "Hypervisor (either type 1 or 2)" },

{ "Lockheed Martin LMHS", "Hypervisor (unknown type)" },

{ "Wine", "Compatibility layer" },

{ "Apple VZ", "Unknown" }
};

auto it = type_table.find(brand_str.c_str());

if (it != type_table.end()) {
return it->second;
}

return "Unknown";
}

void general(const bool hyperv_setting, const bool enable_notes) {
const std::string detected = ("[ " + std::string(green) + "DETECTED" + std::string(ansi_exit) + " ]");
const std::string not_detected = ("[" + std::string(red) + "NOT DETECTED" + std::string(ansi_exit) + "]");
Expand Down Expand Up @@ -363,6 +434,19 @@ void general(const bool hyperv_setting, const bool enable_notes) {

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

if (brand.find(" or ") == std::string::npos) {
const std::string brand = VM::brand(VM::MULTIPLE);
const std::string type_value = type(brand);

std::cout << "VM type: ";

if (type_value == "Unknown") {
std::cout << red << "Unknown" << ansi_exit << "\n";
} else {
std::cout << green << type_value << ansi_exit << "\n";
}
}

const char* percent_color = "";
const std::uint8_t percent = (hyperv_setting ? VM::percentage(VM::ENABLE_HYPERV_HOST) : VM::percentage());

Expand Down Expand Up @@ -443,95 +527,6 @@ void general(const bool hyperv_setting, const bool enable_notes) {
return false;
};














/*
// container
Docker
// Either type 1 or 2
Microsoft Virtual PC/Hyper-V
// hypervisor (unknown type)
Lockheed Martin LMHS
// type 1:
VMWare vSphere, Citrix
Xen Server, Microsoft Hyper-V…
VMware ESXI
ACRN
QNX hypervisor
Microsoft Hyper-V
Microsoft Azure Hyper-V
Xbox NanoVisor (Hyper-V)
KVM
bhyve
KVM Hyper-V Enlightenment
KVM
QEMU+KVM
Intel HAXM
Intel KGT (Trusty)
SimpleVisor
// type 2:
VirtualBox
VMware
VMware Express
VMware GSX
VMware Workstation
VMware Fusion
Parallels
Virtual PC
Virtual Apple
NVMM
OpenBSD VMM
// compatibility layer
Wine
// emulator:
bochs
BlueStacks
Microsoft x86-to-ARM
QEMU
// sandbox
Cuckoo
Sandboxie
Hybrid Analysis
CWSandbox
JoeBox
Anubis (discontinued)
Comodo
ThreatExpert
// partitioning hypervisor
Jailhouse
Unisys s-Par
// unknown
Apple VZ
*/



const char* conclusion_color = color(percent);
std::string conclusion_message = message(percent, brand);

Expand All @@ -547,7 +542,7 @@ Apple VZ

if (hyperv_setting && diff_brand_check() && brand_vec() && enable_notes) {
std::cout << note <<
" 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";
" 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";
} else if (enable_notes) {
std::cout << note <<
" If you found a false positive, please make sure to create an issue at https://github.com/kernelwernel/VMAware/issues\n\n";
Expand Down Expand Up @@ -578,12 +573,13 @@ int main(int argc, char* argv[]) {
PERCENT,
CONCLUSION,
NUMBER,
TYPE,
HYPERV,
NOTES,
NULL_ARG
};

static constexpr std::array<std::pair<const char*, arg_enum>, 20> table {{
static constexpr std::array<std::pair<const char*, arg_enum>, 22> table {{
{ "-h", HELP },
{ "-v", VERSION },
{ "-d", DETECT },
Expand All @@ -593,6 +589,7 @@ int main(int argc, char* argv[]) {
{ "-c", CONCLUSION },
{ "-l", BRAND_LIST },
{ "-n", NUMBER },
{ "-t", TYPE },
{ "--help", HELP },
{ "--version", VERSION },
{ "--detect", DETECT },
Expand All @@ -602,6 +599,7 @@ int main(int argc, char* argv[]) {
{ "--conclusion", CONCLUSION },
{ "--brand-list", BRAND_LIST },
{ "--number", NUMBER },
{ "--type", TYPE },
{ "--disable-hyperv-host", HYPERV },
{ "--disable-notes", NOTES }
}};
Expand Down Expand Up @@ -669,12 +667,13 @@ int main(int argc, char* argv[]) {
static_cast<std::uint8_t>(arg_bitset.test(PERCENT)) +
static_cast<std::uint8_t>(arg_bitset.test(DETECT)) +
static_cast<std::uint8_t>(arg_bitset.test(BRAND)) +
static_cast<std::uint8_t>(arg_bitset.test(TYPE)) +
static_cast<std::uint8_t>(arg_bitset.test(CONCLUSION))
);

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

Expand Down Expand Up @@ -713,6 +712,12 @@ int main(int argc, char* argv[]) {
return 0;
}

if (arg_bitset.test(TYPE)) {
const std::string brand = VM::brand(VM::MULTIPLE);
std::cout << type(brand) << "\n";
return 0;
}

if (arg_bitset.test(CONCLUSION)) {
std::uint8_t percent = 0;

Expand Down
7 changes: 6 additions & 1 deletion src/vmaware.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3608,7 +3608,9 @@ struct VM {
if (check_proc(_T("vmsrvc.exe")) || check_proc(_T("vmusrvc.exe"))) {
return core::add(VPC);
}

/*
removed due to potential false positives
if (
check_proc(_T("vmtoolsd.exe")) ||
check_proc(_T("vmwaretrat.exe")) ||
Expand All @@ -3620,6 +3622,7 @@ struct VM {
) {
return core::add(VMWARE);
}
*/

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

debug("CPUID_SIGNATURE: eax = ", eax);

switch (eax) {
case hyperv: return core::add(HYPERV);
case nanovisor: return core::add(NANOVISOR);
Expand Down

0 comments on commit 5e26b50

Please sign in to comment.