Статья [Reverse-Engineering] Обход таблички -insecure в Left 4 Dead 2

  • colby57
  • UNEXPECTED_KERNEL_MODE_TRAP_M (1000007f)
  • 155
  • 2
  • 240
Шалом.

Сегодня хочу показать как я обходил запрет из-за insecure заходить на официальные сервера в Left 4 Dead 2.
Сама проверка находится в файле engine.dll, там мы и будем находить место сравнения и делать паттерн для патча.

Ищем строку "-insecure" в нашем дизассемблере

1614514567976.png



Находим функцию которая по итогу будет сравнивать имеется ли у клиента в параметрах запуска "-insecure", и после этого внизу есть ещё пару проверок после которых вас или кикнет за -insecure, или за сторонние модификации на локальном сервере.

1614514661887.png


1614514715546.png



Переходим в самое начало где должен быть совершен джамп на проверку параметра запуска

1614515024298.png


Видим тот самый "jnz loc_10058425", означать это может что переход в левую часть с инструкциями будет выполнен, если после инструкции "test al, al" результат не будет равен 0. Именно этот джамп нужен нам для патча, чтобы вырубить полностью проверку на параметр запуска.

Выделяем эту инструкцию и заходим в SigMaker, выбираем "Auto create ida pattern" и получаем наш паттерн для патча.

0F 85 ? ? ? ? 8B 9D ? ? ? ? 8D 8B ? ? ? ?

Теперь заходим в Visual Studio, создаёте проект DLL и в case DLL_PROCESS_ATTACH вписываете CreateThread для создания потока с функцией где будет наш патч.

И в этой функции начинаем писать наш патч:
C++:
char patch_bytes[3] = { 0xE9, 0xC0, 0x00 }; // Байты для патча с jnz на jmp
DWORD oldProtect;

std::uint8_t* insecure = PatternScan(GetModuleHandleA("engine.dll"), "0F 85 ? ? ? ? 8B 9D ? ? ? ? 8D 8B ? ? ? ?");

VirtualProtect(insecure, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy(insecure, patch_bytes, 3);
VirtualProtect(insecure, 3, oldProtect, nullptr);

C++:
std::uint8_t* PatternScan(void* module, const char* signature)
{
    static auto pattern_to_byte = [] (const char* pattern)
    {
        auto bytes = std::vector<int>{};
        auto start = const_cast<char*>(pattern);
        auto end = const_cast<char*>(pattern) + strlen(pattern);

        for(auto current = start; current < end; ++current)
        {
            if(*current == '?')
            {
                ++current;
                if(*current == '?')
                    ++current;
                bytes.push_back(-1);
            } else
            {
                bytes.push_back(strtoul(current, &current, 16));
            }
        }
        return bytes;
    };

    auto dosHeader = (PIMAGE_DOS_HEADER) module;
    auto ntHeaders = (PIMAGE_NT_HEADERS) ((std::uint8_t*)module + dosHeader->e_lfanew);

    auto sizeOfImage = ntHeaders->OptionalHeader.SizeOfImage;
    auto patternBytes = pattern_to_byte(signature);
    auto scanBytes = reinterpret_cast<std::uint8_t*>(module);

    auto s = patternBytes.size();
    auto d = patternBytes.data();

    for(auto i = 0ul; i < sizeOfImage - s; ++i)
    {
        bool found = true;
        for(auto j = 0ul; j < s; ++j)
        {
            if(scanBytes[i + j] != d[j] && d[j] != -1)
            {
                found = false;
                break;
            }
        }
        if(found)
        {
            return &scanBytes[i];
        }
    }
    return nullptr;
}

На этом всё, не знаю как будут обстоять дела с другими играми от Valve, но мой патч в Left 4 Dead 2 всё ещё не угробил мой аккаунт вак баном.

Демонстрация работы патча на видео:
 
Сверху Снизу