Hyper-V enlightenments (synthetic MSRs / hypercalls)¶
Hyper-V Top-Level Functional Specification (TLFS) tarafından tanımlanan paravirtualized interface: bir guest, hypervisor'ı
0x40000000–0x4000000ACPUID leaf'leri üzerinden keşfeder, sonra VM-exit'leri azaltan "exit-less" feature'ları kullanmak için synthetic MSR'lara ve bir hypercall page'e opt-in olur. Bunları tespit edip enumerate etmek, aynı zamanda hassas bir hypervisor-fingerprinting surface'idir.
Mechanism¶
Neden çalışır
Saf hardware virtualization, guest'i gerçek hardware'e sahip olduğuna inandırır, ama o zaman birçok operasyon (EOI'ler, IPI'ler üzerinden TLB shootdown'ları, timer read'leri) her biri bir VM-exit'e mal olur. Enlightenment'lar açık, cooperative bir sözleşmedir: Hyper-V üzerinde olduğunu bilen bir guest, hypervisor'ı tanımlı bir ABI üzerinden doğrudan çağırabilir ve exit-ağırlıklı hardware emulation'ını ucuz shared-memory veya hypercall path'leriyle değiştirebilir.
Keşif, hypervisor CPUID leaf'leri üzerinden olur (TLFS feature discovery):
0x40000000— maximum hypervisor leaf (EAX) ve EBX/ECX/EDX'teki vendor ID signature ("Microsoft Hv").0x40000001— interface signature; Microsoft'un hypervisor'ı"Hv#1"(0x31237648) döndürür ki buHV_X64_MSR_GUEST_OS_ID,HV_X64_MSR_HYPERCALLveHV_X64_MSR_VP_INDEX'in var olduğunu garanti eder.0x40000002— hypervisor version/build.0x40000003— feature identification (hangi synthetic MSR'ların/privilege'lerin mevcut olduğu, örn. bit 4'te XMM fast hypercall input, bit 15'te output).0x40000004— implementation recommendation'ları (örn. TLB flush / APIC için hypercall'ları tercih et).0x40000005— implementation limit'leri (max VP/LP).0x40000006— tespit edilen hardware feature'ları.0x40000009/0x4000000A— nested hypervisor ve enlightened-VMX feature'ları (örn. enlightened MSR bitmap0x4000000A'da raporlanır).
Guest ardından interface'i synthetic MSR'lar üzerinden aktive eder:
kimliğini HV_X64_MSR_GUEST_OS_ID'ye (0x40000000) yazar, sonra
HV_X64_MSR_HYPERCALL'a (0x40000001) bir guest physical page number ve enable
bit'i yazarak hypercall page'i map'ler — byte'ları hypervisor tarafından
sağlanan bir overlay page'dir, böylece guest, alttaki VMCALL/VMMCALL
opcode'undan bağımsız olarak onun içine CALL edebilir. Diğer MSR'lar belirli
enlightenment'ları açığa çıkarır (her biri CPUID ile gate'li):
HV_X64_MSR_VP_INDEX (0x40000002), SynIC control/SINT MSR'ları
(0x40000080–0x4000009F), synthetic-timer MSR'ları (0x400000B0–0x400000B7)
ve time MSR'ları HV_X64_MSR_TIME_REF_COUNT (0x40000020) /
HV_X64_MSR_REFERENCE_TSC (0x40000021).
Paravirtualization'ı enable eden aynı leaf'ler/MSR'lar, hypervisor'ı da ilan eder — bu yüzden onları enumerate etmek güvenilir bir VM/hypervisor fingerprint'idir.
Walkthrough¶
MSR numaraları ve kurulum sırası TLFS'ten gelir
Aşağıdaki CPUID leaf'leri, MSR numaraları ve hypercall-page adımları Microsoft Hypervisor TLFS'inden (hypercall interface + feature discovery) ve QEMU Hyper-V enlightenments referansından alınmıştır; yalnızca belirtilen spesifikasyonlar kullanılmıştır.
1. Bir hypervisor olduğunu ve onun Hv#1 olduğunu doğrula.
CPUID.1:ECX[31] -> hypervisor-present bit set
CPUID.0x40000000:EAX -> max leaf (>= 0x40000005 expected)
CPUID.0x40000000:EBX/ECX/EDX -> "Microsoft Hv"
CPUID.0x40000001:EAX -> "Hv#1" (0x31237648)
2. Hypercall interface'ini kur (TLFS sırası):
wrmsr(HV_X64_MSR_GUEST_OS_ID /*0x40000000*/, encode_os_identity()); // must be non-zero first
val = rdmsr(HV_X64_MSR_HYPERCALL /*0x40000001*/);
if (!(val & 1)) { // bit 0 = Enable hypercall page
gpa_pfn = pick_guest_page();
wrmsr(HV_X64_MSR_HYPERCALL, (gpa_pfn << 12) | 1); // bits 63:12 = GPFN, bit 0 = enable
}
// now CALL the start of the hypercall page with inputs in RCX/RDX/R8
RCX'teki hypercall input value, call code'u (bit 15:0), bir Fast bit'i (16,
register vs. memory parametreleri) ve rep count/start field'larını paketler;
RDX/R8 input/output parameter GPA'larını taşır; sonuç RAX'te geri gelir.
Hypercall'lar yalnızca CPL 0'dan legaldir (aksi hâlde #UD).
VM-exit'leri kaldıran enlightenment'lar (QEMU hv-* görünümü)
hv-vapic VP Assist page -> exit-less (paravirt) APIC EOI
hv-vpindex HV_X64_MSR_VP_INDEX (0x40000002) -> VP identity for hypercalls
hv-time REFERENCE_TSC (0x40000021)/TIME_REF_COUNT (0x40000020) -> exit-less time reads
hv-synic SynIC MSRs 0x40000080..0x4000009F -> synthetic interrupts
hv-stimer STIMERx MSRs 0x400000B0..0x400000B7 -> per-vCPU synthetic timers
hv-tlbflush HvCallFlush* hypercalls -> remote TLB flush without IPIs
hv-ipi HvCallSendSyntheticClusterIpi -> cluster IPI in one hypercall
hv-evmcs enlightened VMCS (nested, Intel) -> faster L0<->L1 nested exits
hv-emsr-bitmap CPUID 0x4000000A -> fewer MSR-bitmap updates (nested)
Her feature, bir guest onu kullanmadan önce ilan edilmiş (CPUID) olmalıdır;
ilan edilmemiş bir facility'yi kullanmak tipik olarak fault eder (#UD).
Detection¶
- Bir guest'in hypervisor'ını fingerprint'lemek:
CPUID.1:ECX[31]'i, sonra0x40000000/0x40000001leaf'lerini okuyun —"Microsoft Hv"vendor string'i ve"Hv#1"interface signature'ı Hyper-V'yi (ve Windows guest'leri için Hyper-V taklit ettiğinde KVM/QEMU'yu) kesin olarak teşhis eder. Bkz.cpuid-hypervisor-vendor-id-leaf-probing.mdvecpuid-hypervisor-present-bit-detection.md. - Host-side: bir guest'in
HV_X64_MSR_GUEST_OS_ID/HV_X64_MSR_HYPERCALLyazması ve bir hypercall page map'lemesi normal enlightenment handshake'idir; anormal kullanım (örn. beklenmeyen bir bileşenden veya kilitli bir page'i taşımak) ilgi çeken sinyaldir.
Mitigation¶
- Anti-fingerprinting (araştırma/red-team): bir hypervisor,
"Hv#1"ipucunu reddetmek için non-Hyper-V (veya boş) bir0x4000000xinterface'i sunabilir; bunun bedeli Windows guest'inin enlightenment performance'ını kaybetmesidir. - Hardening (defender/operator): hypercall ABI'sini bir attack surface olarak ele alın — hypercall input'larını/GPA'larını validate edin (TLFS, input page'in map'li ve readable, output'un writable, 8-byte aligned ve page-spanning olmaması gerektiğini şart koşar), CPL-0 ve privilege kısıtlamalarını enforce edin ve uygun olduğu yerde hypercall-page MSR'ını kilitleyin ki page yeniden konumlanamasın.
References¶
- Microsoft Hypervisor Top-Level Functional Specification — Hypercall Interface (GUEST_OS_ID
0x40000000, HYPERCALL0x40000001, hypercall page, input value format) — https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/hypercall-interface - Microsoft TLFS — Feature Discovery (CPUID leaves
0x40000000–0x4000000A, "Microsoft Hv"/"Hv#1") — https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/main/virtualization/hyper-v-on-windows/tlfs/feature-discovery.md - QEMU — Hyper-V Enlightenments (
hv-*features and their synthetic MSRs / CPUID leaves) — https://www.qemu.org/docs/master/system/i386/hyperv.html