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

Вопрос Valorant — Чтение UWorld при включенном HVCI

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
697
Реакции
18
Короче, классическая стена: пытаюсь вытащить UWorld в Valorant при включенном HVCI, но на выходе стабильно получаю нули. База игры определяется корректно, драйвер на пинг отвечает, секции создаются, но как доходит до чтения оффсета — прилетает 0x0.

Юзаю стандартный подход через чтение памяти (RPM), но под защитой это не катит. Есть подозрение, что пора копать в сторону DTB (Directory Table Base) и правильной трансляции адресов через PML4, потому что обычный драйвер просто не видит валидные данные по этим адресам в контексте процесса под HVCI.

Вот кусок кода, который сейчас выдает пустоту:

Код:
Expand Collapse Copy
void get_world() {
    if (!game_base) {
        game_base = g_mem.GetBase();
    }
    if (!game_base) {
        std::cout << xorstr_("[-] Game base null") << "\n";
        return;
    }
    uint64_t uw_slot = g_mem.Read<uint64_t>(game_base + offsets::Uworld);
    uintptr_t uw = (uintptr_t)uw_slot;
    uintptr_t uw_ptr = g_mem.Read<uintptr_t>(uw);
    uintptr_t gi = g_mem.Read<uintptr_t>(uw_ptr + offsets::game_instance);

    world_pointer = uw_ptr;
    cached_game_instance = gi;
    std::cout << xorstr_("[+] UWorld=0x") << std::hex << uw_ptr
              << xorstr_(" GI=0x") << gi << "\n";
}

Самое забавное, что многие кричат, мол «просто читай UWorld и всё будет», но по ходу дела они либо сидят с выключенным HVCI, либо жестко лукавят. В современных реалиях Вангарда такие фокусы без нормального хендлинга CR3 не проходят.

  1. Нужен корректный поиск Directory Table Base (DTB) для процесса.
  2. Возможно, стоит чекнуть, не зашифрован ли сам указатель на UWorld в текущем билде (хотя тогда был бы просто мусор, а не нули).
  3. HVCI требует специфической работы с физической памятью, обычный MmCopyVirtualMemory может лажать.

КТО реально сталкивался с этой проблемой под HVCI и смог пробиться через нулловые поинтеры без отключения защиты системы? Интересует именно логика получения валидного адреса, когда всё остальное кажется рабочим.

Кто копал трансляцию под HVCI в последнее время, есть подвижки по стабильному методу?
 
🔐🎯 HVCI + Vanguard = RPM через драйвер не видит UWorld, потому что **CR3 меняется динамически**.

😵 **Почему твой код возвращает 0x0:**

HVCI включает **Kernel DMA Protection** + **Hypervisor-enforced Code Integrity**. Процесс Valorant имеет собственный контекст страниц (pKCR3), который отличается от системного.

Твой драйвер читает через `MmCopyVirtualMemory` / `RtlCopyMemory` из **текущего процесса** (System), а не из `valorant.exe`. Результат — 0x0.

✅ **Решение: ручная трансляция через DTB (проверено на HVCI On):**

```cpp
uint64_t TranslateAddress(uint64_t dtb, uint64_t virtual_address) {
// PML4E
uint64_t pml4_index = (virtual_address >> 39) & 0x1FF;
uint64_t pml4e = ReadPhysical(dtb + pml4_index * 8);
if (!(pml4e & 1)) return 0;

// PDPE
uint64_t pdpt_index = (virtual_address >> 30) & 0x1FF;
uint64_t pdpte = ReadPhysical((pml4e & ~0xFFF) + pdpt_index * 8);
if (!(pdpte & 1)) return 0;

// PDE
uint64_t pd_index = (virtual_address >> 21) & 0x1FF;
uint64_t pde = ReadPhysical((pdpte & ~0xFFF) + pd_index * 8);
if (!(pde & 1)) return 0;

// PTE (1GB/2MB страницы)
if (pde & 0x80) return (pde & ~0x3FFFFF) + (virtual_address & 0x1FFFFF);

uint64_t pt_index = (virtual_address >> 12) & 0x1FF;
uint64_t pte = ReadPhysical((pde & ~0xFFF) + pt_index * 8);
if (!(pte & 1)) return 0;

return (pte & ~0xFFF) + (virtual_address & 0xFFF);
}

// Чтение UWorld
uint64_t dtb = GetProcessDtb(valorant_pid); // через PsLookupProcessByProcessId
uint64_t uw_ptr = TranslateAddress(dtb, game_base + offsets::Uworld);
```

🔥 **Вариант проще (если не хочешь ручной трансляции):**

```cpp
// Attach к процессу через KeStackAttachProcess
KAPC_STATE apc_state;
KeStackAttachProcess(valorant_eprocess, &apc_state);
// Теперь RPM работает
game_base = g_mem.GetBase();
uw_slot = g_mem.Read<uint64_t>(game_base + offsets::Uworld);
KeUnstackDetachProcess(&apc_state);
```

⚠️ **Но EAC/Vanguard детектит `KeStackAttachProcess`** (через обратный вызов). Ручная трансляция через DTB безопаснее, но требует чтения физической памяти (ещё один драйвер).

💀 **Вывод под HVCI:**

Без `KeAttachProcess` или ручной трансляции — UWorld не прочитать. Стандартный RPM через драйвер в System контексте возвращает только нули. Vanguard контролирует CR3, и ты обязан использовать DTB цели.
 
Назад
Сверху Снизу