Skip to content

Commit 3ea8cfc

Browse files
authored
Merge pull request #662 from NotRequiem/main
removed some instruction checks
2 parents c50a8d7 + 88bcc04 commit 3ea8cfc

File tree

1 file changed

+6
-106
lines changed

1 file changed

+6
-106
lines changed

src/vmaware.hpp

Lines changed: 6 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -5678,8 +5678,10 @@ struct VM {
56785678
debug("TIMER: VMM -> ", cpuid_l, " | nVMM -> ", ref_l, " | Ratio -> ", latency_ratio);
56795679
if (latency_ratio >= threshold) hypervisor_detected = true;
56805680

5681-
// Now detect bypassers letting the VM boot with cpuid interception, and then disabling interception with SVM by flipping bit 18 in the VMCB
5682-
// if hypervisor lies about the CPU vendor, it will create 100000 more detectable signals (querying intel-specific behavior)
5681+
// Now detect bypassers disabling cpuid interception with SVM
5682+
// 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
5683+
// Instead, they return values based on the LAPIC state or internal CPU registers that the hypervisor must initialize for the vCPU to function
5684+
// if hypervisor lies about the CPU vendor, it will create 100000 more detectable signals (querying Intel-specific behavior)
56835685
if (cpu::is_amd() && !hypervisor_detected) {
56845686
i32 res_d0[4], res_d1[4], res_d12[4], res_ext[4];
56855687
trigger_vmexit(res_d0, 0xD, 0); // XCR0 features
@@ -5707,7 +5709,6 @@ struct VM {
57075709

57085710
std::thread t1(counter_thread);
57095711
trigger_thread();
5710-
57115712
t1.join();
57125713

57135714
if (hypervisor_detected) {
@@ -5718,7 +5719,7 @@ struct VM {
57185719
}
57195720

57205721
return hypervisor_detected;
5721-
#endif
5722+
#endif
57225723
return false;
57235724
}
57245725

@@ -11903,108 +11904,7 @@ struct VM {
1190311904
return true;
1190411905
}
1190511906
}
11906-
11907-
// we will run amd only stuff
11908-
if (!cpu::is_amd()) {
11909-
return false;
11910-
}
11911-
11912-
struct state {
11913-
volatile int in_asm;
11914-
volatile int exception_seen;
11915-
};
11916-
11917-
static thread_local state* tls_state = nullptr;
11918-
11919-
state state{};
11920-
tls_state = &state;
11921-
11922-
// lambda to capture exceptions
11923-
const PVOID vh = AddVectoredExceptionHandler(
11924-
1,
11925-
[](PEXCEPTION_POINTERS ep) -> LONG {
11926-
if (!tls_state || !tls_state->in_asm)
11927-
return EXCEPTION_CONTINUE_SEARCH;
11928-
11929-
const DWORD code = ep->ExceptionRecord->ExceptionCode;
11930-
if (code == EXCEPTION_ILLEGAL_INSTRUCTION) {
11931-
tls_state->exception_seen = 1;
11932-
#if (x86_64)
11933-
ep->ContextRecord->Rip += 3;
11934-
#else
11935-
ep->ContextRecord->Eip += 3;
11936-
#endif
11937-
return EXCEPTION_CONTINUE_EXECUTION;
11938-
}
11939-
return EXCEPTION_CONTINUE_SEARCH;
11940-
}
11941-
);
11942-
if (!vh) return false;
11943-
11944-
// xor rdpru ret
11945-
constexpr unsigned char code[] = {
11946-
0x31, 0xC9,
11947-
0x0F, 0x01, 0xFD,
11948-
0xC3
11949-
};
11950-
11951-
PVOID mem = nullptr;
11952-
SIZE_T size = sizeof(code);
11953-
11954-
if (nt_allocate_virtual_memory(
11955-
current_process,
11956-
&mem,
11957-
0,
11958-
&size,
11959-
MEM_COMMIT | MEM_RESERVE,
11960-
PAGE_EXECUTE_READWRITE) != 0 || !mem)
11961-
{
11962-
RemoveVectoredExceptionHandler(vh);
11963-
return false;
11964-
}
11965-
11966-
memcpy(mem, code, sizeof(code));
11967-
11968-
nt_flush_instruction_cache(current_process, mem, sizeof(code));
11969-
11970-
using fn_t = void(*)();
11971-
fn_t fn = reinterpret_cast<fn_t>(mem);
11972-
11973-
state.exception_seen = 0;
11974-
state.in_asm = 1;
11975-
11976-
__try {
11977-
fn();
11978-
}
11979-
__except (EXCEPTION_EXECUTE_HANDLER) {
11980-
state.exception_seen = 1;
11981-
}
11982-
11983-
state.in_asm = 0;
11984-
11985-
if (state.exception_seen) {
11986-
debug("KVM_INTERCEPTION: Detected a hypervisor intercepting performance counter reads");
11987-
generic_hypervisor = true;
11988-
}
11989-
11990-
SIZE_T free_size = 0;
11991-
nt_free_virtual_memory(
11992-
current_process,
11993-
&mem,
11994-
&free_size,
11995-
MEM_RELEASE
11996-
);
11997-
11998-
nt_close(current_process);
11999-
12000-
RemoveVectoredExceptionHandler(vh);
12001-
12002-
// KVM does this, but other hypervisors might do the same, reason why is generic
12003-
// kernel might configure CR4 to inject exception if CPL > 0, so if this case is detected, trigger a lower probability score
12004-
if (generic_hypervisor) {
12005-
return core::add(brand_enum::NULL_BRAND, 50);
12006-
}
12007-
11907+
1200811908
return false;
1200911909
}
1201011910

0 commit comments

Comments
 (0)