Приветствую всех ещё раз! Сегодня уже будет подготовка по обходу EAC, это лишь метод, который поможет ОБОЙТИ, ведь обойти EAC не значит удержать.
Сброшенные модули
Easy Anticheat использует драйверы ядра и модули пользовательского режима. Вы не можете подключить отладчик, пока не обойдете EAC, поэтому отреверсить EAC становится проблемой. Но, если вы можете войти в ядро, вы можете сбрасывать модули, что позволит вам статически сделать их анализ позже. Эти модули часто обновляются, но у нас есть несколько дампинг. Это ваша первая остановка для изучения того, как обойти EAC, вы можете статически проанализировать эти двоичные файлы и узнать, как работает Easy Anti Cheat.
ВНИМАНИЕ!!!! СЕЙЧАС БУДЕТ ЧАСТЬ С ОТКРЫТЫМ КОДОМ ОБХОДА! ЭТО НЕ ЗНАЧИТ ЧТО ВЫ 100% ОБОЙДЁТЁ EAC, ЭТО ЛИШЬ МЕТОД CVEAC
CVEAC-2020: байпасс EAC
"Разработчики читов особенно заинтересованы в проверках самоконтроля против античитов. Если вы можете их обойти, вы сможете эффективно исправить или "перехватить" любой античит-дамп, который может привести к пику или даже бану. В случае EasyAntiCheat, они используют драйвер режима ядра, который содержит некоторые интересные процедуры обнаружения. Мы обязаны изучить, как работают их проверки целостности и как их обходить, что позволяет эффективно отключить античит.
Обратный процесс
Первое, что нужно сделать, это определить, есть ли какая-либо проверка целостности. Самый простой способ - пропатчить любой лог из .text и посмотреть, решит ли античит выгнать или забанить вас через некоторое время. Примерно через 10-40 секунд после того, как я исправил случайную функцию, меня выгнали, показав, что они действительно проводят проверки целостности в своем модуле ядра. С помощью моего отладчика на основе визора, который использует возможности EPT, я установил точку останова памяти для функции, которая была вызвана их подпрограммой уведомления LoadImage ( PsSetLoadImageNotifyRoutine). Через некоторое время я смог найти, где они обращались к памяти.
Изучив внешние ссылки в IDA Pro и установив некоторые точки останова для инструкций, я обнаружил, откуда вызывается функция проверки целостности, одна из которых находится внутри подпрограммы уведомления CreateProcess (см. PsSetCreateProcessNotifyRoutine). Эта процедура заботится о некоторых частях инициализации античита, таких как создание внутренних структур, которые будут использоваться для представления игрового процесса.
Список регистрируемых модулей EAC.
некоторые драйверы которые по дефолту ищет EAC.
Процедура обнаружения подозрительных потоков EAC для кода, отображаемого вручную
Получение информации о потоке:
Перемещение по стеку:
Шаги по обнаружению подозрительных потоков:
Получение информации от всех потоков в текущем процессе (идентификатор потока, информация о стеке, базовый адрес потока)
[/CODE]
На сегодня всё, сегодня практически узнали способ обхода EAC, через 2-3 дня выйдет продолжение.
Сброшенные модули
Easy Anticheat использует драйверы ядра и модули пользовательского режима. Вы не можете подключить отладчик, пока не обойдете EAC, поэтому отреверсить EAC становится проблемой. Но, если вы можете войти в ядро, вы можете сбрасывать модули, что позволит вам статически сделать их анализ позже. Эти модули часто обновляются, но у нас есть несколько дампинг. Это ваша первая остановка для изучения того, как обойти EAC, вы можете статически проанализировать эти двоичные файлы и узнать, как работает Easy Anti Cheat.
ВНИМАНИЕ!!!! СЕЙЧАС БУДЕТ ЧАСТЬ С ОТКРЫТЫМ КОДОМ ОБХОДА! ЭТО НЕ ЗНАЧИТ ЧТО ВЫ 100% ОБОЙДЁТЁ EAC, ЭТО ЛИШЬ МЕТОД CVEAC
CVEAC-2020: байпасс EAC
"Разработчики читов особенно заинтересованы в проверках самоконтроля против античитов. Если вы можете их обойти, вы сможете эффективно исправить или "перехватить" любой античит-дамп, который может привести к пику или даже бану. В случае EasyAntiCheat, они используют драйвер режима ядра, который содержит некоторые интересные процедуры обнаружения. Мы обязаны изучить, как работают их проверки целостности и как их обходить, что позволяет эффективно отключить античит.
Обратный процесс
Первое, что нужно сделать, это определить, есть ли какая-либо проверка целостности. Самый простой способ - пропатчить любой лог из .text и посмотреть, решит ли античит выгнать или забанить вас через некоторое время. Примерно через 10-40 секунд после того, как я исправил случайную функцию, меня выгнали, показав, что они действительно проводят проверки целостности в своем модуле ядра. С помощью моего отладчика на основе визора, который использует возможности EPT, я установил точку останова памяти для функции, которая была вызвана их подпрограммой уведомления LoadImage ( PsSetLoadImageNotifyRoutine). Через некоторое время я смог найти, где они обращались к памяти.
Изучив внешние ссылки в IDA Pro и установив некоторые точки останова для инструкций, я обнаружил, откуда вызывается функция проверки целостности, одна из которых находится внутри подпрограммы уведомления CreateProcess (см. PsSetCreateProcessNotifyRoutine). Эта процедура заботится о некоторых частях инициализации античита, таких как создание внутренних структур, которые будут использоваться для представления игрового процесса.
Список регистрируемых модулей EAC.
- Dumper.dll
- Glob.dll
- mswsock.dll
- perl512.dll
- vmclientcore.dll
- vmwarewui.dll
- virtualbox.dll
- qtcorevbox4.dll
- vboxvmm.dll
- netredirect.dll
- atmfd.dll
- cdd.dll
- rdpdd.dll
- vga.dll
- workerdd.dll
- msvbvm60.dll
C++:
if ( AttachToProcess(process, (__int64)&v5) )
{
if ( GetUsermodeModule((UNICODE_STRING *)(StringTable + 4830))// Dumper.dll
&& GetUsermodeModule((UNICODE_STRING *)(StringTable + 4852))// Glob.dll
&& GetUsermodeModule((UNICODE_STRING *)(StringTable + 4870))// mswsock.dll
&& GetUsermodeModule((UNICODE_STRING *)(StringTable + 4894))// perl512.dll
|| GetUsermodeModule((UNICODE_STRING *)(StringTable + 4918))// vmclientcore.dll
|| GetUsermodeModule((UNICODE_STRING *)(StringTable + 4952))// vmwarewui.dll
|| GetUsermodeModule((UNICODE_STRING *)(StringTable + 4980))// virtualbox.dll
|| GetUsermodeModule((UNICODE_STRING *)(StringTable + 5010))// qtcorevbox4.dll
|| GetUsermodeModule((UNICODE_STRING *)(StringTable + 5042))// vboxvmm.dll
|| GetUsermodeModule((UNICODE_STRING *)(StringTable + 5066)) )// netredirect.dll
{
v3 = 1;
}
- Dbgv.sys
- PROCMON23.sys
- dbk64.sys
C++:
LOBYTE(v11) = 1;
if ( !(unsigned int)strstr2((__int64)&a1, (const char *)(StringTable + 8038), v11) )// Dbgv.sys
break;
LOBYTE(v16) = 1;
if ( !(unsigned int)strstr2((__int64)&a1, (const char *)(StringTable + 8047), v16) )// PROCMON23.sys
break;
LOBYTE(v17) = 1;
if ( !(unsigned int)strstr2((__int64)&a1, (const char *)(StringTable + 8061), v17) )// dbk64.sys
break;
Процедура обнаружения подозрительных потоков EAC для кода, отображаемого вручную
- API-интерфейсы,
- используемые для перечисления потоков и открытия для них дескрипторов: CreateToolhelp32Snapshot, Thread32First, Thread32Next, OpenThread
Получение информации о потоке:
- NtQueryInformationThread (ThreadBasicInformation и ThreadQuerySetWin32StartAddress)
Перемещение по стеку:
- GetThreadContext, RtlLookupFunctionEntry и RtlVirtualUnwind
Шаги по обнаружению подозрительных потоков:
Получение информации от всех потоков в текущем процессе (идентификатор потока, информация о стеке, базовый адрес потока)
C++:
[CODE]//getting thread info
if ( thread_info_obtained )
{
thread_info.ExitStatus = thread_basic_info.ExitStatus;
thread_info.TebBaseAddress = (__int64)thread_basic_info.TebBaseAddress;
thread_info.Priority = thread_basic_info.Priority;
thread_info.BasePriority = thread_basic_info.BasePriority;
thread_info.StartAddress = v18;
if ( thread_basic_info.TebBaseAddress )
{
thread_info.StackBase = *((_QWORD *)thread_basic_info.TebBaseAddress + 1);
thread_info.StackLimit = *((_QWORD *)thread_basic_info.TebBaseAddress + 2);
}
stack_walk_thread(*v8, v14, &thread_info.RipsStackWalk);
LABEL_22:
v15 = v1->CurrentEntry;
if ( v1->LastEntry == v15 )
{
reallocate_vector_thread_information(v1, v15, &thread_info);
}
else
{
memcpy_thread_information(v11, v15, &thread_info);
++v1->CurrentEntry;
}
}
reset_thread_information_struct(&thread_info);
++v8;
v19 = v8;
}
C++:
//stack walking routine
run_count = 0;
while ( run_count < 9 )
{
entry_pc = RtlLookupFunctionEntry(Context.Rip, &v20, 0i64);
if ( entry_pc )
{
RtlVirtualUnwind_0(0i64, v20, Context.Rip, entry_pc, &Context, &v23, &v22, 0i64, thread_rip_1);
if ( !Context.Rip )
return vec_rips_stackwalk->FirstEntry != vec_rips_stackwalk->CurrentEntry;
thread_rip_1 = Context.Rip;
current_entry = vec_rips_stackwalk->CurrentEntry;
if ( vec_rips_stackwalk->LastEntry == current_entry )
{
reallocate_vector_qword(vec_rips_stackwalk, current_entry, &thread_rip_1);
}
else
{
*current_entry = Context.Rip;
++vec_rips_stackwalk->CurrentEntry;
}
}
++run_count;
RtlLookupFunctionEntry = *(__int64 (__fastcall **)(DWORD64, __int64 *, _QWORD))RtlLookupFunctionEntry_0;
}
return vec_rips_stackwalk->FirstEntry != vec_rips_stackwalk->CurrentEntry;
На сегодня всё, сегодня практически узнали способ обхода EAC, через 2-3 дня выйдет продолжение.