CS:GO anticheat update - trusted launch

Po měsíci testování v beta větvi je nová ochrana proti cheaterům - trusted mode launch v CS:GO povinná pro všechny hráče. Jelikož update vzbudil značný zájem médií a hráčů, podíval jsem na tuto funkci podrobně a v tomto článku chci ukázat, že nový update nejenže situaci s cheatováním prakticky nepomůže, ale naopak vytváří zbytečně složitější podmínky pro fungování VAC systému.
Update samotný je poměrně triviální - proces hry hookuje (upravuje chování) funkcí NtOpenFile a LdrOpenDll z knihovny ntdll.dll
// patch list
LdrOpenDll 8b ff 55 8b ec 83 e4 f8 --> e9 f5 06 58 fe 83 e4 f8
NtOpenFile b8 33 00 00 00 ba d0 60 --> e9 25 ec 13 00 ba d0 60
// Prvních 5 upravených bajtů NtOpenFile zavolá proceduru, která vypadá takto:
test byte ptr [ebp+arg_4], 20h // kontroluje přítomnost vlajky FILE_EXECUTE v DesiredAccess parametru (ta je vyžadována pro spuštění kódu a tedy nezbytná při zavádění dll)
jz short loc_XXX // pokud DesiredAccess vlajku neobsahuje, spustí se originální implementace NtOpenFile
push eax ; // na stack umístí obsah registru eax, v tuto chvíli ObjectAttributes->ObjectName->Buffer
call sub_YYY ; // zavolá proceduru, která ověří certifikát dll, výsledek je v registru al
test al, al ; // je hodnota registru al 0?
jnz short loc_XXX ; // ano -> sub_YYY ověřila dll a dll bude načteno
mov eax, 0C0000034h ; // v opačném případě vrátí STATUS_OBJECT_NAME_NOT_FOUND
pop esi
pop ebp
retn 18h
NtOpenFile je v kombinaci s několika podmínkami použita mimo jiné funkcí LoadLibrary(A) (Nt funkce se typicky nevolají přímo v ring3 aplikacích, i když je to možné), kterou využívají jednoduché injektory v kombinaci s CreateRemoteThread k zavedení vstupního dll do daného procesu.
Už v tuto chvíli je tedy patrné několik věcí - update se nijak nedotkne chování externích (neinjektovaných do hry, samostatné exe, které čte a upravuje hodnoty v RAM, používá se typicky funkce OpenProcess) cheatů. Fakt, že se jedná typicky o jednoduché cheaty (wallhack, trigger, aim, antiflash, radar..) není pro hráče útěchou, protože i tyto cheaty dokáží bezpečně zničit zážitek ze hry (složitější věci, kterých lze snadněji dosáhnout v internal cheatech jako spinbot, esp, resolver jsou proti legit hráčům overkill).
Složitější injektory interních cheatů fungují dnes typicky na bázi manuálního mapování - emulaci funkce LoadLibrary vlastní implementací (což je snadné udělat špatně, protože je potřeba hlídat několik věcí včetně správného nastavení ochranných vlajek regionů, vyřešení závislostí, jejich opožděné importy.. je toho hodně). Injektor tohoto typu může dll zavést, protože nepoužije patchnutou variantu LoadLibrary. VAC tím pádem ztrácí možnost něco zjistit z vlastního hooku (passthrough hooku), protože injektor tuto funkci nepoužívá a cheater, který předtím používal lehce odposlouchávatelnou funkci teď používá injektor, ze kterého odposlech té samé funkce k ničemu nevede.
Bypass tohoto updatu je triviální - stačí přečíst výchozí implementaci funkce LoadLibrary, zkopírovat do paměti prvních 5 bajtů (které hra upravuje) a po zapnutí hry je jednoduše vložit na správné místo, čímž lze efektivně dosáhnout volání originální implementace:
LPVOID originalniNtOpenFile = GetProcAddress(LoadLibraryW(L"ntdll"), "NtOpenFile"); // lpvoid je winapi typedef pro void*, tedy ukazatel bez datového typu
if (originalniNtOpenFile) // originalniNtOpenFile není null -> podařilo se získat ukazatel na implementaci funkce
{
char puvodniBajty[5]; // potřebujeme uložit prvních 5 bajtů, alokujeme na ně místo
memcpy(puvodniBajty, originalniNtOpenFile, 5); // originalniNtOpenFile ukazuje na začátek implementace, uložíme tedy prvních 5 bajtů od této adresy do naší proměnné
WriteProcessMemory(handleProcesuCska, originalniNtOpenFile, puvodniBajty, 5, NULL); // handleProcesuCska je výsledek OpenProcess(), na začátek implementace originalniNtOpenFile zapíšeme našich původních 5 bajtů
}
Kromě (nezamezení) cheatů update velmi dobře zamezil (ve své beta verzi) fungování různých overlayů, zejména tomu od Discordu a Nvidie. Oba overlaye jsou nyní nicméně správně podepsané a je možné je použít.
Celý update shrnu tak, že in-game popis funkce "prevents all 3rd party programs from affecting CS:GO game process" je značně nadnesený, vzhledem k tomu, že ve skutečnosti je blokovaná dnes poměrně úzká skupina zastaralých injektorů a jejich aktualizace do stavu, kdy mohou opět fungovat je otázkou několika minut.
Načítám diskuzi...