Skip to content

Commit e044981

Browse files
authored
XSS delta calculation removal
2 parents b465db2 + 08a08f4 commit e044981

1 file changed

Lines changed: 3 additions & 37 deletions

File tree

src/vmaware.hpp

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5533,7 +5533,6 @@ struct VM {
55335533
// Shared state and results
55345534
cache_state state;
55355535
bool hypervisor_detected = false;
5536-
bool bypass_detected = false;
55375536

55385537
#define VMAWARE_STR2(x) #x
55395538
#define VMAWARE_STR(x) VMAWARE_STR2(x)
@@ -5986,7 +5985,7 @@ struct VM {
59865985
// the only way a legitimate interrupt can make the check false flag is if most of the samples were contaminated just in the cpuid samples but not in the serialize/lfence samples
59875986
// still possible tho, but it's as accurate we can get on user-mode without relying on any other hardware clock or cross-referencing with the counter thread mid-execution
59885987
// this is why the score of this technique is not enough to determine a VM
5989-
trigger_vmexit(); // this forces the hypervisor to keep interception and try to bypass latency, or disable interception if on AMD and try to bypass XSAVE states
5988+
trigger_vmexit();
59905989

59915990
std::atomic_signal_fence(std::memory_order_seq_cst);
59925991
v_post = state.counter;
@@ -6036,35 +6035,9 @@ struct VM {
60366035
// Detect IPI-based counter pausing bypasses
60376036
// For the median itself to exceed baremetal limits (which rarely pass 1000), an interrupt must be occurring on almost EVERY single loop iteration
60386037
// This is the footprint of a hypervisor continuously spamming cross-core IPIs to try and pause the counter thread (or the trigger_thread to make SERIALIZE/LFENCE take a lot of time)
6039-
if (!hypervisor_detected && (cpuid_l > 1000 || ref_l > 1000 || cpuid_l == 1 || ref_l == 1)) {
6038+
if (cpuid_l > 1000 || ref_l > 1000 || cpuid_l == 1 || ref_l == 1) {
60406039
debug("TIMER: Detected artificial IPI delivery to VMAware's threads");
6041-
bypass_detected = true;
6042-
}
6043-
6044-
// Now detect bypassers disabling cpuid interception with SVM
6045-
// Even when a bypasser disables INTERCEPT_CPUID in the VMCB, they often fail to realize that certain CPUID leaves do not return static values from the hardware
6046-
// Instead, they return values based on the LAPIC state or internal CPU registers that the hypervisor must initialize for the vCPU to function
6047-
// if hypervisor lies about the CPU vendor, it will create 100000 more detectable signals (querying Intel-specific behavior)
6048-
if (cpu::is_amd() && !hypervisor_detected) {
6049-
i32 res_d0[4], res_d1[4], res_d12[4], res_ext[4];
6050-
cpu::cpuid(res_d0, 0xD, 0); // XCR0 features
6051-
cpu::cpuid(res_d1, 0xD, 1); // XCR0 + XSS features
6052-
cpu::cpuid(res_d12, 0xD, 12); // CET State details
6053-
cpu::cpuid(res_ext, 0x80000008, 0);
6054-
6055-
const bool hardware_supports_cet = (res_d12[0] > 0);
6056-
const u32 active_xcr0_size = (u32)res_d0[1]; // size for features enabled in XCR0
6057-
const u32 active_total_size = (u32)res_d1[1]; // size for XCR0 + IA32_XSS
6058-
6059-
if (hardware_supports_cet) {
6060-
// delta is the size attributed to supervisor states like CET_U
6061-
const u32 xss_delta = active_total_size - active_xcr0_size;
6062-
6063-
if (xss_delta != 0x10) {
6064-
debug("TIMER: VMAware detected a SVM hypervisor with cpuid interception disabled, score was raised up due to a bypass attempt");
6065-
bypass_detected = true;
6066-
}
6067-
}
6040+
hypervisor_detected = true;
60686041
}
60696042

60706043
// cleanup
@@ -6080,13 +6053,6 @@ struct VM {
60806053
trigger_thread();
60816054
t1.join();
60826055

6083-
if (hypervisor_detected) {
6084-
return true; // 100 score, 99% hypervisor likeliness
6085-
}
6086-
else if (bypass_detected) {
6087-
return core::add(brand_enum::KVM, 150); // 100% hypervisor likeliness; KVM is a guess
6088-
}
6089-
60906056
return hypervisor_detected;
60916057
#endif
60926058
return false;

0 commit comments

Comments
 (0)