Skip to content

Commit a636896

Browse files
author
Requiem
committed
feat: improved VM::HYPERVISOR_BIT
1 parent b703a79 commit a636896

1 file changed

Lines changed: 23 additions & 19 deletions

File tree

src/vmaware.hpp

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ struct VM {
707707

708708
// specifically for util::hyper_x() and memo::hyperv
709709
enum hyperx_state : u8 {
710-
HYPERV_UNKNOWN_VM = 0,
710+
HYPERV_UNKNOWN = 0,
711711
HYPERV_REAL_VM,
712712
HYPERV_ARTIFACT_VM,
713713
HYPERV_ENLIGHTENMENT
@@ -1802,7 +1802,7 @@ struct VM {
18021802
* - HYPERV_ARTIFACT_VM for host with Hyper-V enabled
18031803
* - HYPERV_REAL_VM for real Hyper-V VM
18041804
* - HYPERV_ENLIGHTENMENT for QEMU with Hyper-V enlightenments
1805-
* - HYPERV_UNKNOWN_VM for unknown/undetected state
1805+
* - HYPERV_UNKNOWN for unknown/undetected state
18061806
*/
18071807
[[nodiscard]] static hyperx_state hyper_x() {
18081808
#if (!WINDOWS)
@@ -1863,7 +1863,7 @@ struct VM {
18631863
}
18641864
else {
18651865
core_debug("HYPER_X: Hyper-V is not active");
1866-
state = HYPERV_UNKNOWN_VM;
1866+
state = HYPERV_UNKNOWN;
18671867
}
18681868
}
18691869
else {
@@ -2287,14 +2287,24 @@ struct VM {
22872287
#if (!x86)
22882288
return false;
22892289
#else
2290-
if (util::hyper_x() == HYPERV_ARTIFACT_VM) {
2291-
return false;
2290+
u32 eax = 0, ebx = 0, ecx = 0, edx = 0;
2291+
cpu::cpuid(eax, ebx, ecx, edx, 1);
2292+
constexpr u32 HYPERVISOR_MASK = (1u << 31);
2293+
2294+
if (ecx & HYPERVISOR_MASK) {
2295+
if (util::hyper_x() == HYPERV_ARTIFACT_VM) {
2296+
return false;
2297+
}
2298+
return true;
2299+
}
2300+
2301+
const auto hx = util::hyper_x();
2302+
if (hx != HYPERV_UNKNOWN) {
2303+
debug("HYPERVISOR_BIT: Running under nested virtualization");
2304+
return true; // hypervisor bit is not set but Hyper-V was detected through root partition checks
22922305
}
22932306

2294-
u32 unused, ecx = 0;
2295-
cpu::cpuid(unused, unused, ecx, unused, 1);
2296-
const u32 mask = (1u << 31);
2297-
return (ecx & mask);
2307+
return false;
22982308
#endif
22992309
}
23002310

@@ -5696,7 +5706,7 @@ struct VM {
56965706

56975707
/**
56985708
* @brief Check for uncommon IDT virtual addresses
5699-
* @author Matteo Malvica (Linux)
5709+
* @author Matteo Malvica
57005710
* @author Idea to check VPC's range from Tom Liston and Ed Skoudis' paper "On the Cutting Edge: Thwarting Virtual Machine Detection" (Windows)
57015711
* @link https://www.matteomalvica.com/blog/2018/12/05/detecting-vmware-on-64-bit-systems/ (Linux)
57025712
* @category Windows, Linux, x86
@@ -5711,31 +5721,25 @@ struct VM {
57115721
#if (x86_64)
57125722
// 64-bit Linux: IDT descriptor is 10 bytes (2-byte limit + 8-byte base)
57135723
__asm__ __volatile__("sidt %0" : "=m"(values));
5714-
57155724
#ifdef __VMAWARE_DEBUG__
5716-
debug("SIDT5: values = ");
5725+
debug("SIDT: values = ");
57175726
for (u8 i = 0; i < 10; ++i) {
57185727
debug(std::hex, std::setw(2), std::setfill('0'), static_cast<unsigned>(values[i]));
57195728
if (i < 9) debug(" ");
57205729
}
57215730
#endif
5722-
57235731
return (values[9] == 0x00); // 10th byte in x64 mode
5724-
57255732
#elif (x86_32)
57265733
// 32-bit Linux: IDT descriptor is 6 bytes (2-byte limit + 4-byte base)
57275734
__asm__ __volatile__("sidt %0" : "=m"(values));
5728-
57295735
#ifdef __VMAWARE_DEBUG__
5730-
debug("SIDT5: values = ");
5736+
debug("SIDT: values = ");
57315737
for (u8 i = 0; i < 6; ++i) {
57325738
debug(std::hex, std::setw(2), std::setfill('0'), static_cast<unsigned>(values[i]));
57335739
if (i < 5) debug(" ");
57345740
}
57355741
#endif
5736-
57375742
return (values[5] == 0x00); // 6th byte in x86 mode
5738-
57395743
#else
57405744
return false;
57415745
#endif
@@ -11827,7 +11831,7 @@ std::string VM::memo::brand::brand_cache = "";
1182711831
std::string VM::memo::multi_brand::brand_cache = "";
1182811832
std::string VM::memo::cpu_brand::brand_cache = "";
1182911833
VM::u32 VM::memo::threadcount::threadcount_cache = 0;
11830-
VM::hyperx_state VM::memo::hyperx::state = VM::HYPERV_UNKNOWN_VM;
11834+
VM::hyperx_state VM::memo::hyperx::state = VM::HYPERV_UNKNOWN;
1183111835
bool VM::memo::hyperx::cached = false;
1183211836

1183311837
#ifdef __VMAWARE_DEBUG__

0 commit comments

Comments
 (0)