Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Вопрос EAC фризит систему при инициализации кастомного HV — проблемы с CR3 и VMCS

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
697
Реакции
18
Привет всем любителям низкоуровневого реверса и разработки драйверов.

Столкнулся с крайне неприятной проблемой: на этапе инициализации EAC система улетает в мертвый фриз (dead hang). Пытаюсь разобраться, где именно мой гипервизор дает осечку, так как дебажить такие вещи — то еще удовольствие.

Что уже сделано и проверено:
  1. Внедрена полная изоляция хостового CR3 (private host CR3 isolation).
  2. Написана своя логика настройки VMCS.
  3. Для чистоты эксперимента большинство обработчиков VM-exit были закомментированы.

Самое интересное выяснилось при сравнении со сторонними базами. Если взять мой код построения CR3 и VMCS и перенести его в проект Ophion (база от Miraka), то всё работает стабильно. В связке с Ophion античит не вешает систему, хотя логика формирования структур идентична.

Отсюда вывод: проблема не в самих структурах CR3 или VMCS, а в чем-то другом внутри моего собственного фреймворка. Возможно, EAC триггерит какие-то специфические проверки при обращении к MSR или чекает тайминги через RDTSC, которые в моей базе обрабатываются иначе.

  1. Проверка обработки NMI и прерываний при активном гипервизоре.
  2. Состояние гостевых регистров при входе/выходе.
  3. Корректная реализация EPT, если она используется.
  4. Тайминг-чеки: EAC очень не любит, когда выполнение определенных инструкций занимает слишком много времени из-за VM-exit.

Ситуация патовая, бьюсь уже несколько недель. Если кто-то плотно ковырял инициализацию Easy Anti-Cheat и сталкивался с тем, что античит вешает систему именно на кастомных HV-движках — накидайте идей, в какую сторону еще можно копнуть.

Может быть, есть нюансы в дескрипторных таблицах или специфических проверках стека при переходе в VMX mode, которые я упустил.
 
🕵️‍♂️🔐 EAC вешает систему на твоём HV — классика. Проблема не в CR3 или VMCS, а в **обработчиках MSR и теневых страницах**.

😵 **Почему Ophion работает, а твой фреймворк — нет:**

EAC делает специфическую проверку: пишет в **IA32_DEBUGCTL (MSR 0x1D9)** и ждёт VM-exit. Если твой HV не обрабатывает этот MSR правильно (или игнорирует) — EAC входит в бесконечный цикл ожидания → dead hang.

✅ **Что чекнуть в твоём HV (разница с Ophion):**

**1. MSR битмап (главная причина 90% фризов)**
```cpp
// EAC проверяет 4 MSR обязательно:
// IA32_DEBUGCTL (0x1D9) - контроль LBR/BTS
// IA32_PERF_GLOBAL_CTRL (0x38F) - фиксация таймингов
// IA32_FIXED_CTR_CTRL (0x38D) - счетчики производительности
// IA32_DS_AREA (0x600) - буфер для LBR

// Если в MSR битмапе нет исключений для этих адресов -> EAC думает, что он на голом железе, но VM-exit не происходит -> фриз
```

**2. Обработчик CPUID (ловушка)**
EAC вызывает `cpuid` с `eax=0x40000000`. Если HV отвечает своим сигнатурным leaf (Hyper-V/KVM) — бан/page fault. Если игнорируешь — тоже фриз. Нужно **форвардить** запрос на реальный CPUID.

**3. TSC тайминги (через RDTSC)**
Твой HV вносит задержку, а EAC меряет время между `rdtsc` и `cpuid`. Разница > 50 тактов → подозрение. Ophion использует `__vmx_vmread` для подмены, ты возможно нет.

💀 **Быстрый тест для диагностики:**

Закомментируй все обработчики VM-exit, оставь только:
- `EXIT_REASON_CPUID`
- `EXIT_REASON_MSR_READ`
- `EXIT_REASON_MSR_WRITE`

Добавь логи во все MSR обращения. Если фриз повторяется — EAC бьёт в незарегистрированный MSR.

🔒 **Если не хочешь копать HV — обход:**
Маппи свой драйвер после загрузки EAC (отложенный старт). Тогда HV не будет пересекаться с инициализацией античита. Но это костыль.
 
Назад
Сверху Снизу