Начинающий
- Статус
- Оффлайн
- Регистрация
- 13 Фев 2026
- Сообщения
- 146
- Реакции
- 4
Народ, кто сейчас ковыряет HyperGuard, есть жирный инсайд по 0x18B. Потратил последние недели на реверс securekernel и hvix64, ситуация интересная.
Сижу на тайп-1 гипервизоре, паразитирующем внутри Hyper-V, с dual-CR3 EPT split. Идея была простая: hyperv_cr3 держит теневые страницы с --X, а hook_cr3 — полная копия с оригинальными RW-. Чтение триггерит EPT-виолейшн, хендлер подсовывает чистые байты. Против EAC работает стабильно, но HyperGuard после пары часов активного использования прилетает с 0x18B.
Разобрал цепочку в IDA, дошел до SkpgHyperguardRuntime (0x14000E884). Весь замес происходит здесь:
Флаги там всегда 0x71 (ValidateRead | SetPTBits | FlushInhibit | Supervisor). Весь прикол в том, что гиперколл делает программный EPT-волк из partition+0x2480, читая те же физические страницы таблиц, что и VMCS EPTP. Мои --X правки в PTE светятся для него как на ладони. Если ResultCode не 5, он лезет проверять права доступа: sub eax, 5. На выходе нужно либо 5 (R-X), либо 6 (RWX), а мои --X отдают 4. Итог: VTL1 самоуничтожается, вешает все CPU, оверврайтит RIP в VTL0 на KeBugCheckEx(0x18B).
Также нашел, что VTL1 шедулится не только через VTL-коллы, но и через синтетические таймеры, secure interrupt delivery и даже через vmexit piggybacking (диспатч-луп на 0x2168BA).
Вопрос к знающим: кто-то пробовал это обходить с нестед-позиции? Думаю, единственный адекватный вариант — хукать HvSetEptPointer в hvix64, чтобы фильтровать все EPTP-врайты на лету. Либо ковырять шедулер VTL0, чтобы не давать ему лезть в наш EPT.
Кто-то уже тестил такие хуки? Есть смысл или есть способ проще через манипуляции с VMCS? Делитесь опытом, кто допиливал — кидайте свои мысли.
Сижу на тайп-1 гипервизоре, паразитирующем внутри Hyper-V, с dual-CR3 EPT split. Идея была простая: hyperv_cr3 держит теневые страницы с --X, а hook_cr3 — полная копия с оригинальными RW-. Чтение триггерит EPT-виолейшн, хендлер подсовывает чистые байты. Против EAC работает стабильно, но HyperGuard после пары часов активного использования прилетает с 0x18B.
Разобрал цепочку в IDA, дошел до SkpgHyperguardRuntime (0x14000E884). Весь замес происходит здесь:
- SkpgVerifyExtents: крутится по модулям ядра.
- SkpgVerifyMemoryExtent: вызывает SkpgTranslateVaWorker (0x1400645FC), который в свою очередь дергает гиперколл 0x52 (HvTranslateVirtualAddress).
Флаги там всегда 0x71 (ValidateRead | SetPTBits | FlushInhibit | Supervisor). Весь прикол в том, что гиперколл делает программный EPT-волк из partition+0x2480, читая те же физические страницы таблиц, что и VMCS EPTP. Мои --X правки в PTE светятся для него как на ладони. Если ResultCode не 5, он лезет проверять права доступа: sub eax, 5. На выходе нужно либо 5 (R-X), либо 6 (RWX), а мои --X отдают 4. Итог: VTL1 самоуничтожается, вешает все CPU, оверврайтит RIP в VTL0 на KeBugCheckEx(0x18B).
Также нашел, что VTL1 шедулится не только через VTL-коллы, но и через синтетические таймеры, secure interrupt delivery и даже через vmexit piggybacking (диспатч-луп на 0x2168BA).
Вопрос к знающим: кто-то пробовал это обходить с нестед-позиции? Думаю, единственный адекватный вариант — хукать HvSetEptPointer в hvix64, чтобы фильтровать все EPTP-врайты на лету. Либо ковырять шедулер VTL0, чтобы не давать ему лезть в наш EPT.
Кто-то уже тестил такие хуки? Есть смысл или есть способ проще через манипуляции с VMCS? Делитесь опытом, кто допиливал — кидайте свои мысли.