JhonnyD
Местный
- Сообщения
- 463
- Реакции
- 772
Компьютерные игры открывают перед нами новые миры, а мир читов - один из таких миров. Сегодня мы исследуем путь от теории к практике, написав собственный чит. Если вы хотите освоить искусство взламывания исполняемых файлов, это может быть отличным упражнением.
Существует несколько видов читов, которые можно разделить на следующие группы:
Давайте начнем, создав собственную игру на языке программирования C. Это поможет нам лучше понять, как работают читы. Я буду использовать C#, но структура данных будет максимально приближена к C++. Впрочем, читерить в играх на C# тоже довольно просто.
Принцип игры прост: нажмите Enter и проиграли. Это не слишком честное правило, не так ли? Давайте попробуем изменить его.
Теперь мы начнем реверс-инжиниринг. У нас есть файл игры, но вместо доступа к исходному коду, мы будем анализировать память и поведение приложения. Каждый раз, когда вы нажимаете Enter, ваше здоровье уменьшается на 15 единиц. Исходное количество здоровья - 100.
Мы будем использовать Cheat Engine для анализа памяти. Это приложение поможет нам найти переменные в памяти приложения и также предоставит хороший дебаггинг.
Первым шагом мы получим список всех значений 85 в памяти. Затем, когда мы нажмем Enter, значение здоровья снизится до 70. Мы отсеим все ненужные значения и найдем необходимое. После этого мы сможем изменить значение и проверить результат.
Проблема заключается в том, что после перезапуска игры адрес переменной будет изменен. Поэтому каждый раз искать его неэффективно. Мы должны использовать сканирование AOB (Array Of Bytes - массив байтов).
После каждого перезапуска приложения из-за рандомизации адресного пространства (ASLR) структура, описывающая вашего персонажа, будет находиться в новом месте. Чтобы ее найти, нам нужно сначала найти сигнатуру. Сигнатура - это набор байтов, которые не меняются в структуре и по которым мы можем искать в памяти приложения.
После нескольких нажатий Enter ваше здоровье уменьшилось на 55. Мы снова найдем необходимое значение в памяти и откроем регион, в котором оно находится. Выделенный байт будет началом нашего int32-числа. Например, 37 00 00 00 - это число 55 в десятичной форме.
Мы скопируем небольшой регион памяти и вставим его в текстовый редактор для дальнейшего изучения. Затем мы перезапустим приложение и снова найдем значение в памяти, скопируем такой же регион и сравним их. Нам нужно найти байты, которые остаются неизменными рядом с этой сигнатурой.
Таким образом, выделенные байты остаются неизменными, и мы можем использовать их как сигнатуру для поиска переменной. Сигнатура должна быть как можно более уникальной, чтобы ускорить сканирование. Например, сигнатура 01 00 00 00 будет слишком распространенной, лучше взять более уникальную, например, ED 03 00 00 01 00 00 00.
Теперь мы можем начать поиск этой сигнатуры в памяти игры. Как только сигнатура найдена, мы сможем найти адрес переменной и изменить ее значение.
Существует несколько видов читов, которые можно разделить на следующие группы:
- External (внешние читы): работают в отдельном процессе. Если загрузить внешний чит в память другого процесса, он становится скрытым внешним читом (hidden external).
- Internal (внутренние читы): встраиваются в процесс игры с помощью инжектора. После загрузки в память игры они вызываются в отдельном потоке.
- Pixelscan (читы, использующие сканирование пикселей): анализируют изображение с экрана и используют паттерны расположения пикселей для получения информации от игры.
- Network proxy (читы с использованием сетевых прокси): перехватывают сетевой трафик между клиентом и сервером, получая или изменяя необходимую информацию.
- Изменение памяти игры: используется API операционной системы для поиска и изменения участков памяти, содержащих нужную информацию, такие как здоровье или боеприпасы.
- Симуляция действий игрока: приложение повторяет действия игрока, например, кликая мышкой в заранее указанных местах.
- Перехват трафика игры: чит встаёт между игрой и сервером, перехватывая данные и изменяя их, чтобы обмануть клиент или сервер.
Давайте начнем, создав собственную игру на языке программирования C. Это поможет нам лучше понять, как работают читы. Я буду использовать C#, но структура данных будет максимально приближена к C++. Впрочем, читерить в играх на C# тоже довольно просто.
Принцип игры прост: нажмите Enter и проиграли. Это не слишком честное правило, не так ли? Давайте попробуем изменить его.
Теперь мы начнем реверс-инжиниринг. У нас есть файл игры, но вместо доступа к исходному коду, мы будем анализировать память и поведение приложения. Каждый раз, когда вы нажимаете Enter, ваше здоровье уменьшается на 15 единиц. Исходное количество здоровья - 100.
Мы будем использовать Cheat Engine для анализа памяти. Это приложение поможет нам найти переменные в памяти приложения и также предоставит хороший дебаггинг.
Первым шагом мы получим список всех значений 85 в памяти. Затем, когда мы нажмем Enter, значение здоровья снизится до 70. Мы отсеим все ненужные значения и найдем необходимое. После этого мы сможем изменить значение и проверить результат.
Проблема заключается в том, что после перезапуска игры адрес переменной будет изменен. Поэтому каждый раз искать его неэффективно. Мы должны использовать сканирование AOB (Array Of Bytes - массив байтов).
После каждого перезапуска приложения из-за рандомизации адресного пространства (ASLR) структура, описывающая вашего персонажа, будет находиться в новом месте. Чтобы ее найти, нам нужно сначала найти сигнатуру. Сигнатура - это набор байтов, которые не меняются в структуре и по которым мы можем искать в памяти приложения.
После нескольких нажатий Enter ваше здоровье уменьшилось на 55. Мы снова найдем необходимое значение в памяти и откроем регион, в котором оно находится. Выделенный байт будет началом нашего int32-числа. Например, 37 00 00 00 - это число 55 в десятичной форме.
Мы скопируем небольшой регион памяти и вставим его в текстовый редактор для дальнейшего изучения. Затем мы перезапустим приложение и снова найдем значение в памяти, скопируем такой же регион и сравним их. Нам нужно найти байты, которые остаются неизменными рядом с этой сигнатурой.
Таким образом, выделенные байты остаются неизменными, и мы можем использовать их как сигнатуру для поиска переменной. Сигнатура должна быть как можно более уникальной, чтобы ускорить сканирование. Например, сигнатура 01 00 00 00 будет слишком распространенной, лучше взять более уникальную, например, ED 03 00 00 01 00 00 00.
Теперь мы можем начать поиск этой сигнатуры в памяти игры. Как только сигнатура найдена, мы сможем найти адрес переменной и изменить ее значение.
