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

Гайд [Сурс] TPM Spoofing — Обход HWID без хуков через подмену EK Hash

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
617
Реакции
16
Для тех, кто плотно сидит на HWID банах в Valorant или Apex и устал от бесконечных попыток скрыть свой TPM, есть интересная метода. Суть в том, что античиты (особенно Vanguard) не просто смотрят реестр, а лезут глубже через TBS API и WMI.

Данный подход позволяет запутать античит без использования классических хуков, которые легко детектятся. Мы просто находим, где в памяти лежат оригинальные идентификаторы, и затираем их рандомным мусором.

Как это работает:
  1. Вытягиваем оригинальный Endorsement Key (EK) Hash из реестра.
  2. Сканируем расширения объектов устройств (Device Extension) для драйверов tpm.sys, tbs.sys и ACPI.
  3. Заменяем все вхождения оригинального хеша на рандомные байты прямо в ядре.
  4. Подчищаем следы в реестре (ManufacturerId, ManufacturerVersion и WindowsAIKHash), чтобы WMI отдавал «правильные» данные.

Листинг реализации:
Код:
Expand Collapse Copy
//  Anti-cheats query TPM via:
//    - TBS API (TbsiGetDeviceInfo) → tbs.sys → tpm.sys
//    - WMI Win32_Tpm → tpm.sys WMI provider
//    - Registry TPM\WMI → EndorsementKeyHash, WindowsAIKHash
// approach:
//    1. Read original EK hash from registry
//    2. Scan tpm.sys + tbs.sys + ACPI device extensions for the hash
//    3. Replace all instances with random bytes
//    4. Update registry WMI values (backup layer)
 
 
void SpoofTpm()
{
    // Read original TPM EK hash from registry
    UCHAR origEkHash[32] = {};
    ULONG ekLen = 0;
    UCHAR spfEkHash[32];
    for (int i = 0; i < 32; i++) spfEkHash[i] = RandByte();
 
    RegGetBin(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet"
        L"\\Services\\TPM\\WMI", L"EndorsementKeyHash",
        origEkHash, sizeof(origEkHash), &ekLen);
 
    // ── Kernel Layer: Scan TPM driver extensions ──────────────────────
    if (ekLen >= 20) // SHA-1 (20) or SHA-256 (32)
    {
        const WCHAR* tpmDrivers[] = {
            L"\\Driver\\TPM",
            L"\\Driver\\tbs",
            L"\\Driver\\ACPI",   // TPM2.0 ACPI-enumerated
        };
 
        for (ULONG d = 0; d < ARRAYSIZE(tpmDrivers); d++)
        {
            UNICODE_STRING name; RtlInitUnicodeString(&name, tpmDrivers[d]);
            PDRIVER_OBJECT drv = nullptr;
            if (!NT_SUCCESS(ObReferenceObjectByName(&name, OBJ_CASE_INSENSITIVE,
                nullptr, 0, *IoDriverObjectType, KernelMode, nullptr, (PVOID*)&drv)))
                continue;
 
            PDEVICE_OBJECT dev = drv->DeviceObject;
            while (dev) {
                if (!MmIsAddressValid(dev)) break;
                if (dev->DeviceExtension && MmIsAddressValid(dev->DeviceExtension))
                    MemReplace(dev->DeviceExtension, 0x3000,
                        origEkHash, ekLen, spfEkHash, ekLen);
 
                PDEVICE_OBJECT lower = IoGetLowerDeviceObject(dev);
                ULONG depth = 0;
                while (lower && depth < 8) {
                    if (!MmIsAddressValid(lower)) break;
                    if (lower->DeviceExtension && MmIsAddressValid(lower->DeviceExtension))
                        MemReplace(lower->DeviceExtension, 0x3000,
                            origEkHash, ekLen, spfEkHash, ekLen);
                    PDEVICE_OBJECT next = IoGetLowerDeviceObject(lower);
                    ObDereferenceObject(lower);
                    lower = next; depth++;
                }
                if (lower) ObDereferenceObject(lower);
                dev = dev->NextDevice;
            }
            ObDereferenceObject(drv);
        }
    }
 
    // ── Registry Layer ───────────────────────────────────────────────
    const WCHAR* wmi = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\TPM\\WMI";
    RegSetBin(wmi, L"EndorsementKeyHash", spfEkHash, 32);
 
    UCHAR spfAik[32]; for (int i = 0; i < 32; i++) spfAik[i] = RandByte();
    RegSetBin(wmi, L"WindowsAIKHash", spfAik, 32);
    RegSetDw(wmi, L"ManufacturerId", RandDword());
    RegSetDw(wmi, L"ManufacturerVersion", RandDword() & 0xFFFF);
}

Метод хорош тем, что мы не создаем аномалий в структурах драйверов, которые проверяет PatchGuard. Однако помните, что современные античиты могут кэшировать данные TPM еще на этапе ранней загрузки (Boot Start), так что маппить драйвер лучше как можно раньше.

Перед использованием не забудьте прочекать, как ваш маппер работает с валидными подписями, иначе отлетите за сам факт наличия левого драйвера в системе раньше, чем спуфер отработает.

Интересно, насколько долго этот метод будет жить против обновленного Vanguard, учитывая их любовь к сканированию расширений объектов устройств.
 
Назад
Сверху Снизу