Skip to content

Execute-only EPT page (hidden breakpoint)

Read ve write bit'leri temizlenmiş ama execute bit'i set kalan bir EPT entry'si; böylece page normal execute olur ama her data read ya da write hypervisor'a trap eder — disassembler'ların ve self-check'lerin göremediği bir breakpoint ya da detour'un temeli.

Mechanism

Note

Intel SLAT (EPT)'de her guest-physical frame'in access right'ları guest'e değil, host EPT entry'sine aittir. İlgili invariant şudur: EPT permission bit'leri (Read, Write, eXecute) guest'in kendi page table'larından bağımsız olarak kontrol edilir. Bir execute-only page, X=1 yaparken R=0 ve W=0'ı temizler. CPU o zaman frame'den instruction'ları fetch eder ve çalıştırır, ama aynı guest-physical address'e herhangi bir data erişimi (bir read ya da write) EPT permission check'ini fail eder ve bir EPT violation VM-exit'i yükseltir. Bu, "bir page'e erişmek" tek kavramını hypervisor'ın farklı servis edebileceği iki ayrı path'e — execute vs. read/write — böler.

Bu asimetri breakpoint'i gizli yapan şeydir. Host, page'in modifiye edilmiş bir kopyasını (bir breakpoint byte'ı ya da bir detour jump'ı ile) execution için canlı tutabilirken, page'i okuyan her şeye şeffaf biçimde orijinal, temiz byte'ları sunar. Kendi .text'ini checksum'layan bir guest debugger, integrity scanner ya da anti-cheat, el değmemiş kopyayı okur ve hiçbir şey görmez; instruction'ları fetch eden CPU ise instrument edilmiş kopyayı çalıştırır. İzolasyon-sınırı açısından: guest, EPT permission'larını inceleyemez ya da değiştiremez, dolayısıyla "aynı" adresin read'leri ile execute'larının farklı host frame'lere yönlendirildiğini gözlemleyecek mimari bir yolu yoktur. Bu, defensive/introspection bir primitive'dir (analiz için stealth breakpoint'ler) ve aynı şekilde EPT-tabanlı rootkit hook'larının da zeminidir. Bkz. EPT split ve EPT-based stealth hooking.

Walkthrough

HyperDbg iki çeşit implement eder. İkisi de execute-only state'e dayanır.

Permission state'leri (bir EPT entry, iki faz):

default        : R=1 W=1 X=1   -> normal frame
armed (X-only) : R=0 W=0 X=1   -> execution allowed, any read/write => EPT violation

Klasik stealth int3 hook'u (!epthook):

  1. Hedef page'i (Page A) taze bir host frame'e (Page B) kopyala.
  2. Page B'de hedef instruction'ın ilk byte'ına 0xCC (int3) yaz.
  3. EPT entry'sini Page B'ye yönelt ve onu execute-only yap (R=0 W=0 X=1).
  4. Execution'da int3 tetiklenir ve Exception Bitmap bir VM-exit'i zorlar; hypervisor #BP'nin kendisine mi ait (debugger'a teslim et) yoksa yabancı mı (guest'e re-inject et) olduğuna karar verir.
  5. O page'in bir read ya da write'ında bir EPT violation oluşur. Handler entry'yi geri orijinal Page A'ya swap eder, R=1 W=1 X=0 yapar ve Monitor Trap Flag (MTF)'i set eder. Data access o zaman temiz byte'ları görür.
  6. MTF bir single-step VM-exit'e neden olur; handler entry'yi execute-only Page B'ye (R=0 W=0 X=1) geri çevirir ve gizli breakpoint'i yeniden arm eder.

Gizli detour (!epthook2):

Handler bunun yerine entry'de R/W'yi temizler ve X'i set eder, Page A'yı Page B'ye kopyalar ve Page B'yi hook fonksiyonuna absolute bir jump ile patch'ler (length'ler bir length-disassembler engine ile hesaplanır ki tüm bir instruction overwrite edilsin). Execution detour'a iner; page'in read'leri trap'lenir ve orijinal byte'lar sunulur. !epthook2 gizli bir inline hook gibi davranır ve klasik varyanttan daha hızlıdır, ama tek bir mode kısıtlaması taşır: HyperDbg docs'una göre yalnızca kernel-mode address'lerde kullanılabilir, user-mode address'ler için kullanılamaz. !epthook ise tam da bu yüzden tercih edilir; çünkü o mode kısıtlamasından muaftır ve hem user-mode hem kernel-mode address'lerde çalışır.

Warning

Breakpoint/detour byte'ı bir instruction boundary'sinde oturmalıdır. İlk olmayan bir byte'ı patch'lemek decoding'i değiştirir ve execution'ı bozar. Ayrıca, bu tasarımda iki detour tarzı hook tek bir fiziksel page'i paylaşamaz — read/execute split'i per-frame'dir.

Detection

  • Read/execute ayrışması: bir guest kendi kodunu bir buffer'a kopyalayıp okuduğu byte'ları execute ettiği byte'larla karşılaştırabilir (örn. bir checksum hesapla, sonra region'a jump et) — bir uyuşmazlık split bir mapping'i açığa çıkarır.
  • EPT-violation timing'i: hook'lanmış bir page'in her data dokunuşundaki trap-swap-MTF-swap döngüsü normal bir erişimden çok daha yavaştır; .text üzerindeki sıkı read döngüleri anormal latency gösterir.
  • Host telemetry'si: VMM'i çalıştıran defender'lar için authoritative sinyal EPT entry'sinin kendisidir — R=0 W=0 X=1 state'inde bırakılmış frame'ler, eşleşmiş shadow frame'ler ve per-page EPT-violation sayıları.

Mitigation

  • Execute-only EPT entry'lerini ve eşleşmiş shadow frame'leri host-owned introspection state'i olarak ele al ve onlar üzerinde audit/alert yap; guest, EPT permission'larını asla okuyamamalı ya da modifiye edememeli.
  • Stealth hooking'in düşmanca olduğu yerlerde, hypervisor-seviyesi integrity monitoring her guest code frame'inin executable view'ını read view'ıyla karşılaştırabilir.
  • Pencereyi minimize et: MTF step'inden hemen sonra yeniden arm et (X-only'ye geri swap) ki temiz page yalnızca tek trap'lenen erişim için açığa çıksın.

References