Skip to content

Commit

Permalink
hyper-x v4
Browse files Browse the repository at this point in the history
  • Loading branch information
kernelwernel committed Oct 12, 2024
1 parent d21c0c4 commit 568445f
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 35 deletions.
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
- [ ] /sys/class/dmi/id/product_name check this in qemu
- [ ] update sourceforge
- [X] fix the VM::vmaware struct

- [ ] do the ACPI technique and add it to hyper-x

# Distant plans
- add the library to conan.io when released
Expand Down
103 changes: 69 additions & 34 deletions src/vmaware.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,7 @@ struct VM {

struct hyperx {
static hyperx_state state;
static bool cached;

static hyperx_state fetch() {
return state;
Expand All @@ -1151,7 +1152,7 @@ struct VM {
}

static bool is_cached() {
return (state != hyperx_state::UNKNOWN);
return cached;
}
};
};
Expand Down Expand Up @@ -1722,15 +1723,25 @@ struct VM {
// SMBIOS check
auto is_smbios_hyperv = []() -> bool {
const std::string smbios = SMBIOS_string();
core_debug("HYPER_X: SMBIOS string = ", smbios);
return (smbios == "VIRTUAL MACHINE");
const bool result = (smbios == "VIRTUAL MACHINE");

if (result) {
core_debug("HYPER_X: SMBIOS string = ", smbios);
core_debug("HYPER_X: SMBIOS string returned true");
}

return result;
};


// motherboard check
auto is_motherboard_hyperv = []() -> bool {
const bool motherboard = motherboard_string(L"Microsoft Corporation");
core_debug("HYPER_X: motherboard string match = ", motherboard);

if (motherboard) {
core_debug("HYPER_X: motherboard string match = ", motherboard);
}

return motherboard;
};

Expand All @@ -1739,7 +1750,13 @@ struct VM {
auto is_event_log_hyperv = []() -> bool {
std::wstring logName = L"Microsoft-Windows-Kernel-PnP/Configuration";
std::vector<std::wstring> searchStrings = { L"Virtual_Machine", L"VMBUS" };
return (util::query_event_logs(logName, searchStrings));
const bool result = (util::query_event_logs(logName, searchStrings));

if (result) {
core_debug("HYPER_X: event log returned true");
}

return result;
};


Expand All @@ -1758,57 +1775,74 @@ struct VM {


// check if eax is either 11 or 12 after running VM::HYPERVISOR_STR technique
auto eax = []() -> bool {
auto eax = []() -> u32 {
char out[sizeof(int32_t) * 4 + 1] = { 0 }; // e*x size + number of e*x registers + null terminator
cpu::cpuid((int*)out, cpu::leaf::hypervisor);

const u32 eax = static_cast<u32>(out[0]);

core_debug("HYPER_X: eax = ", eax);

return ((eax == 11) || (eax == 12));
return eax;
};

const bool eax_result = eax();
bool run_mechanism = false;

// neither an artifact nor a real VM
if (!eax_result) {
core_debug("HYPER_X: none detected");
memo::hyperx::store(hyperx_state::UNKNOWN);
return false;
switch (eax()) {
case 11: run_mechanism = false; break; // real hyper-v vm
case 12: run_mechanim = true; break; // artifact hyper-v vm
default:
// fallback in case eax fails
if (is_root_partition()) {
run_mechanism = true;
}
}

const bool has_hyperv_indications = (
is_smbios_hyperv() ||
is_motherboard_hyperv() ||
is_event_log_hyperv() ||
is_root_partition()
);

const bool is_real_hyperv_vm = (eax_result && has_hyperv_indications);

enum hyperx_state state;

if (is_real_hyperv_vm) {
state = hyperx_state::HYPERV_REAL_VM;
core::add(HYPERV);
core_debug("HYPER_X: added Hyper-V real VM");
if (run_mechanism) {
const bool has_hyperv_indications = (
is_smbios_hyperv() ||
is_motherboard_hyperv() ||
is_event_log_hyperv()
);

const bool eax_result = (eax() == 11 || eax() == 12);

const bool is_real_hyperv_vm = (eax_result && has_hyperv_indications);

if (is_real_hyperv_vm) {
state = hyperx_state::HYPERV_REAL_VM;
} else {
state = hyperx_state::HYPERV_ARTIFACT_VM;
}
} else {
state = hyperx_state::HYPERV_ARTIFACT_VM;
core::add(HYPERV_ARTIFACT);
core_debug("HYPER_X: added Hyper-V artifact VM");
core_debug("HYPER_X: none detected");
state = hyperx_state::UNKNOWN;
}

core_debug("HYPER_X: cached");
memo::hyperx::store(state);
core_debug("HYPER_X: cached");

// false means it's an artifact, which is what the
// point of this whole function is supposed to do
switch (state) {
case hyperx_state::HYPERV_ARTIFACT_VM: return true;
case hyperx_state::HYPERV_REAL_VM: return false;
case hyperx_state::UNKNOWN: return false;
default: return false;
case hyperx_state::HYPERV_ARTIFACT_VM:
core_debug("HYPER_X: added Hyper-V artifact VM");
core::add(HYPERV_ARTIFACT);
return true;

case hyperx_state::HYPERV_REAL_VM:
core_debug("HYPER_X: added Hyper-V real VM");
core::add(HYPERV);
return false;

case hyperx_state::UNKNOWN:
core_debug("HYPER_X: none detected");
return false;

default:
return false;
}
#endif
}
Expand Down Expand Up @@ -10459,6 +10493,7 @@ std::string VM::memo::brand::brand_cache = "";
std::string VM::memo::multi_brand::brand_cache = "";
std::string VM::memo::cpu_brand::brand_cache = "";
VM::hyperx_state VM::memo::hyperx::state = VM::hyperx_state::UNKNOWN;
bool VM::memo::hyperx::cached = false;

#ifdef __VMAWARE_DEBUG__
VM::u16 VM::total_points = 0;
Expand Down

0 comments on commit 568445f

Please sign in to comment.