Категория > Новости > Чит своими руками. Вскрываем компьютерную игру и пишем трейнер на C++ - «Новости»
Чит своими руками. Вскрываем компьютерную игру и пишем трейнер на C++ - «Новости»26-03-2022, 00:02. Автор: Оксана |
Hyper Light Drifter (далее HLD). Если ты планируешь поэкспериментировать с коммерческой игрой, обрати внимание на сайт pcgamingwiki, а также на игры с открытым исходным кодом.warningТак как для написания этой статьи я буду использовать коммерческую игру, мне нужно удостовериться, что лицензионное соглашение (EULA) позволяет это делать. Начав установку и внимательно прочитав текст EULA, я убедился, что в нем явно запрещается написание и распространение только тех читов и трейнеров, которые мешают работе сервиса, а в нашем случае ничего подобного не планируется. Поэтому смело продолжаем установку. EULA HLD Поиск значенийДля поиска значений, которые будет изменять чит, мы станем использовать Cheat Engine (далее CE). Запустим игру и в настройках игры выберем оконный режим — нам нужно, чтобы на экране помещалось еще что‑то, кроме игры. Оконный режим Как видим, в оконном режиме отсутствует панель заголовка, с помощью которой мы могли бы перетаскивать окно игры по экрану. Чтобы исправить эту неприятность, откроем отладчик x64dbg, а именно его 32-битную версию ( Поставим брейк‑пойнты на функции Вкладка символов Видим, что наше окно создается с параметром Значение параметра dwStyle, равное WS_POPUP Поменяем это значение на Параметр dwStyle, измененный на WS_OVERLAPPED И вот результат: теперь мы можем перемещать окно. Оконный режим с панелью заголовка окна После того как мы настроили окно игры с помощью отладчика, ненадолго отложим его. Чтобы найти нужные нам значения в Cheat Engine, разберемся с теорией. Что такое статический адресСтатический адрес — это адрес, который изменяется предсказуемо по отношению к модулю, которому он принадлежит. Если переменная глобальная, то можно найти ее в сегменте данных. Статические адреса указываются в формате Если же переменная локальная, то искать нужно в стеке. Для этого получаем Поиск показателей здоровьяЗапускаем Cheat Engine и подключаемся к процессу игры. Подключение к процессу игры Так как мы не знаем, в каком типе хранится показатель здоровья, выставляем следующие параметры для первого сканирования. Первое сканирование Далее продолжаем сканирование, не забывая при этом терять hp (показатель здоровья) в игре. Делаем мы это для того, чтобы отслеживать изменения значения hp в памяти игры через CE, а также уменьшать значение в поиске для следующих сканирований. Делать мы это будем до тех пор, пока не будет достигнуто адекватное количество значений в окне CE. Адекватное количество значений в данном случае — это такое количество адресов, проверка которых займет максимум минут пять. Найденные адреса и их значения Мне приглянулись вот эти два адреса, которые я добавил в нижнее окно двойным щелчком мыши на них. Приглянулись они мне в первую очередь потому, что значения по этим адресам среди всех остальных имеют наибольший тип — double. Всегда нужно проверять от большего типа к меньшему. То есть сначала проверяем адреса, хранящие тип double, затем float, после integer и так далее. Более подробно о размере типов данных можно прочитать в документации Microsoft. Добавленные адреса Если мы поменяем значение по адресу Индикатор hp Если теперь мы поменяем значение по адресу Изменение hp Дадим название найденным нами адресам: Поиск статического адреса для индикатора здоровьяДля дальнейшего поиска статического адреса вернемся к отладчику. В окне дампа переходим по ранее полученному адресу Значение по адресу 0x36501A30 в окне дампа Ставим по адресу Выйдя из этой функции, проследим, откуда она получает свой первый параметр. Мы увидим, что передаваемый параметр — это возвращаемое значение функции по адресу Поставим брейк‑пойнт на вызов функции по адресу После того как мы узнали адрес Мы нашли статический адрес! Если посмотреть его расположение в памяти, он находится в секции Зная все смещения, добавим их в CE, нажав Поиск значения числа патроновТеперь приступим к поиску значения числа патронов (ammo). Первое сканирование делаем с такими же параметрами поиска, как когда мы искали здоровье. В данном случае мы смогли найти лишь одно значение, и это значение полосы, которая показывает число боеприпасов. В игре этот индикатор не появился. В отличие от полосы здоровья, он отображается только после нажатия на кнопку E или во время выстрелов. Поиск статического адреса для ammoМы понимаем, что показания индикаторов в игре всегда сравниваются с фактическими. Если одна из полос показывает не то, что нужно, ее длина изменяется. Поэтому возвращаемся к отладчику и начинаем с аппаратного брейк‑пойнта на запись по адресу По аналогии с поиском hp, выходим из функции. Так как мы уже знаем, что индикатор должен получать значение где‑то раньше, нам придется пролистать окно дизассемблера выше, пока мы не увидим функцию, предположительно получающую фактическое значение ammo. Мы видим, что в этой функции мы уже были, а это значит, что она тоже получает значение, но уже ammo — Добавив это «странное» значение в Cheat Engine, а потом изменив его, к примеру, на 100, мы увидим, что на экране появится индикатор патронов и его значение поменяется. Значит, мы нашли адрес, в котором хранится значение ammo в игре. Зная все смещения от статического адреса к адресу значений ammo, добавим их в CE, нажав infoСкорее всего, боеприпасы в HLD представляют собой заряд энергии и поэтому хранятся в процентах, ведь при их поиске через отладчик можно было увидеть строки, содержащие слово Проверка полученного статического адресаЧтобы проверить, правильно ли мы определили адреса, нужно выйти в меню игры и вернуться к игровому процессу или же перезапустить игру. Проверка для HPТак выглядит наша cheat table для hp. Таблица до выхода в меню / перезапуска игры А вот так она выглядит после перезапуска игры. Таблица после запуска игрового процесса Проверка для ammoТак выглядит наша cheat table для ammo. Таблица до выхода в меню / перезапуска игры А вот так она выглядит после перезапуска игры. Таблица после запуска игрового процесса Как будет выглядеть наш указатель в C++В нашем чите доступ к найденным адресам значений будет таким.
static_addr = (DWORD)GetModuleHandle(0);
static_addr = *(DWORD*)(static_addr + 0x255AF150);
static_addr = *(DWORD*)(static_addr);
static_addr = *(DWORD*)(static_addr + 0xD48);
static_addr = *(DWORD*)(static_addr + 0x0C);
static_addr = (DWORD*)(static_addr + 0xC4);
static_addr = *(DWORD*)(*static_addr + 0x08);
static_addr = *(DWORD*)(static_addr + 0x44);
static_addr = *(DWORD*)(static_addr + 0x10);
drifter_hp = (double*)(DWORD*)*(DWORD*)(static_addr + 0x1FD8);
drifter_ammo = (double*)(DWORD*)*(DWORD*)(static_addr + 0x268C);
Написание трейнераПо принципу действия читы можно разделить на две группы: внутренние и внешние. Внешние читы — это отдельное приложение, запущенное в системе в виде процесса. Внутренние читы обычно реализованы как динамическая библиотека, внедряемая в процесс игры. Мы будем писать внутренний чит, поэтому нам понадобится не только сама библиотека, но и инжектор, который внедрит нашу библиотеку в процесс игры. Инжектор получит список процессов, найдет процесс игры, выделит в ней память, в которую запишет наш внутренний чит, а после создаст удаленный поток внутри игры для выполнения кода нашего чита. Перейти обратно к новости |