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

Гайд Как ВЫ должны были изучать кс2

PoC Life
Участник
Участник
Статус
Онлайн
Регистрация
22 Авг 2022
Сообщения
1,339
Реакции
215
Всем привет. Тема относится к людям, которые не понимают каким образом читеры находят глобальные переменные, функции, или бездумно копируют код и не понимают откуда он взялся. Сегодня мы разберёмся, каким образом ВЫ должны были изучать игру кс2 изнутри.

Предисловие или почему всё так легко?
Если вы хоть раз видели как кто-то обновляет себе оффсеты или сигнатуры под функции вы наверняка удивлялись насколько быстро это происходит. Также большиство говорит, что кс2 дырявая, давайте разберёмся правда ли это.

Если говорить с точки зрения преимуществ в читах, то есть игры и по хуже, например мобильные. В них много расчётов производит клиент и отправляет на сервер (либо вообще нахуй не отправляет), что даёт плоды реализациям от вечных патронов до режима бога или полёте по всей карте. Обосновывается это тем, что игры создаются на телефон, а как правило интернет на телефоне не самый быстрый, поэтому во избежания отправки лишних данных они переносят большую часть основной логики в клиент. В кс2 такого почти нету, вы не можете летать по всей карте, убивать каждого с одной пули в ногу с глока или включить себе режим бога. Однако не ясно, почему доверие генерации сприда на данный момент отдана клиенту, и всё ещё игру нельзя назвать слишком дырявой, ведь условно в том же фортнайте банально можно телепортироваться и летать находясь в машине :)

Если говорить с точки зрения защищённости клиента и античита, то тут кс2 очень сильно разочаровывает потому, что иметь такое количество гавна это надо постараться. Мне до сих пор непонятно, почему игра собрана в дебаг режиме. Почему-то в коде часто виден путь до исходного файла:
Pasted-image-20260422200328.png

Pasted-image-20260422200549.png

Pasted-image-20260422225400.png

Почему-то игра имеет RTTI (Run-Time Type Information):
Pasted-image-20260422200928.png

Ещё валвы любят добавлять огромную кучу команд и описывать их значение, что ещё сильно упрощает анализ. А также игра имеет очень много схожестей с CS:GO, исходный код которого сливался аж несколько раз. И поверьте, мне есть что ещё добавить.

GlobalVars
Начнём с того, что в движке сурс2 (а также в сурс1) есть глобальные переменные, распространяющиеся между движком и игрой:
Pasted-image-20260422201309.png

Такой вывод можно сделать из их комментария. Глобальные переменные хранят в себе название карты, количество сущностей, тип режима игры и тд:
Pasted-image-20260422201357.png

Вспомним как мы можем узнать на какой мы карте? Напрягаем извилины и вспоминаем про cl_showfps:
Pasted-image-20260422201535.png

Также глобальные переменные хранят игровое время, которое тоже палится из команды cl_showpos:
Pasted-image-20260422201639.png

И ещё cl_showtick:
Pasted-image-20260422203914.png

Все они отображаются в одном месте в коде.
Pasted-image-20260422204457.png

Давайте посмотрим что такое 20496A0 в чит энжине (вы можете использовать ReClass, однако я в своей жизни ни разу им не пользовался):
Pasted-image-20260422204700.png

Что ты маленький привет. Теперь мы знаем, что оффсет 0x20496A0 указывает на GlobalVars, где +0x180 является путём до карты.
Pasted-image-20260422204818.png

А вот и RenderTime (значение чуть чуть расходится с игрой, т.к. чит энжин не так часто обновляет значения).
Ray Tracing
Для того, чтобы понять, попала ли в противника пуля и сколько нанесла урона используется технология Ray Tracing. Она пробрасывает луч от точки A до точки B и ищет соприкосновения по фильтру. Фильтром может являться что угодно: вода, сущности, игроки, материалы на карте ну или же ничего. И да, для неё тоже есть консольная команда - cast_ray:
Pasted-image-20260422205537.png

Она визуально показывает откуда пробрасывался луч (на скриншоте в момент написания команды я стоял справа) и где он соприкоснулся, эта информация также передаётся вам в консоль:
Pasted-image-20260422205641.png

Откуда прекрасно виден hitbox, hitgroup, кость, поверхность, позиция и остальные параметры. Попробуем ещё раз, но уже в стену:
Pasted-image-20260422205745.png

Pasted-image-20260422205752.png

На этот раз мы попали в мировую сущность, у неё нету костей, однако видна поверхность Wood_Plank и тип материала - mesh.
Данная команда находится не в client.dll:
Pasted-image-20260422205928.png

т.к. C-Style строчка это просто последовательность символов оканчивающаяся на нулевой байт, то мы можем просто найти слово cast_ray, просканировав файлы игры. Вы можете использовать абсолютно любой инструмент, я лично пользуюсь notepad++, особого значения кроме скорости здесь нет:
Pasted-image-20260422210102.png

Pasted-image-20260422211401.png

Заходим в функцию с выполнением cast_ray и находим там сообщения, которые видели ранее в консоли:
Pasted-image-20260422211641.png

Идём от обратного
Pasted-image-20260422211926.png

Видим, что большинство информации приходит к нам из v45. Заранее кстати интересно посмотреть что за функция sub_B892B0, уж больно много параметров она принимает:
Pasted-image-20260422212053.png

Pasted-image-20260422212108.png

и мы попадаем в серверный TraceShape. Однако мы работаем с клиентом, поэтому давайте попробуем найти по этой строчке функцию в клиенте:
Pasted-image-20260422212156.png

и она действительно существует
Pasted-image-20260422212219.png

А по хрефам я уже начинаю замечать присутствие фильтров. Кстати каждый раз в первый аргумент идёт какая-то константа. Посмотрев на использование первого аргумента в функции становится ясно, что это какой-то виртуальный класс:
Pasted-image-20260422212346.png

Так как у нас есть RTTI информация мы можем с лёгкостью посмотреть что это. Я использую чит энжин, т.к. он умеет считывать название класса с RTTI:
Pasted-image-20260422212438.png

А вот и указатель на класс CVPhys2World.

Более подробно эту функцию вы можете изучить сами, я не вижу смысла тратить половину содержимого статьи на разжёвывание одной функции.

Дамаг сквозь стены AKA Penetration
Если вы уже реализовали свой первый аим, наверняка столкнулись с проблемой простреливаний через стены. К счастью и такая команда у меня для вас есть - sv_showimpacts_penetration 1:
Pasted-image-20260422213137.png

После выстрела вы увидите каждое соприкосновение пули и её продолжение сквозь некоторые стены. На каждом выстреле появляется текст с жирностью стены (или STOPPED при её достаточной твёрдости для остановки пули), потерянный урон, название поверхности соприкосновения, урон после соприкосновения и дистанцию.
Снова отправляемся в server.dll:
Pasted-image-20260422214010.png

Pasted-image-20260422214730.png

Текст здесь форматируется в отдельной функции, и дамаг получается с использованием третьего аргумента.
Вот вызов этой функции:
Pasted-image-20260422214817.png

Чтобы не закидывать вам триллион скриншотов, я соберу основной флоу:
C++:
Expand Collapse Copy
sub_9EA850((__int64)v179, (float)a8, a5, a10, a6, v33, (__int64)v32);

while (1) {
    hit = hits + 24 * idx; // элемент соприкосновения
 
    if ((*(_BYTE *)(hit + 20) & 1) == 0) // проверка, остановилась ли пуля
        break;
 
    damage_applied = *(float *)(hit + 8); // итоговый урон
 
    hit_number++;
    idx++;
 
    if (hit_number >= max_hits)
        break;
}
sub_9EA850 проходится по всем поверхностям и заполняет информацию о результате простреливания:
C++:
Expand Collapse Copy
surfaces_count = (int *)(a1 + 0x1820);

for ( i = 0; ; i += 24 ) {
    surface = *(_QWORD *)(a1 + 0x1828) + i;
    need_stop = sub_A07990(a1, (float *)v18, surface, a6, a7); // заполнение информации о простреливании:
    // +0x0  - текущий урон
    // +0x4  - множитель пробиваемости
    // +0x8  - урон после соприкосновения
    // +0xC  - hitgroup
    // +0x12 - surface id
    // +0x14 - флаги, если первый бит равен 0 - значит пуля остановилась
 
    if (need_stop)
        break;
 
    if (i >= *surfaces_count)
        break;
}

WorldToScreen и ViewMatrix
Для отрисовки точки с мировыми координатами в 2д пространстве нам нужно перевести их, используя видовую матрицу. В игре мы также можем встретить такой элемент:
Pasted-image-20260422235309.png

это простой худ под союзником. Находится эта функция довольно просто:
Pasted-image-20260422235542.png

Функция создаёт худ панель в панораме и ставит хук на получение пакета от сервера, в случае которого игрок должен иметь healthbar над собой:
Pasted-image-20260422235704.png

Сам код обновления позиции healthbar'а довольно большой, поэтому я как и в прошлый раз покажу вам его в сокращённом виде:
C++:
Expand Collapse Copy
player_pos = ...; // позиция игрока
sub_B726B0(&player_pos, modified); // преобразование мировых координат в нормализованные 2д (NDC)
sub_CEE0C0(modified); // преобразуем NDC координаты в 2д пиксели на экране

screen_x = modified->x;
screen_y = modified->y;

scale = 1.0 / (*(*v45 + 64i64))(v45);

// центрирование. v53, v54 - размеры хп текста
bar_x = ((screen_x - (v53 * 0.5)) * scale);
bar_y = ((screen_y - (v54 * 0.5)) * scale);

panorama_translate3d = util::allocate(32i64, v59);
*panorama_translate3d = &panorama::CTransformTranslate3D::`vftable';
*(panorama_translate3d + 8) = bar_x;
*(panorama_translate3d + 16) = bar_y;
Здесь мы видим sub_B726B0, который работает как первая часть реализации WorldToScreen:
Pasted-image-20260423001044.png

Вот тут остановимся. View matrix лежит в unk_232EAC0, поэтому теперь вы знаете как найти видовую матрицу.
Продолжаем. sub_CEE0C0 отвечает за вторую часть WorldToScreen:
Pasted-image-20260423001305.png

Отсюда вы также можете взять функции получения размера экрана
Pasted-image-20260423001324.png

v1 это указатель на width, v2 на height. qword_2324E60 указывает на CEngineClient.

Конец
На этом всё, пишите что думаете насчёт этого. Думал кстати, что получится больше. Всем пока
 
Последнее редактирование:
в кс2 люди что то уровня майнкрафтеров бывают вместо того что бы сами прореверсить они: "дайте паттерн на эту функцию" "дайте фикс"
 
Самая популярная игра и простая для изучения с кучей сурсов. Конечно это все будет.
Хотя какое-либо шифрование не особо бы помогло, ибо игре все равно это равно должна расшифровывать и ты это делаешь также как она. Валорант раст овервоч тому пример
если люди заходят в сферу кс2 с целью получения денег они не станут зарабатывать с читов на кс2 99% почему бы не пойти и делать читы на юнити где ты запустил ил2цппдампер где ты буквально получаешь все названия функций и многое другое кажется самое легкое что может быть ну исключения шифрование метадаты
 
в кс2 люди что то уровня майнкрафтеров бывают вместо того что бы сами прореверсить они: "дайте паттерн на эту функцию" "дайте фикс"
Самая популярная игра и простая для изучения с кучей сурсов. Конечно это все будет.
Хотя какое-либо шифрование не особо бы помогло, ибо игре все равно это равно должна расшифровывать и ты это делаешь также как она. Валорант раст овервоч тому пример
 
Назад
Сверху Снизу