From e61d37c4d3b5058ab086fe29811fb2dddfd704ab Mon Sep 17 00:00:00 2001
From: kernel <77142078+kernelwernel@users.noreply.github.com>
Date: Wed, 16 Oct 2024 00:08:51 +0100
Subject: [PATCH] slight changes for ci/cd
---
docs/documentation.md | 17 ++++---
src/cli.cpp | 26 ++++++++++-
src/vmaware.hpp | 100 +++++++++++++++++++++++-------------------
3 files changed, 92 insertions(+), 51 deletions(-)
diff --git a/docs/documentation.md b/docs/documentation.md
index 85353f4..32043a1 100644
--- a/docs/documentation.md
+++ b/docs/documentation.md
@@ -48,16 +48,16 @@ int main() {
/**
* There are roughly 1/3 of all techniques that are considered to be "spoofable",
* meaning that anybody can potentially cause a false positive by exploiting the
- * fact that the "spoofable" techniques checks for things that anybody can modify
- * (file, registry, directories, etc...). This category of techniques are disabled
+ * fact that the spoofable techniques checks for things that anybody can modify
+ * (file data, registry, directories, etc...). This category of techniques are disabled
* by default, but they can be enabled with the VM::SPOOFABLE flag.
*/
bool is_vm4 = VM::detect(VM::SPOOFABLE);
/**
- * All checks are performed including SPOOFABLE techniques
- * and the cursor check, which waits 5 seconds for any human
+ * All checks are performed including spoofable techniques
+ * and a few techniques that are disabled by default, which waits 5 seconds for any human
* mouse interaction to detect automated virtual environments.
* If you're fine with having a 5 second delay, add VM::ALL
*/
@@ -123,9 +123,9 @@ int main() {
if (percent == 100) {
std::cout << "Definitely a VM!\n";
} else if (percent == 0) {
- std::cout << "Definitely NOT a VM";
+ std::cout << "Definitely NOT a VM\n";
} else {
- std::cout << "Unsure if it's a VM";
+ std::cout << "Unsure if it's a VM\n";
}
// converted to std::uint32_t for console character encoding reasons
@@ -343,6 +343,11 @@ This will return the "conclusion" message of what the overall result is as a `st
+## `VM::detected_count()`
+This will fetch the number of techniques that have been detected as a `std::uint8_t`. Can't get any more simpler than that ¯\_(ツ)_/¯
+
+
+
# vmaware struct
If you prefer having an object to store all the relevant information about the program's environment instead of calling static member functions, you can use the `VM::vmaware` struct:
diff --git a/src/cli.cpp b/src/cli.cpp
index 1f756a5..49f53cf 100644
--- a/src/cli.cpp
+++ b/src/cli.cpp
@@ -26,7 +26,30 @@
#include
#include
#include
+#include
+#include
+void checkXsetbvVmException() {
+ UINT64 xcr0 = _xgetbv(0);
+
+ __try {
+ _xsetbv(0, xcr0 & ~1);
+
+ std::cout << "No exception occurred. Likely running on bare metal.\n";
+
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) {
+ std::cout << "Exception caught! VM likely detected (GP fault triggered).\n";
+ }
+}
+
+int main() {
+ checkXsetbvVmException();
+
+ return 0;
+}
+
+/*
#if (defined(__GNUC__) || defined(__linux__))
#include
#define LINUX 1
@@ -755,4 +778,5 @@ int main(int argc, char* argv[]) {
// at this point, it's assumed that the user's intention is for the general summary to be ran
general();
return 0;
-}
\ No newline at end of file
+}
+*/
\ No newline at end of file
diff --git a/src/vmaware.hpp b/src/vmaware.hpp
index 7401967..856318f 100644
--- a/src/vmaware.hpp
+++ b/src/vmaware.hpp
@@ -570,6 +570,8 @@ struct VM {
static constexpr const char* WSL = "WSL";
static constexpr const char* OPENVZ = "OpenVZ";
static constexpr const char* ANYRUN = "ANY.RUN";
+ static constexpr const char* NULL_BRAND = "";
+
static flagset global_flags; // for certain techniques where the flags MUST be accessible
@@ -1150,6 +1152,7 @@ struct VM {
static void store(const hyperx_state p_state) {
state = p_state;
+ cached = true;
}
static bool is_cached() {
@@ -1930,7 +1933,7 @@ struct VM {
* the Hyper-X mechanism comes into play to distinguish between these two.
* @author idea by Requiem (https://github.com/NotRequiem)
* @returns boolean, true = Hyper-V artifact, false = Real Hyper-V VM
- * @link graph to explain how this works: https://github.com/kernelwernel/VMAware/blob/main/assets/Hyper-X_version_3.png
+ * @link graph to explain how this works: https://github.com/kernelwernel/VMAware/blob/main/assets/hyper-x/v4/Hyper-X_version_4.drawio.png
*/
[[nodiscard]] static bool hyper_x() {
#if (!MSVC)
@@ -3956,40 +3959,35 @@ struct VM {
/* GPL */ #if (!MSVC)
/* GPL */ return false;
/* GPL */ #else
-/* GPL */ HMODULE hDll;
-/* GPL */
-/* GPL */ constexpr std::array szDlls = {{
-/* GPL */ "avghookx.dll", // AVG
-/* GPL */ "avghooka.dll", // AVG
-/* GPL */ "snxhk.dll", // Avast
-/* GPL */ "sbiedll.dll", // Sandboxie
-/* GPL */ "dbghelp.dll", // WindBG
-/* GPL */ "api_log.dll", // iDefense Lab
-/* GPL */ "dir_watch.dll", // iDefense Lab
-/* GPL */ "pstorec.dll", // SunBelt CWSandbox
-/* GPL */ "vmcheck.dll", // Virtual PC
-/* GPL */ "wpespy.dll", // WPE Pro
-/* GPL */ "cmdvrt64.dll", // Comodo Container
-/* GPL */ "cmdvrt32.dll" // Comodo Container
-/* GPL */ }};
-/* GPL */
-/* GPL */ for (const auto& key : szDlls) {
-/* GPL */ const char* dll = key;
-/* GPL */
-/* GPL */ hDll = GetModuleHandleA(dll); // Use GetModuleHandleA for ANSI strings
-/* GPL */
-/* GPL */ if (hDll != NULL && dll != NULL) {
-/* GPL */ if (strcmp(dll, "sbiedll.dll") == 0) { return core::add(SANDBOXIE); }
-/* GPL */ if (strcmp(dll, "pstorec.dll") == 0) { return core::add(CWSANDBOX); }
-/* GPL */ if (strcmp(dll, "vmcheck.dll") == 0) { return core::add(VPC); }
-/* GPL */ if (strcmp(dll, "cmdvrt32.dll") == 0) { return core::add(COMODO); }
-/* GPL */ if (strcmp(dll, "cmdvrt64.dll") == 0) { return core::add(COMODO); }
-/* GPL */
-/* GPL */ return true;
-/* GPL */ }
+/* GPL */ std::unordered_map dllMap = {
+/* GPL */ { "sbiedll.dll", SANDBOXIE }, // Sandboxie
+/* GPL */ { "pstorec.dll", CWSANDBOX }, // CWSandbox
+/* GPL */ { "vmcheck.dll", VPC }, // VirtualPC
+/* GPL */ { "cmdvrt32.dll", COMODO }, // Comodo
+/* GPL */ { "cmdvrt64.dll", COMODO }, // Comodo
+/* GPL */ { "dbghelp.dll", NULL_BRAND }, // WindBG
+/* GPL */ { "avghookx.dll", NULL_BRAND }, // AVG
+/* GPL */ { "avghooka.dll", NULL_BRAND }, // AVG
+/* GPL */ { "snxhk.dll", NULL_BRAND }, // Avast
+/* GPL */ { "api_log.dll", NULL_BRAND }, // iDefense Lab
+/* GPL */ { "dir_watch.dll", NULL_BRAND }, // iDefense Lab
+/* GPL */ { "pstorec.dll", NULL_BRAND }, // SunBelt CWSandbox
+/* GPL */ { "vmcheck.dll", NULL_BRAND }, // Virtual PC
+/* GPL */ { "wpespy.dll", NULL_BRAND } // WPE Pro
/* GPL */ }
-/* GPL */
-/* GPL */ return false;
+/* GPL */
+/* GPL */ for (const auto& key : dllMap) {
+/* GPL */ hDll = GetModuleHandleA(key);
+/* GPL */
+/* GPL */ if (hDll != NULL) {
+/* GPL */ auto it = dllMap.find(key);
+/* GPL */ if (it != dllMap.end()) {
+/* GPL */ return core::add(it->second);
+/* GPL */ }
+/* GPL */ }
+/* GPL */ }
+/* GPL */
+/* GPL */ return false;
/* GPL */ #endif
/* GPL */ }
/* GPL */ catch (...) {
@@ -5436,22 +5434,22 @@ struct VM {
u32 idt_entry = 0;
#if (MSVC)
-#if (x86_32)
+# if (x86_32)
_asm sidt idtr
-#elif (x86)
-#pragma pack(1)
+# elif (x86)
+# pragma pack(1)
struct IDTR {
u16 limit;
u64 base;
};
-#pragma pack()
+# pragma pack()
IDTR idtrStruct;
__sidt(&idtrStruct);
std::memcpy(idtr, &idtrStruct, sizeof(IDTR));
-#else
+# else
return false;
-#endif
+# endif
idt_entry = *reinterpret_cast(&idtr[2]);
#elif (LINUX)
@@ -9532,7 +9530,9 @@ struct VM {
* @return bool
* @link https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#vmcheck
*/
- [[nodiscard]] static bool check(const enum_flags flag_bit
+ [[nodiscard]] static bool check(
+ const enum_flags flag_bit,
+ const enum_flags memo_arg = NULL_ARG
// clang doesn't support std::source_location for some reason
#if (CPP >= 20 && !CLANG)
, const std::source_location& loc = std::source_location::current()
@@ -9563,12 +9563,21 @@ struct VM {
throw_error("Flag argument must be a technique flag and not a settings flag");
}
+ if (
+ (memo_arg != NO_MEMO) &&
+ (memo_arg != NULL_ARG)
+ ) {
+ throw_error("Flag argument for memoization must be either VM::NO_MEMO or left empty");
+ }
+
+ const bool is_memoized = (memo_arg != NO_MEMO);
+
#if (CPP >= 23)
[[assume(flag_bit < technique_end)]];
#endif
// if the technique is already cached, return the cached value instead
- if (memo::is_cached(flag_bit)) {
+ if (memo::is_cached(flag_bit) && is_memoized) {
const memo::data_t data = memo::cache_fetch(flag_bit);
return data.result;
}
@@ -9592,7 +9601,9 @@ struct VM {
#endif
// store the technique result in the cache table
- memo::cache_store(flag_bit, result, pair.points);
+ if (is_memoized) {
+ memo::cache_store(flag_bit, result, pair.points);
+ }
return result;
}
@@ -10423,7 +10434,8 @@ std::map VM::core::brand_scoreboard{
{ VM::PODMAN, 0 },
{ VM::WSL, 0 },
{ VM::OPENVZ, 0 },
- { VM::ANYRUN, 0 }
+ { VM::ANYRUN, 0 },
+ { VM::NULL_BRAND, 0 }
};