Skip to content
Merged

Dev #124

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,6 @@ The library is:
- Contains separate MIT and GPL-3.0 compliant library header files


<br>

> [!CAUTION]
**DO NOT USE THIS LIBRARY FOR CRITICAL SOFTWARE** (i.e. anti-cheats, proprietary software, paid software, etc...)
>
> The full reason can be found [here](deprecation.md)

<br>

## Example 🧪
Expand Down Expand Up @@ -165,6 +158,7 @@ If you know a project, or if you're working on a project that uses VMAware, let
- [systemd project](https://github.com/systemd/systemd)
- mrjaxser
- [iMonket](https://github.com/PrimeMonket)
- Eric Parker's discord community

<br>

Expand Down
204 changes: 204 additions & 0 deletions assets/Hyper-X.drawio

Large diffs are not rendered by default.

Binary file added assets/Hyper-X.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed assets/hyperv_fucker.png
Binary file not shown.
1 change: 0 additions & 1 deletion docs/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,6 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
| -p | --percent | Prints the VM likeliness percentage between 0 and 100 |
| -n | --number | Prints the number of VM detection techniques it can performs |
| -t | --type | Returns the VM type (if a VM was found) |
| | --disable-hyperv-host | Disable the possibility of Hyper-V default virtualisation result on host OS (this can be used as a combination with the above commands) |
| | --disable-notes | No notes will be provided |
| | --spoofable | Allow spoofable techniques to be ran (not included by default)

Expand Down
9 changes: 9 additions & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- completely fixed all false positives due to Hyper-V artifacts with new Hyper-X mechanism
<p align="center">
<img src="assets/Hyper-X.png" align="center" title="VMAware">
<br>
</p>
<br>
<br>

- added new VM brand `Hyper-V artifacts (not an actual VM)`
25 changes: 7 additions & 18 deletions src/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,8 @@ constexpr const char* red_orange = "\x1B[38;2;247;127;40m";
constexpr const char* green_orange = "\x1B[38;2;174;197;59m";
constexpr const char* grey = "\x1B[38;2;108;108;108m";

constexpr bool ENABLE_HYPERV = true;
constexpr bool ENABLE_NOTES = true;
constexpr bool ENABLE_SPOOF = false;
constexpr bool DISABLE_HYPERV = false;
constexpr bool DISABLE_NOTES = false;
constexpr bool DISABLE_SPOOF = false;

Expand All @@ -73,7 +71,7 @@ enum arg_enum : std::uint8_t {
CONCLUSION,
NUMBER,
TYPE,
HYPERV,
HYPERV, // will be removed in the next release
NOTES,
SPOOFABLE,
NULL_ARG
Expand Down Expand Up @@ -429,7 +427,6 @@ void general() {
};

bool notes_enabled = false;
VM::enum_flags hyperv_setting;
VM::enum_flags spoofable_setting;

if (arg_bitset.test(NOTES)) {
Expand All @@ -438,12 +435,6 @@ void general() {
notes_enabled = true;
}

if (arg_bitset.test(HYPERV)) {
hyperv_setting = VM::NULL_ARG;
} else {
hyperv_setting = VM::ENABLE_HYPERV_HOST;
}

if (arg_bitset.test(SPOOFABLE)) {
spoofable_setting = VM::SPOOFABLE;
} else {
Expand Down Expand Up @@ -587,7 +578,7 @@ void general() {
}

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

if (percent == 0) { percent_color = red; }
else if (percent < 25) { percent_color = red_orange; }
Expand All @@ -597,7 +588,7 @@ void general() {

std::cout << "VM likeliness: " << percent_color << static_cast<std::uint32_t>(percent) << "%" << ansi_exit << "\n";

const bool is_detected = VM::detect(hyperv_setting, spoofable_setting);
const bool is_detected = VM::detect(spoofable_setting);

std::cout << "VM confirmation: " << (is_detected ? green : red) << std::boolalpha << is_detected << std::noboolalpha << ansi_exit << "\n";

Expand Down Expand Up @@ -645,8 +636,8 @@ void general() {
<< "\n\n";


if ((hyperv_setting == VM::ENABLE_HYPERV_HOST) && (brand == "Hyper-V artifact (not an actual VM)") && notes_enabled) {
std::cout << note << " If you know you are running on host, Hyper-V leaves VM artifacts in CPUIDs which makes the system look like it's running in a Hyper-V VM when it's not. If you want to disable this mechanism, uninstall Hyper-V in your system.\n\n";
if ((brand == "Hyper-V artifact (not an actual VM)") && notes_enabled) {
std::cout << note << "The result means that the CLI has found Hyper-V, but as an artifact instead of an actual VM. This means that although the hardware values in fact match with Hyper-V due to how it's designed by Microsoft, the CLI has determined you are NOT in a Hyper-V VM.\n\n";
} else if (notes_enabled) {
if (!arg_bitset.test(SPOOFABLE)) {
std::cout << tip << "To enable spoofable techniques, run with the \"--spoofable\" argument\n\n";
Expand Down Expand Up @@ -696,7 +687,7 @@ int main(int argc, char* argv[]) {
{ "--spoofable", SPOOFABLE }
}};

[[maybe_unused]] std::string potential_null_arg = "";
std::string potential_null_arg = "";

for (const auto arg_string : args) {
auto it = std::find_if(table.cbegin(), table.cend(), [&](const auto &p) {
Expand Down Expand Up @@ -757,9 +748,7 @@ int main(int argc, char* argv[]) {
auto settings = [&]() -> std::bitset<max_bits> {
std::bitset<max_bits> setting_bits;

if (arg_bitset.test(HYPERV) == false) {
setting_bits.set(VM::ENABLE_HYPERV_HOST);
} else {
if (arg_bitset.test(HYPERV)) {
std::cerr << "--disable-hyperv-host has been deprecated, the determination of whether it's a host Hyper-V or VM Hyper-V is now done automatically";
return 1;
}
Expand Down
46 changes: 32 additions & 14 deletions src/vmaware.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ struct VM {
// start of non-technique flags (THE ORDERING IS VERY SPECIFIC HERE AND MIGHT BREAK SOMETHING IF RE-ORDERED)
NO_MEMO,
HIGH_THRESHOLD,
ENABLE_HYPERV_HOST,
NULL_ARG, // does nothing as a placeholder
ENABLE_HYPERV_HOST [[deprecated("This mechanism is done by default as of 1.8 release")]],
NULL_ARG, // does nothing, just a placeholder flag mainly for the CLI
SPOOFABLE,
MULTIPLE
};
Expand All @@ -430,13 +430,15 @@ struct VM {
static constexpr u16 high_threshold_score = 300; // new threshold score from 100 to 350 if VM::HIGH_THRESHOLD flag is enabled
static constexpr bool SHORTCUT = true; // macro for whether VM::core::run_all() should take a shortcut by skipping the rest of the techniques if the threshold score is already met


// intended for loop indexes
static constexpr u8 enum_begin = 0;
static constexpr u8 enum_end = enum_size + 1;
static constexpr u8 technique_begin = enum_begin;
static constexpr u8 technique_end = NO_MEMO;
static constexpr u8 non_technique_begin = NO_MEMO;
static constexpr u8 non_technique_end = enum_end;
static constexpr u8 ENABLE_HYPERV_HOST_REPLACEMENT = HIGH_THRESHOLD + 1;

public:
static constexpr u8 technique_count = NO_MEMO; // get total number of techniques
Expand Down Expand Up @@ -1632,6 +1634,7 @@ struct VM {
core_debug("HYPERV_FUCKER: eax = ", eax);

if (eax == 12) {
// SMBIOS check
const std::string p = SMBIOS_string();

core_debug("HYPERV_FUCKER: SMBIOS string = ", p);
Expand All @@ -1640,18 +1643,33 @@ struct VM {
return add(false);
}


// motherboard check
const bool motherboard = motherboard_string(L"Microsoft Corporation");

core_debug("HYPERV_FUCKER: motherboard string = ", motherboard);

if (motherboard == true) {
if (motherboard) {
return add(false);
}


// event log check (slow, so in last place)
std::wstring logName = L"Microsoft-Windows-Kernel-PnP/Configuration";
std::vector<std::wstring> searchStrings = { L"Virtual_Machine", L"VMBUS" };

const bool found = util::query_event_logs(logName, searchStrings);

if (found) {
return add(false);
}

// at this point, it's fair to assume it's a Hyper-V on host

// at this point, it's fair to assume it's Hyper-V artifacts on
// host since none of the "VM-only" techniques returned true
return add(true);
} else if (eax == 11) {
// actual Hyper-V VM
// actual Hyper-V VM, might do something within this scope in the future idk
return add(false);
} else {
return add(false);
Expand Down Expand Up @@ -8604,10 +8622,10 @@ struct VM {
if (
flags.test(NO_MEMO) ||
flags.test(HIGH_THRESHOLD) ||
flags.test(ENABLE_HYPERV_HOST) ||
flags.test(SPOOFABLE) ||
flags.test(ENABLE_HYPERV_HOST_REPLACEMENT) ||
flags.test(MULTIPLE)
) {
) {
flags |= DEFAULT;
}
}
Expand Down Expand Up @@ -8891,7 +8909,7 @@ struct VM {
if (
(flag_bit == NO_MEMO) ||
(flag_bit == HIGH_THRESHOLD) ||
(flag_bit == ENABLE_HYPERV_HOST) ||
(flag_bit == ENABLE_HYPERV_HOST_REPLACEMENT) ||
(flag_bit == SPOOFABLE) ||
(flag_bit == MULTIPLE)
) {
Expand Down Expand Up @@ -9255,7 +9273,7 @@ struct VM {
flags.set(NO_MEMO, 0);
flags.set(HIGH_THRESHOLD, 0);
flags.set(SPOOFABLE, 0);
flags.set(ENABLE_HYPERV_HOST, 0);
flags.set(ENABLE_HYPERV_HOST_REPLACEMENT, 0);
flags.set(MULTIPLE, 0);

return flags;
Expand Down Expand Up @@ -9414,20 +9432,20 @@ VM::flagset VM::DEFAULT = []() -> flagset {
tmp.flip(RDTSC);
tmp.flip(RDTSC_VMEXIT);
tmp.flip(HIGH_THRESHOLD);
tmp.flip(ENABLE_HYPERV_HOST);
tmp.flip(ENABLE_HYPERV_HOST_REPLACEMENT);
tmp.flip(SPOOFABLE);
tmp.flip(MULTIPLE);

return tmp;
}();
}();


// flag to enable every technique, basically VM::DEFAULT but with VM::CURSOR technique
VM::flagset VM::ALL = []() -> flagset {
flagset tmp = DEFAULT;
tmp.set(CURSOR);
return tmp;
}();
}();


std::vector<VM::u8> VM::technique_vector = []() -> std::vector<VM::u8> {
Expand All @@ -9439,7 +9457,7 @@ std::vector<VM::u8> VM::technique_vector = []() -> std::vector<VM::u8> {
}

return tmp;
}();
}();


// check if cpuid is supported
Expand All @@ -9458,7 +9476,7 @@ bool VM::core::cpuid_supported = []() -> bool {
#else
return false;
#endif
}();
}();


// this is initialised as empty, because this is where custom techniques can be added at runtime
Expand Down
2 changes: 1 addition & 1 deletion src/vmaware_MIT.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8018,7 +8018,7 @@ information about the hypervisor Linux is running on
flag_collector.set(VM::QEMU_GA);
flag_collector.set(VM::QEMU_PROC);
flag_collector.set(VM::VPC_PROC);
flag_collector.set(VM::VM_FILES_EXTRA);
flag_collector.set(VM::VM_FILES_EXTRA)
flag_collector.set(VM::UPTIME);
flag_collector.set(VM::CUCKOO_DIR);
flag_collector.set(VM::CUCKOO_PIPE);
Expand Down