Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
kernelwernel committed Mar 17, 2024
2 parents bfc28a2 + 8a44e9a commit 23142af
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 59 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
<p align="center">
<img src="assets/banner.jpg" align="center" width="500" title="VMAware">
<br>
<img alt="GitHub Workflow Status (with event)" align="center" src="https://img.shields.io/github/actions/workflow/status/kernelwernel/VMAware/cmake-multi-platform.yml">
<img alt="GitHub" align="center" src="https://img.shields.io/github/license/kernelwernel/VMAware">
<img align="center" src="https://img.shields.io/github/actions/workflow/status/kernelwernel/VMAware/cmake-multi-platform.yml">
<img align="center" src="https://img.shields.io/github/downloads/kernelwernel/VMAware/total">
<img align="center" src="https://img.shields.io/github/license/kernelwernel/VMAware">
<img align="center" src="https://img.shields.io/github/license/kernelwernel/Tourneys-bot">
</p>

**VMAware** (VM + Aware) is a cross-platform C++ library for virtual machine detection.
Expand Down
2 changes: 1 addition & 1 deletion auxiliary/updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,4 @@ def update(filename):


update("../src/vmaware.hpp")
update("../src/vmaware_mit.hpp")
update("../src/vmaware_MIT.hpp")
2 changes: 1 addition & 1 deletion docs/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,4 +305,4 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
| `VM::NO_MEMO` | This will disable memoization, meaning the result will not be fetched through a previous computation of the `VM::detect()` function. Use this if you're only using a single function from the `VM` struct for a performance boost.
| `VM::EXTREME` | This will disregard the weights/biases and its scoring system. It will essentially treat any technique that found a hit as a VM detection no matter how low that technique's certainty is, so if a single technique is positive then it will return true. |
| `VM::DEFAULT` | This represents a range of flags which are enabled if no default argument is provided. The reason why this exists is to easily disable any bits manually (shown in the is_vm6 example in the `VM::detect()` section)
| `VM::WIN11_HYPERV` | This will take into account that Windows 11 sometimes may have Hyper-V as a default virtualisation software for any program used even if the OS is running as host. |
| `VM::WIN11_HYPERV` | This will take into account that Windows 11 sometimes may have Hyper-V as a default virtualisation software for any program even if the OS is running as host. Essentially, it will diregard any techniques prone to this issue, and NOT detect it as running in a VM, while having a higher threshold bar to detect it as a VM. |
81 changes: 43 additions & 38 deletions src/vmaware.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
* - License: GPL-3.0
*
* ================================ SECTIONS ==================================
* - enums for publicly accessible techniques => line 221
* - struct for internal cpu operations => line 377
* - struct for internal memoization => line 606
* - struct for internal utility functions => line 679
* - struct for internal core components => line 4352
* - start of internal VM detection techniques => line 1205
* - start of public VM detection functions => line 4436
* - start of externally defined variables => line 4669
* - enums for publicly accessible techniques => line 226
* - struct for internal cpu operations => line 393
* - struct for internal memoization => line 622
* - struct for internal utility functions => line 695
* - struct for internal core components => line 4977
* - start of internal VM detection techniques => line 1336
* - start of public VM detection functions => line 5062
* - start of externally defined variables => line 5295
*/

#if (defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__))
Expand Down Expand Up @@ -589,29 +589,29 @@ struct VM {
const bool found = (std::find(std::begin(IDs), std::end(IDs), brand) != std::end(IDs));

if (found) {
if (brand == qemu) { return core::add(QEMU); }
if (brand == vmware) { return core::add(VMWARE); }
if (brand == vbox) { return core::add(VBOX); }
if (brand == bhyve) { return core::add(BHYVE); }
if (brand == kvm) { return core::add(KVM); }
if (brand == hyperv) { return core::add(HYPERV); }
if (brand == xta) { return core::add(MSXTA); }
if (brand == parallels) { return core::add(PARALLELS); }
if (brand == qemu) { return core::add(QEMU); }
if (brand == vmware) { return core::add(VMWARE); }
if (brand == vbox) { return core::add(VBOX); }
if (brand == bhyve) { return core::add(BHYVE); }
if (brand == kvm) { return core::add(KVM); }
if (brand == hyperv) { return core::add(HYPERV); }
if (brand == xta) { return core::add(MSXTA); }
if (brand == parallels) { return core::add(PARALLELS); }
if (brand == parallels2) { return core::add(PARALLELS); }
if (brand == xen) { return core::add(XEN); }
if (brand == acrn) { return core::add(ACRN); }
if (brand == qnx) { return core::add(QNX); }
if (brand == virtapple) { return core::add(VAPPLE); }
if (brand == xen) { return core::add(XEN); }
if (brand == acrn) { return core::add(ACRN); }
if (brand == qnx) { return core::add(QNX); }
if (brand == virtapple) { return core::add(VAPPLE); }
}

/**
* This is added because there are inconsistent string
* values for KVM's manufacturer ID. For example,
* it gives as "KVMKMVMKV" when I run it under QEMU
* it gives me "KVMKMVMKV" when I run it under QEMU
* but the Wikipedia article on CPUID says it's
* "KVMKVMKVM\0\0\0", like wtf????
*/
if (brand.find("KVM") != std::string::npos) {
if (util::find(brand, "KVM")) {
return core::add(KVM);
}

Expand All @@ -624,23 +624,23 @@ struct VM {
private:
// memoization structure
MSVC_DISABLE_WARNING(4820)
struct memo_struct {
struct cache_struct {
std::string get_brand;
u8 get_percent;
bool get_vm;

// Default constructor
memo_struct() : get_brand("Unknown"), get_percent(0), get_vm(false) {}
cache_struct() : get_brand("Unknown"), get_percent(0), get_vm(false) {}

// Constructor to initialize the members
memo_struct(const std::string& brand, u8 percent, bool is_vm)
cache_struct(const std::string& brand, u8 percent, bool is_vm)
: get_brand(brand), get_percent(percent), get_vm(is_vm) {}
};
MSVC_ENABLE_WARNING(4820)

public:
// memoize the value from VM::detect() in case it's ran again
static std::map<bool, memo_struct> cache;
static std::map<bool, cache_struct> cache;

// easier way to check if the result is memoized
[[nodiscard]] static inline bool is_memoized() noexcept {
Expand All @@ -652,19 +652,19 @@ struct VM {

// get vm bool
static bool get_vm() {
memo_struct& tmp = cache.at(true);
cache_struct& tmp = cache.at(true);
return tmp.get_vm;
}

// get vm brand
static std::string get_brand() {
memo_struct& tmp = cache.at(true);
cache_struct& tmp = cache.at(true);
return tmp.get_brand;
}

// get vm percentage
static u8 get_percent() {
memo_struct& tmp = cache.at(true);
cache_struct& tmp = cache.at(true);
return tmp.get_percent;
}

Expand All @@ -687,7 +687,7 @@ struct VM {
std::string local_vm_brand = (p_flags & FOUND_BRAND) ? vm_brand : brand(NO_MEMO);
u8 local_vm_percent = (p_flags & FOUND_PERCENT) ? vm_percent : percentage(NO_MEMO);

memo_struct tmp(local_vm_brand, local_vm_percent, local_is_vm);
cache_struct tmp(local_vm_brand, local_vm_percent, local_is_vm);
cache[true] = tmp;
}
};
Expand Down Expand Up @@ -1499,7 +1499,7 @@ struct VM {
return false;
}

#if (!x86)
#if (!x86 || MSVC)
return false;
#else
u32 a, b, c, d = 0;
Expand Down Expand Up @@ -2382,7 +2382,6 @@ struct VM {
* @brief Check if the mouse coordinates have changed after 5 seconds
* @note Some VMs are automatic without a human due to mass malware scanning being a thing
* @note Disabled by default due to performance reasons
* @note Doing this on linux is a major pain bc it requires X11 linkage and it isn't universally supported
* @category Windows
*/
[[nodiscard]] static bool cursor_check() try {
Expand Down Expand Up @@ -2463,7 +2462,7 @@ struct VM {
u8 vbox = 0;
u8 vmware = 0;

constexpr std::array<const TCHAR*, 26> files = { {
constexpr std::array<const TCHAR*, 25> files = { {
// VMware
_T("C:\\windows\\System32\\Drivers\\Vmmouse.sys"),
_T("C:\\windows\\System32\\Drivers\\vm3dgl.dll"),
Expand Down Expand Up @@ -5199,9 +5198,10 @@ struct VM {
constexpr const char* TMP_KVM = VM::KVM;
#endif

if (
(core::scoreboard.at(TMP_QEMU) > 0) &&
(core::scoreboard.at(TMP_KVM) > 0)
if (core::scoreboard.contains(TMP_QEMU) &&
core::scoreboard.contains(TMP_KVM) &&
core::scoreboard.at(TMP_QEMU) > 0 &&
core::scoreboard.at(TMP_KVM) > 0
) {
current_brand = "QEMU+KVM";
}
Expand Down Expand Up @@ -5330,16 +5330,21 @@ MSVC_ENABLE_WARNING(4626 4514)
};


std::map<bool, VM::memo::memo_struct> VM::memo::cache;
std::map<bool, VM::memo::cache_struct> VM::memo::cache;

VM::flagset VM::flags = 0;

VM::flagset VM::DEFAULT = []() -> flagset {
flagset tmp;
tmp.set(); // set all bits to 1

// set all bits to 1
tmp.set();

// disable all the non-default flags
tmp.flip(EXTREME);
tmp.flip(NO_MEMO);
tmp.flip(CURSOR);
tmp.flip(WIN11_HYPERV);
return tmp;
}();

Expand Down
35 changes: 18 additions & 17 deletions src/vmaware_MIT.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* - @Requiem (https://github.com/NotRequiem)
* - @Alex (https://github.com/greenozon)
* - @Marek Knápek (https://github.com/MarekKnapek)
* - @Vladyslav Miachkov (https://github.com/fameowner99)
* - Repository: https://github.com/kernelwernel/VMAware
* - Docs: https://github.com/kernelwernel/VMAware/docs/documentation.md
* - Full credits: https://github.com/kernelwernel/VMAware#credits
Expand All @@ -39,14 +40,14 @@
* SOFTWARE.
*
* ================================ SECTIONS ==================================
* - enums for publicly accessible techniques => line 219
* - struct for internal cpu operations => line 365
* - struct for internal memoization => line 594
* - struct for internal utility functions => line 667
* - struct for internal core components => line 3934
* - start of internal VM detection techniques => line 1231
* - start of public VM detection functions => line 4018
* - start of externally defined variables => line 4251
* - enums for publicly accessible techniques => line 239
* - struct for internal cpu operations => line 385
* - struct for internal memoization => line 614
* - struct for internal utility functions => line 687
* - struct for internal core components => line 3954
* - start of internal VM detection techniques => line 1251
* - start of public VM detection functions => line 4038
* - start of externally defined variables => line 4271
*/

#if (defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__))
Expand Down Expand Up @@ -616,23 +617,23 @@ struct VM {
private:
// memoization structure
MSVC_DISABLE_WARNING(4820)
struct memo_struct {
struct cache_struct {
std::string get_brand;
u8 get_percent;
bool get_vm;

// Default constructor
memo_struct() : get_brand("Unknown"), get_percent(0), get_vm(false) {}
cache_struct() : get_brand("Unknown"), get_percent(0), get_vm(false) {}

// Constructor to initialize the members
memo_struct(const std::string& brand, u8 percent, bool is_vm)
cache_struct(const std::string& brand, u8 percent, bool is_vm)
: get_brand(brand), get_percent(percent), get_vm(is_vm) {}
};
MSVC_ENABLE_WARNING(4820)

public:
// memoize the value from VM::detect() in case it's ran again
static std::map<bool, memo_struct> cache;
static std::map<bool, cache_struct> cache;

// easier way to check if the result is memoized
[[nodiscard]] static inline bool is_memoized() noexcept {
Expand All @@ -644,19 +645,19 @@ struct VM {

// get vm bool
static bool get_vm() {
memo_struct& tmp = cache.at(true);
cache_struct& tmp = cache.at(true);
return tmp.get_vm;
}

// get vm brand
static std::string get_brand() {
memo_struct& tmp = cache.at(true);
cache_struct& tmp = cache.at(true);
return tmp.get_brand;
}

// get vm percentage
static u8 get_percent() {
memo_struct& tmp = cache.at(true);
cache_struct& tmp = cache.at(true);
return tmp.get_percent;
}

Expand All @@ -679,7 +680,7 @@ struct VM {
std::string local_vm_brand = (p_flags & FOUND_BRAND) ? vm_brand : brand(NO_MEMO);
u8 local_vm_percent = (p_flags & FOUND_PERCENT) ? vm_percent : percentage(NO_MEMO);

memo_struct tmp(local_vm_brand, local_vm_percent, local_is_vm);
cache_struct tmp(local_vm_brand, local_vm_percent, local_is_vm);
cache[true] = tmp;
}
};
Expand Down Expand Up @@ -4305,7 +4306,7 @@ MSVC_ENABLE_WARNING(4626 4514)
};


std::map<bool, VM::memo::memo_struct> VM::memo::cache;
std::map<bool, VM::memo::cache_struct> VM::memo::cache;

VM::flagset VM::flags = 0;

Expand Down

0 comments on commit 23142af

Please sign in to comment.