Instruction emulation hyper-breakpoint¶
Patch'lenmiş instruction'ı guest'te restore edip yeniden çalıştırmak yerine, original instruction'ı hypervisor içinde decode edip emulate eden bir hyper-breakpoint varyantı — böylece guest'in memory'si hiçbir zaman un-patch edilmez ve breakpoint'in yeniden re-arm edilmesi gerekmez.
Mechanism¶
Note
Bir hyper-breakpoint, hedef instruction'ın ilk byte'ının üzerine bir int3
(0xCC) byte'ı yerleştirir; bunu çalıştırmak hypervisor'ın intercept ettiği
bir #BP exception'ı doğurur (bir exception-bitmap VM-exit). Asıl problem
continuation: original instruction'ın ilk byte'ı kaybolduğu için CPU öylece
devam edemez. instruction-emulation varyantı bunu guest memory'sine
dokunmadan çözer: hypervisor saklanmış original byte'(lar)ı okur, original
instruction'ın tamamını decode eder ve etkisini guest state'e (register'lar,
flag'ler, memory) karşı software içinde çalıştırır, ardından guest RIP'i onun
ötesine ilerletir. 0xCC hiçbir zaman kaldırılmadığından, trap'in disarm
olduğu bir pencere yoktur ve onu re-inject etmeye gerek kalmaz — byte'ı restore
edip Monitor Trap Flag üzerinden single-step yapan
instruction repair ile karşılaştır.
Bu, bir memory-write + single-step gidiş-dönüşünü (bir ekstra VM-exit) host içindeki bir software instruction decoder/emulator maliyetiyle takas eder.
Walkthrough¶
Kavramsal akış (hyper-breakpoint varyant karşılaştırma literatüründen):
- Arm. Hedef adresteki original byte'ı sakla ve üzerine
0xCCyaz. - Trap. Guest byte'ı çalıştırır;
#BPbir VM-exit'e yol açar. Handler, fault'lanan RIP'i kayıtlı bir hyper-breakpoint ile eşleştirir ve callback'i çalıştırır. - Repair yerine emulate. Original byte'ı geri yazmak yerine handler:
orig = saved_original_bytes(rip) // bytes hidden by the 0xCC
insn = decode(orig) // length + semantics
emulate(insn, &guest_state) // apply effect to regs/flags/mem
guest_rip += insn.length // step over the original instruction
0xCC tüm bu süre boyunca guest memory'sinde kalır.
4. Resume. VM-entry doğrudan bir sonraki instruction'a döner. Trap bir sonraki
isabet için hâlâ arm'lıdır — re-injection adımı yok.
Warning
Correctness, eksiksiz ve sadık bir emulator'a bağlıdır. Decoder'ın modellemediği herhangi bir instruction ya da yanlış uyguladığı herhangi bir side effect (segmentation, fault'lar, locked op'ların atomicity'si, FPU/SSE state), guest'i bozar. Bu, gerçek instruction'ı her zaman gerçek silicon üzerinde çalıştıran repair/EPT-switch varyantlarına karşı merkezî takastır. Correctness'i tercih eden engine'ler (örn. DRAKVUF) emulation'dan bilinçli olarak kaçınır ve bunun yerine SLAT view switching kullanır.
Beklenen gözlem: her breakpoint isabeti, ardından bir Monitor-Trap-Flag exit'i
olmadan ve page'in geçici bir un-patch'i olmadan tek bir #BP VM-exit üretir.
Detection¶
0xCCexecutable byte'larda kalıcı olarak bulunur, dolayısıyla patch'lenmiş adresi okuyabilen bir guest (EPT split gibi read-side stealth katmanlanmadığında) breakpoint'i doğrudan görür — bir self-checksum bunu tespit eder.- Davranışsal timing native'den farklıdır çünkü her isabet bir emulation pass'i getirir.
Mitigation¶
- SLAT/altp2m read-side stealth katmanla, böylece patch'lenmiş page'in okumaları
temiz byte'ları görürken
0xCCyalnızca çalıştırılır. - Emulator sadakatinin şüpheli olduğu yerlerde, gerçek instruction'ı çalıştıran instruction repair veya bir EPT-switch single-step tercih et.
References¶
- "EPT Switching vs. Instruction Repair vs. Instruction Emulation: A Performance Comparison of Hyper-Breakpoint Variants" (MDPI Engineering 2025) — https://www.mdpi.com/2673-4117/6/10/278
- "Benchmarking Hyper-Breakpoints for Efficient Virtual Machine Introspection" (MDPI Electronics 2025) — https://www.mdpi.com/2079-9292/14/3/534