Перейти к содержанию

MasterGH

Ветераны
  • Постов

    2 999
  • Зарегистрирован

  • Победитель дней

    129

Сообщения, опубликованные MasterGH

  1. Тема будет не плохой тренировкой на Дельфи. Взято из интернета.

    Результат на картинке (внизу).

    Готовый вариант.

    unit Unit1; 

    interface

    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls, Grids;

    type

    TPole = record
      x: Byte;
      y: Byte;
    End;

    TForm1 = class(TForm)
       Button1: TButton;
       sg: TStringGrid;
       procedure Button1Click(Sender: TObject);
      private
       SapMap: Tpole;
      public
      end;

    var
    Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.Button1Click(Sender: TObject);

    Var
    hWn: HWND;
    PID, hProc, dwReaded: DWord;
    buf: Byte;
    i, r: Dword;
    StartAddr: Dword;

    begin
    hWn := HWND(FindWindow(nil, PChar('Сапер')));
    If IsWindow(hWn) Then
      Begin
      GetWindowThreadProcessId(hWn, PID);
      hProc := OpenProcess(PROCESS_VM_READ, False, PID);
      Try
        If (hProc <> 0) Then
          Begin
          ReadProcessMemory(hProc, ptr($10056AC), @buf, 1, dwReaded);
          SapMap.x := buf;
          ReadProcessMemory(hProc, ptr($10056A8), @buf, 1, dwReaded);
          SapMap.y := buf;

          sg.ColCount := SapMap.x;
          sg.RowCount := SapMap.y;
          For i := 0 To (sg.ColCount - 1) Do
          For r := 0 To (sg.RowCount - 1) Do sg.Cells[i,r] := ' ';

          StartAddr := $01005361;
          For i := 0 To (SapMap.y - 1) Do
              For r := 0 To (SapMap.x - 1) Do 
                  Begin 
                     ReadProcessMemory(hProc, ptr((i*$20) + StartAddr + r), @buf, 1, dwReaded); 
                     If (buf = $8F) Then sg.Cells[r, i] := 'X'; 
                  End; 
      
          End;

      Finally
      CloseHandle(hProc);
      end;

      end; //If IsWindow(hWn)
    end;

    end.

    saper.gif

  2. Выставление оконного режима по горячей клавише F2.

    Весь интернет облазил как реализовать  ChangeDisplaySettings(NULL,0) на Дельфи. Просто ради интереса. Дело в том что NULL  нельзя поставить в Дельфи и в C#, потому что там должен быть укзатель на структуру. Можно в VC++ и средах ассемблера... Никто не знает ответа... Но не МастерGh  B)

    Для результа - один раз восстановить окно дисплея подходит следующий метод  Внизу я написал код с указателем на объект DevMode (или это запись, уже точно не помню), затем скомпилировал, пошёл в OllyDbg и пропатчил начальные параметры перед функциией

    Было 

    004520BE   PUSH                             Project1.00459542; //флаг
    004520C0 PUSH Project1.004595A4 // указатель на структуру 
    004520C5 CALL ; ChangeDisplaySettingsA

    Стало

    000514BE     PUSH 0 // а вот и Null тот самый.
    000514C0  PUSH Project1.004595A4
    000514C5  CALL ; ChangeDisplaySettingsA

    Сначала я написал такой код (кинул на пустую форму таймер и добавил строки (выделенные), остальное всё автоматически генерировалось)

    unit Unit1;

    interface

    uses

    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

    Dialogs, StdCtrls, ExtCtrls;

    type

    TForm1 = class(TForm)

    Timer1: TTimer;

    procedure Button1Click(Sender: TObject);

    procedure Timer1Timer(Sender: TObject);

    private

    { Private declarations }

    public

    { Public declarations }

    end;

    var

    Form1: TForm1;

    implementation

    {$R *.dfm}

    var

    DevMode : TDeviceMode;

    Msg : TMSG;

    procedure TForm1.Button1Click(Sender: TObject);

    begin

    ChangeDisplaySettings(DevMode,0);

    end;

    procedure TForm1.Timer1Timer(Sender: TObject);

    begin

    TranslateMessage(Msg);

    if (GetAsyncKeyState(VK_F2) <> 0) then  ChangeDisplaySettings(DevMode,0);

    DispatchMessage(Msg);

    end;

    end.

    После патча, программа ставила основной режим и игра была в окне если его разрешение было меньше чем рабочего стола перед запуском игры.

    Вот задание написать эту программу максимально маленького размера, а если не можете или лень то можете скачать отсюда.

    Если игра постоянно проверяет видеорежим и выставляет свой, то моя программа не поможе - окно вновь будет восстанавливаться, но я думаю таких игр мало. В этом случе тоже можно написать утиль, но его придётся уже писать с хуками: после срабатывани ChangeDisplaySettings на установку полноэкранного режима надо пресекать исполнения режима и выводить ложный результат, дескать режим был установлен...

  3. Тема. Установка оконного режима в ручную.

    Описание всех фукнкций и процедур можно найти в интернете. Они есть у всех в библиотеках user32.dll (если не ошибаюсь).

    Похали. Берём игрушку и OllyDbg. Ищем все вложенные функции. Обращаем внимание на те, которые я пишу ниже.

    При создании окна работают CreateWindowExA (или CreateWindow). Нужно поставить на них всех брейкпоинт, когда он сработает, то нужно изменить параметры в функции: высоту и ширину. Далее отпустить игру.

    После задания размеров окна игра пытается получить его EnumDisplaySettings.

    Далее фунцией ChangeDisplaySettings (или ChangeDisplaySettingsEx) пытается запомнить режим и включить полноэкранный.

    LONG ChangeDisplaySettings(

    LPDEVMODE lpDevMode, // графический режим

    DWORD dwflags // параметры графического режима

    );

    Я не разобрался ещё какие цифры какой означают флаг, пока известно вот что:

    dwflags при двойке - я думаю так или иначе был сохранением экрана.

    dwflags при четвёрке - немедленно включал полноэкранный.

    Болле подробно о флагах и инструкциях можно посомтреть здесь

    Не допускайте чтобы флаг был четвёркой, пример ниже.

    Как я устаналвивал оконный режим в игре "Ghost Master Demo" в OllyDbg.

    1. Перехватил CreateWindowExA (поставил ширину и высоту 800 на 600)

    2. На ChangeDisplaySettings внутри user32 поставил бряк. Когда он прервался я вышел вверх на неявный call (см. ниже)

    jle метка1 // этот прыжок я сделал безусловным

    цикл

    call ebx // неявный вызов ChangeDisplaySettings(указатель, 2)

    call ebx //второй неявный ChangeDisplaySettings(указатель, 4)

    конец цикла

    Метка1:

    // тут же в отладке проскочила инфа в регистрах о том что режим остался "vga"

    Во вреия игры при загрузке нового уровня, часто выполнялся тот прыжок jle метка1 и его пришлось просто пропатчить на jmp метка1.

    Таким образом Игра была постоянно в оконном режиме (доказательство на рисунке). Хочу заметить что d3dWindower не помог, иначе бы не было этого туториала. На этом всё.

    okno.jpg
  4. Базовый способ взлома — это поиск адреса в памяти игры по правилам поиска, изменение значения адреса и заморозка значения по адресу. Это можно сделать с помощью программ Artmoney, Cheat Engine и других сканеров памяти. Правила поиска описываются в руководстве Artmoney на русском языке. Этим способом можно взломать (или сделать читы) чуть ли не на все игры.

     

    Если в игре загружается игровой уровень или игровая сцена, то  адреса в памяти могут поменяться и придется адрес искать вновь. В этом случае можно использовать поиск указателей, который может быть как быстрым так и очень долгим. Попробовать можно в тех же программах Artmoney, Cheat Engine.

     

    Если поиск указателей не хотим использовать, т.к. он долгий, то есть вариант изменить код игры для того чтобы по адресу записывалось другое значение. Попробовать можно в тех же программах Artmoney, Cheat Engine. Для этого нужно поставить брейкпоинт на найденный адрес, выйти на инструкцию ассемблера и что-то с ней сделать. Для нужно поискать руководства по инструкциям ассемблера.

     

    Кратко

    1) если инструкция пишет в адрес, то её можно занопить, т.е. стереть. mov, dec, sub или другие...

    2) с Cheat Engine можно заменить инструкцию, если размер инструкции в байтах подойдет. Если не подойдет, то заменяем инструкцию на инструкцию прыжка на адрес выделенной памяти, в которой пишут немного "сложного" ассемблерного кода и затем делают прыжок обратно.

     

    Если все делается с Cheat Engine, то на действия вешаются хот-кеи. Создается таблица или трейнер и все готово. Берем любую игру, Cheat Engine, делаем трейнер и публикуем его на форуме или где захотим.

     

    Вы можете пойти по следующим путям:

    1) писать скрипты для CE (Cheat Engine)

    2) генерировать трейнеры на CE,

    3) можете писать трейнеры на языке программирования.

     

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

    1) Туторы по CE Autoassembler Engine;

    2) Grand Theft Auto Vice City, метод указателей (использовалась TSearch, но вы должны всё понимать как если бы это было CE )

    3) Посмотрите наш раздел по Cheat Engine

    4) Ну и чиnаем всё что найдёте у нас на сайте и на форуме.

    Для более опытных  Lua Engine в CE для создания трейнеров или создание на языках программирования с Windows API.

     


    Термины

     

    Скрытый текст

    Опкод (Operation Code) - часть инструкции, равная одному байту

    Ноп (Nop - Noop) - опкод "пустой", ничего не делающей инструкции. Используется для выравнивания оригинальных инструкций при создании Code Cave.

    Нопить - забивать какую-либо инструкцию нопами (nop).

    Типы данных - прежде всего тип данных обусловлен размером количества единиц информации битов или байтов. Затем процессор может их воспринимать как знаковое число, целое число, вещественное число или как текст.

    Проверочные байты - байты, которые не меняются при разных обновлениях и патчах игры. Помогают найти определить адрес внедрения, если он был смещен.

    Статический адрес - адрес в памяти, который не меняет своего положения в памяти игры. Виден как зелёный адрес в Cheat Engine и MHS. Находится в регионах памяти с типом Image.

    Динамический адрес - адрес в памяти, который меняет своё положение в памяти игры после некоторого события.

    Цепочка указателей - указатель на указатель больше чем одного уровня. Представление цепочки указателей обозначается фигурными скобками. Пример f[[game.exe+0x6454]+5*54h]. Более подробно в справке MHS.

    Структура - структура это набор данных. Главные параметры структуры: есть начало и конец, соответственно размер. В структурах могут быть данные как одного типа так и разных.

    Расструктуризация - раскрытие характеристик определённых структур данных при которой становится известно, на каком смещении от начала структуры какие данные находятся. Например, здоровье находится на смещении +0x48, от начала структуры или начала структуры объекта.

    Объект (игровой объект) - объект можно воспринимать буквально как явление, предмет, на к-рый направлена чья-н. деятельность, чье-н. внимание (книжн.) . Объект в программировании или при обмане игр, когда речь идёт об инструкциях работающих с объектами стоит воспринимать как структуру данных в памяти, которая отражает поведение некоторой абстрактной сущности. Например, юнита в игре можно реализовать как объект на основе описания класса юнита. Объект наполняется данными по описанию класса, также к данным по смещениям от начала структуры объекта "привязываются" методы. Таким образом методы будут работать с некоторым объектом на основе описания класса.

    Класс - это описание данных и методов объекта. На описании класса реализуются объекты или один объект. Класс также является типом.

    Метод - в дизассемблерном представлении это блок кода который направлен на работу с данными объекта описанному по определённому классу. Этот блок кода (иначе говоря функция) может вызываться из любого места адресного пространства игр чтобы обращаться к данным объекта.

    Массив данных - массив представляет однотипную структуру данных. Например, массив байт или массив некоторых объектов.

    Отладчик - обычно, включает в себя также дизассемблер. Позволяет ставить брекпоинты, снимать показания регистров изменять регистры и т.п.

    Брейкпоинты - точки остановки программы. Можно поставить на адрес на чтение и запись. Можно поставить на инструкцию. В результате остановки игрового процесса можно снять показания регистров. Брейкпоинты бывают также условные, которые выполняются при определённых условиях (см. правку по ollyDbg)

    Дизассемблер - позволяет перевести байт-код в ассемблерное представление. Ассемблер - язык программирования, самый близкий к машинному.

    Регистры - информацию по регистрам смотреть в Интернете или у нас на форуме. Своими словами это операнды, которыми оперирует процессор, выполняя те или иные инструкции.

    Инструкции - или ассемблерные инструкции, также смотреть в Интернете или у нас на форуме. Дизассемблированные инструкции отражают какую-то операцию происходящую в игре. С помощью программ CE, MHS можно изменять инструкции изменяя поведение игры и её игровых объектов.

    Часто обращаемая инструкция - инструкция которая срабатывает очень часто (можно определить по хит-ам при срабатывании бряка).

    Определение адресов на инструкции - определение результирующих адресов с которыми происходит работа. Например, есть инструкция mov eax, [ecx*4 + 64]. В квадратных скобках может проскакивать множество адресов, которые можно определить средствами CE или OllyDbg.

    Классификация инструкций сработавших при брейкпоинте (термины писал сам)

    -Тип А

    Данная инструкция работает с некоторым единственным параметром только определённого игрового объекта.

    Например, здоровье от структуры находится по смещению +155. Инструкция А, работает только с этой структурой, только со смещением +155.

    -Тип B

    Эта инструкция работает с параметрами двух и более объектов, параметры которых находятся по одинаковым смещениям.

    Например, у нас шесть объектов - игроков, у которых по смещениям +155 находится здоровье. Инструкция типа B получает указатель на начало некоторой структуры объекта игрока, прибавляет смещение +155 и работает с параметром (читает параметр из адреса или пишет в адрес). Таким образом, инструкция типа B может отнимать здоровье у героя, а также отнимать здоровье у врагов.

    -Тип С

    Данный тип инструкций может работать с данными находящимися не по одному (как при типах А и В), а по разным смещениям относительно одной или более структур. Стоит не путать тип А с С, т.к. инструкция А работает с одним смещением, тоже самое касается и B.

    Отсюда мы получаем подтипы:

    C(А) - работает с разными смещениями одной структуры (объекта);

    C(B ) - работает с разными смещениями более одной структуры (объекта).

    Часть 1. Редактирование параметра по адресу

     

    Скрытый текст

    Чтобы приступить к делу надо начинать с малого, а именно полностью разобраться с Artmoney. В чём нужно хорошо разобраться новичку читая справку Артмани.

    1) Разобраться в типах данных:


    • [*:1ppxw1g7]Что такое 16-ричная система.
      [*:1ppxw1g7]Какие типы данных существуют, что обозначают.
      [*:1ppxw1g7]Какие типы данных следует выбирать при поиске, а не выбирать все подряд.

     

    2) Разобраться в правилах поиска адресов и указателя.

    3) Разобраться, что такое указатель на адрес.

    Разобравшись во всём этом на множестве игр вы можете на этом остановиться, но у вас часто будут проблемы из-за многоуровневых указателей. В Artmoney поиск указателя, не очень удобен так как в ней нет отладчика. Если вы хотите чтобы ваш "обман" работал на принципе "включить чит/выключить чит" даже с самыми сложными указателями, то переходим на инструменты по мощнее чем ArtmoneyPRO, т.е. переходим на CheatEngine, MHS и OllyDbg.

    Заметки.

    Если с Артмани всё понятно, то стоит слега объяснить какой приоритет пользования у программ CheatEngine, MHS и OllyDbg.

    CheatEngine является основным инструментом для внедрения чит-кода. У отладчика CheatEngine есть ряд неудобств которые компенсируются OllyDbg. MHS полезна в ряде случаев: различных приёмов поиска, встроенные калькулятором, конвертером знаковых и беззнаковых чисел и другими. Но MHS оставляет впечатление огромного функционального гиганта, по сравнению с малым CheatEngine в котором необходимые и достаточные функции более удобны к приминению.

    Каснёмся такой сложной темы как поиск указателя в Артмани. Многоуровневые указатели Артмани оформлять научилась, а вот искать может только одного уровня.

    [[Указатель]+смещение]=значение.

    Многоуровневый указатель может быть вида [[[[xrGame.dll+5f5b54]+94h]+4]+388h], но, к сожалению, Артмани не обладает функции поиска подобных указателей. Данный указатель может помочь найти автоматический поиск в Cheatengine, но с ним нужно уметь обращаться. Надеюсь, методом проб и шибок у вас получится - нужно задать предполагаемый уровень указателя и ширину структур для всех заданных уровней. Из примера выше потребовалось бы задать 4 уровня и размер структуры (388h) переведённую в десятичную систему. Надеюсь, что вы уже прочитали вдоль и поперёк справку Артмани и обманули множество игр. Остановимся более подробно на системах счисления и правилах поиска, а в части 2 лучше вникнем, что такое указатели.

    1.1 Система счисления, код и данные

     

    Скрытый текст

    Наверняка, вы знаете что помимо обычных цифр в 16-ричной (hex) системе присутствуют ещё и буквы A,B,C,D,E,F. Таким образом счёт идёт 0,1,2,3,4,5,6,7,9,A,B,C,D,E,F. Если число состоит из двух и более цифр 16-ричной системы, то дописывают букву «h». Например 24h, 14h… в этом случае понятно, что имеем дело с 16-ричной системой, а также иногда приписывают "0х" например 0x24. Переводить из одной системы в другую и производить расчёты можно в стандартном калькуляторе в инженерном виде удобнее это делать в строенным калькуляторе MHS. На этом с целыми числами закончим.

    Другое дело обстоит с вещественными числами, т.е. числами с запятой (точкой). Стандартный калькулятор Windows не умеет работать с вещественными 16-ричными числами. А именно не умеет переводить их в десятичную и обратно. Для этого вы можете использовать программу конвертор Converter или калькулятор MHS.

    converteral9.jpg

    Converter.rar

    Теперь рассмотрим представление кода и данных.

    Код

    В игре и данные и код оцифрованы в 16-ричной системе. Одни цифры это данные. Другие цифры это инструкции, которые выполняет процессор. Цифры кода можно понять с помощью дизассемблера, который является неотъемлемой частью отладчика. Дизассемблер есть в OllyDbg, CheatEngine, MHS.

    Данные

    Важную роль играет размер данных именуемый типом данных.

    Почти никогда вам не потребуется искать данные бита (встречаются в очень старых игрушках).

    1 бит (bit) это 0 или 1. Восемь последовательных бит составляют 1 байт. Поиск/отсев битов есть в CheatEngine.

    Чаще всего встречающиеся размеры данных.

    1 байт содержит значиния 00-FF или 00-255 в десятичной.

    2 байта (word) содержат значиния 00 00-FF FF

    4 байта (dword) содержит значиния 00 00 00 00-FF FF FF FF

    8 байт ddword - или "двойной дворд", так как "содержит 2 дворда".

    Существуют и знаковые даннные для целых чисел типа байта, ворда, дворда и ддворда - почти не встерчаются в играх. В десятичной системе их велечина будет определяться как "- число" до "число", где нулём будет половина от размера типа данных.

    Данные с точкой содержат не меньше 4-х байтов и 8-ми. Чаще всего это капризные данные, один байт которых может поменяться, а видимое число в игре может остаться прежним.

    Из своего опыта могу сказать, что в 32-х разрядных играх чаще всего будут попадаться значения типа 4 байта целое. Чуть реже 4 байта с точкой и ещё реже именно 1 байт остальные типы довольно редко. В 16-ти разрядных играх чаще попадаются данные 2-х байт и байта.

    У вас есть программа Converter. С её помощью вы можете выбрать оптимальный тип данных для целых чисел и для чисел с точкой. К примеру с этой программой и какой-то игрой вы можете разобраться раз и навсегда как подбирать тип данных для целого и для вещественного чисел. Я об этом писать много не буду. Приведу только 2 примера наглядно показывающие как меняются байты.

    В игре значение денег 456546.

    Допустим я могу увеличивать деньги или уменьшать в пределах одного байта.

    Значит я буду искать 1 байт.

    456546= 06 F7 62

    Увеличивать деньги нужно в пределах 1 байта, чтобы число было не больше чем 06 F7 FF, т.е.

    456703 = 06 F7 FF

    А уменьшать деньги нужно чтобы число было не меньше чем 06 F7 00

    456448=06 F7 00

    Таким образом промежуток денег видимый в игре при поиске и отсеивании должен быть от 456448 до 456703. Если я найду адрес этого последнего байта, то я смогу узнать адрес денег уменьшив найденный адрес на 3 и присвоив ему 4 байта (или адрес можно установить опытным путём посмотрев карту памяти или поставив брекпоинт в отладчике на этот адрес - об этом позже).

    Допустим возникнет вопрос почему нельзя искать сразу 456546 тип 4 байта. Да можно и нужно, я просто показал пример как меняются байты и расширил ваши знания по типам данных.

    Теперь по сложнее напримере для чисел с точкой.

    Полоска жизней составляет промежуток от 0 до 100.00 (т.е. 00 - 42C80000)

    100,0 - 42 C8 0000

    99,0 - 42 C6 0000

    90,0 - 42 B4 0000

    80,0 - 42 A0 0000

    70,0 - 42 8C 0000

    60,0 - 42 70 0000

    Можно видеть что меняется каждый второй байт. А теперь обратите внимание как будет дело с десятыми долями, какие байты меняются а какие не меняются.

    100,0 - 42 C8 00 00 - Значение в игре 100

    99.9 - 42 C7 CC CD - Значение в игре 99

    99.8 - 42 C7 99 9A - Значение в игре 99

    99.7 - 42 C7 66 66 - Значение в игре 99

    99,6 - 42 C7 33 33 - Значение в игре 99

    99.5 - 42 C7 00 00 - Значение в игре 99

    99.4 - 42 C6 CC CD - Значение в игре 99

    …..

    99,0 - 42 C6 00 00 - Значение в игре 99

    98.9 - 42 C5 CC CD - Значение в игре 98

    Обратите внимание, что отображаемое значение округляется. При поиске нужно искать например не "95.0" тип 4 байта с точкой, а промежуток от 95,0 до 96.

    Нетрудно догодаться что 4 байта с точкой можно найти по одному байту, если отображаемое значение в игре будет увеличиваться уменьшаться как минимум через 2 единицы от 100,0 до 32,0

    99 - 42C60000

    97 - 42C20000

    95 - 42BE0000

    ...

    32 - 42000000

    Все это понять поможет практика, если хотябы раз в жизни вы будете взламывать кодированные значения. О примерах кодированных значений можно написать много. Я думаю это не так интересно поэтому двигаемся дальше.

    1.2 Особенности поиска адресов

     

    Скрытый текст

    Пример. В игре "50", а на самом деле "50.44". Значит вы ищите от 50 до 51 число 4 байта с точкой.

    Пример. В игре "50", а на самом деле на единицу больше "51" или меньше "49". Значит вы выбираете интервал от 49 до 51.

    Пример. В игре "50", а на самом деле нужно искать "0,5000000012...". Из-за того что в игре есть такая операция 50/100=0,5000000012...,то рабочий адрес будет со значением "0,5000000012". Такое значение эффективнее искать в MHS,там вы выбираете "float" - вещественное число. Поиск интервалом, уменьшилось/увеличилось/равно 1(при полном значении).

    Пример. В игре "50", а на самом деле кодированное. В этом случае описываю способы далее.

    Прямая пропорциональность.


    • [*:1ppxw1g7]1. Способ. Изменения на определённую величину.
      Пример. В игре "50", стало "80". А на самом деле было "100", а стало "130"
      Ищу неизвестное. Как стало "80" отсеиваю "увеличилось на 30". Нахожу адрес со значением "130"
      Правило такое: "увеличилось на" или "уменьшилось на".
      [*:1ppxw1g7]2.Способ. Изменения уменьшилось/увеличилось
      Пример. В игре "50", стало "80". А на самом деле было "черт знает что =))) но вы предполагаете что при увелечении кодированное увеличивается, а при уменьшении уменьшается.
      Правило такое: "увеличилось" при увелечении в игре или "уменьшилось" при уменьшении.

     

    Обратная пропорциональность.

     


    • [*:1ppxw1g7]1. Способ. изменения на определённую величину.
      Проще объяснить так.
      Если число в игре увеличивается, то ищем уменьшающиеся.
      Если число в игре уменьшается, то ищем увеличивающиеся.
      Пример. Число в игре 50, ищу неизвестное. Стало 80 . Ищу уменьшилось на 30. Но этот пример образно.
      [*:1ppxw1g7]2.Способ. Изменения уменьшилось/увеличилось
      Ну тут, почти также. Только без изменения на определённую величину.
      Если число в игре увеличивается, то ищем уменьшающиеся.
      Если число в игре уменьшается, то ищем увеличивающиеся.

     

    Первые в отличии от вторых способов в обратной и прямой пропорциональности позволят эффективнее, т.е. более быстрее найти адрес.

    Способ. "Изменилось не изменилось."

    Этот способ самый мучительный способ отсеивания. Потому что сопровождается долгими поисками. Применяете его только в последнюю очередь с типами 4 или 2 байта целое. Один байт вряд ли будет. 4 байта с точкой не выбирайте, от этого толку ноль.

    Правило: ищите кодированное. Если значение меняется, тогда отсеиваете "изменилось". Не меняется, тогда отсеиваете "не изменилось"

    Приколы с несколькими адресами.

    Встречал в некоторых играх, например, в CNC.

    Прикол в CNC тибериума с деньгами.

    Там было два адреса денег(или чего-то там минералов что ли)

    1 Адрес =..... (до 3000, вроде)

    2.Адрес= ... (любое число в пределах 4 байт)

    Пришлось искать 1 Адрес когда минералов было до 3000. Потом когда я увидел несуразность в изменении денег при заморозке Адреса 1, а вы можете её себе представить?! Я замораживаю адрес, а минералы почему-то до какого-то числа могут уменьшаться. И я понял адрес "полурабочий". И когда я исследовал код поставив бряк на 1 Адрес в CheatEngine, только тогда я понял, что есть второй адрес. Вот так. А так бы без CheatEngine никогда бы не догадался.

    Приколы с очень длинными данными.

    В весьма редких случаях бывает так, что искать нужно 8 байт целое или с точкой. Надо быть к этому готовым smile.gif

    Прикол, когда адрес нашёлся, но не работает.

    Вам нужно искать другой адрес. Ниже привидён пример.

    Пример. В игре "50", а на самом деле нужно искать "0,5000000012...". Из-за того что в игре есть такая операция 50/100=0,5000000012...,то рабочий адрес будет со значением "0,5000000012". Такое значение эффективнее искать в MHS,там вы выбираете "float" - вещественное число. Поиск интервалом, уменьшилось/увеличилось/равно 1(при полном значении).

    Т.е. вы искали "50" и нашли не правильный адрес.

    Бывают и такие случаи, что вы перепробовали все способы, а адрес по-прежнему не рабочий. В этом случае вступает в дело "реверс инжинеринг". Ставим бряки на адреса связанные со значением в игре и исследуем код в IDA,отладчике OllyDbg, отладчике CE... разбираясь в чём проблема.

    Хочу отметить пару важных моментов.

    smile.gif

    Если нельзя найти указатель?

    Поиск указателя не всегда простая задача всё зависит от вашего опыта. С помощью функций CE, таких как: поиск в памяти, определение прервавшихся инструкций на адресе и расструктуризации можно найти указатель повышенной сложности. Чем больше уровней тем труднее поиск. Особенно если адрес включён в свойства объекта из многомерного динамического массива объектов. Прежде всего, это касается таких игр как стратегии... Более подробно о поиске многоуровневых указателей читайте в моих статьях.

    1.3 Архитектура Памяти Windows приложений(игр)

     

    Скрытый текст

    Когда вы редактируете какой-то адрес, то вы, наверно, не задумываетесь, что у этого адреса есть права доступа. Что у адресного пространства есть свои рамки и т.п. Это мы разберём в данной теме.

    Рассмотрим чем может быть полезна карта памяти процесса игры.

    Виртуальное адресное пространство для 32-рязрядной системы любого приложения занимает от 0x00000000 до 0xFFFFFFFF байт. Или 4 гигабайта с копейками. Для 64-разрядных процессоров от 0x00000000 00000000 до 0xFFFFFFFF FFFFFFFF. Рассматриваем с вами 32-разрядные игры и 32-разрядные операционки. Как обстоят дела у 64-рязрядных пока не знаю. Скорее где-то также.

    Если мы посмотрим с вами на карту памяти процесса (напрмер Artmoney или CE), то увидим колонки с атрибутами защиты памяти.

    Например:

    Адрес, Адрес региона, Размер региона, Состояние региона, Защита региона, Защита, Тип.

    Адрес(Address) – адрес

    Адрес региона – начальный адрес региона в который входят блоки до размера региона.

    Размер региона/размер блока – показан размер региона если это начало региона и блока если это блок.

    Состояние региона (State) - состояние региона

    Защита региона(Allocation Protect) - Защита региона

    Защита блока (Protect) - Защита блока

    1. Пункт

    Обращаем внимание что блок кратен 1000h байтам, а регион 10000h байтам. Это связано с выравниванием данных – гранулярностью. А у 64-разрядных систем блок кратен 2000h байтам, а про регионы сами посмотрите...

    2. Пункт

    Состояние региона/блока (State) бывает:

    COMMIT – память спроецирована на файл постраничный или файл образа

    RESERVE – зарезервирована (но не доступна)

    FREE –свободная (высбождена)

    3. Пукт Тип региона/блока.

    Free

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

    Private

    Этот диапазон виртуальных адресов сопоставлен со страничным файлом.

    Image

    Этот диапазон виртуальных адресов изначально был сопоставлен с образом ЕХЕ- или DLL-файла, проецируемого в память, но теперь, возможно, уже нет Например, при записи в глобальную переменную из образа модуля механизм поддержки «копирования при записи» выделяет соответствующую страницу памяти из страничного файла, а не исходною образа файла

    Mapped

    Этот диапазон виртуальных адресов изначально был сопоставлен с файлом данных, проецируемым в память, но теперь, возможно, уже нет. Например, файл данных мог быть спроецирован с использованием механизма поддержки «копирования при записи" Любые операции записи в этот файл приведут к тому, что соответствующие страницы памяти будут выделены из страничного файла, а не из исходного файла данных.

    4.Пункт

    Защита региона обычно совпадает с защитой блоков, отличия могут быть, если у блока стековый параметр Guard. И когда у региона параметр перезаписи «Write Copy» (об этом ниже)

    Атрибут защиты (регионов и в частности блоков)

    PAGE_NOACCESS

    Попытки чтения, записи или исполнения содержимого памяти на этой странице вызывают нарушение доступа

    PAGE_READONLY

    Попытки записи или исполнения содержимого памяти на этой странице вызывают нарушение доступа

    PAGE_READWRITE

    Попытки исполнения содержимого памяти на этой странице вызывают нарушение доступа

    PAGE_EXECUTE

    Попытки чтения или записи на этой странице вызывают нарушение доступа

    PAGE_EXECUT_READ

    Попытки записи на этой сфанице вызывают нарушение доступа

    PAGE_EXECUTE_READWRITE

    На этой странице возможны любые операции

    PAGE_WRITECOPY

    Попытки исполнения содержимого памяти на этой странице выбывают нарушение доступа, попытка записи приводит к тому, что процессу предоставляется «личная» копия данной страницы

    PAGE_EXECUTE_WRITECOPY

    На этой странице возможны любые операции, попытка записи приводит к тому, что процессу предоставляется «личная» копия данной страницы

    Общие выводы

    1. Вывод

    Статичные адреса, которые обычно не меняют своего местоположения это адреса входящие в блоки и регионы памяти IMAGE с параметрами защиты:

    PAGE_EXECUTE

    PAGE_ EXECUTE_READ

    PAGE_EXECUTE_READWRITE

    PAGE_WRITECOPY

    PAGE_EXECUTE_WRITECOPY

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

    Правда у статических адресов возможны и другие состояния, как Commit с защитой Read и типом mapped. Если адрес с типом региона mapped и защитой блока и региона read+write, то на этот адрес вам явно нужно искать указатель.

    2. Вывод.

    Блок памяти не может быть меньше 1000h байт, а регион не может быть меньше 10000h и всегда соблюдается кратность. Если вы нашли адрес ресурса в игре, то где-то в рядом в этом блоке или в регионе памяти вероятно нахождения другого ресурса. Поэтому нет необходимости искать всю память, достаточно задать параметры поиска в заданном промежутке адресов. Особенно это касается при поиске неизвестного значения.

    3. Вывод.

    Если тип адреса Image, то убедитесь, что это не подгружаемый модуль dll или файл с другим расширением. Если это так, то вам нужно вместо обычного адреса задавать смещение относительно начала модуля. Пример [[core.dll+1000]+20h]. Если у вас обычный exe файл игры, то всё в порядке можно заголовок игры не писать, например, не писать [game.exe+1000], а просто [401000]

    P.S. Вот и вся польза от карты памяти процесса, если кто не знал.

    Часть 2. Встраивание чит-кода

     

    Скрытый текст

    Встраивание чит-кода сложная тема. Перед тем как читать статьи в разделе для продвинутых нужна подготовка. Здесь как раз она и будет.

    Мы рассмотрим как работает машинный код с указателями в ассемблерном представлении и вы при этом сможете понять принцип работы ассемблера.

    Ассемблер это низкоуровневый язык программирования более понятный человеку чем машинные коды.

    2.1 Поиск динамических «бегающих» данных и основы встраивания чит-кода

     

    Скрытый текст

    Указатели позволяют быстро перемещаться по схожим структурам информации.

    Грубое представление указателей

     


    2.
    3.Структура 1
    4.Имя игрока: Игрок 1
    5.Жизнь игрока: 65
    6.Патроны пистолета игрока : 50
    7.
    8.Структура 2
    9.Имя игрока: Игрок 2
    10.Жизнь игрока: 80
    11.Патроны пистолета игрока : 10
    12.
    13. Структура 3
    
    
    
    
    
    
    
    1. «3»(по адресу 1 находится указатель на начало структуры характеристик некоторого игрока)

     

    Примичание: как видно все числа я привёл в десятичной системе, а не в 16-ричной и не указывал размер данных. Так, на мой взгляд, новичку проще понять,а по ходу чтения статьи и на практике работы с отладчиком можно будет соориентироваться без особого труда...

    Как видно каждая структура содержит свой адрес в адресном пространстве и находится на одинаковом раcстоянни от какой-то базовой точки. В нашем случе базовая точка - это третий адрес. А на третий адрес, указывает первый адрес (!)

    Вот что произойдёт когда данные «убегут»

    1. «7»

    2.

    3.

    4.

    5.

    6.

    7. Структура 1

    8. Имя игрока: Игрок 1

    9. Жизнь игрока: 65

    10.Патроны пистолета игрока : 50

    11.

    12.Структура 2

    13.Имя игрока: Игрок 2

    14.Жизнь игрока: 80

    15.Патроны пистолета игрока : 10

    16.

    17. Структура 3

    Ниже примеры c комментариями к выше описанному примеру.

     

    mov eax,edi //eax=edi=7 mov ebx,[eax+2] // ebx =[7+2]=[9]=65 жизней Игрока 1
    
    
    
    
    
    
    
    mov edi, [1] // записать в edi значение адреса 1, а именно  значение «7»

     

    Теперь попробуйте самостоятельно.

     

    mov ebx, [2] mov esi,[eax+ebx+3] Проверьте себя. Чему равен esi для адресного пространства ниже? [Указатель] 1. «7» [Указатель] 2. «5» 3. 4. 5. 6. 7. Структура 1 8. Имя игрока: Игрок 1 9. Жизнь игрока: 65 10.Патроны пистолета игрока : 50 11. 12.Структура 2 13.Имя игрока: Игрок 2 14.Жизнь игрока: 80 15.Патроны пистолета игрока : 10 16. 17. Структура 3 …
    
    
    
    
    
    
    
    mov eax, [1]

     

    Ответ:

    ESI будет равен 10 патронам пистолета второго игрока.

    Если вы научились это считать, то можно сказать, что вы поняли основной принцип работы ассемблера.

    Обращение к адресам выглядит так (примеры)

    [ ] - обозначение обращение к адресу

    [[1]+[2]+2] - адрес жизни

    [[1]+[2]+3] - адрес патронов

    Как видно с помощью укзателей можно легко перемещаться по структурам, считывать и записывать данные в эти структуры.

    Понятия чтения и записи.

    ЧТЕНИЕ

     

    mov esi,[eax+ebx+3]- чтение данных из адреса [eax+ebx+3] в esi
    
    
    
    
    
    
    
    mov eax, [1] - чтение данных из адреса 1 в eax

     

    ЗАПИСЬ

     

    mov [eax+ebx+3], esi - запись данных из esi в адрес [eax+ebx+3]
    
    
    
    
    
    
    
    mov [1], eax  - запись данных  из eax в адрес 1

     

    Про брейкпоинты.

    Брейкпоинт (Break Point) - точка остановки при работе с адресом.

    Брекпоинт может сработать

    при чтении данных,

    при записи данных,

    при прохождении (ставится в отладчике на инструкции, обычно, по кнопке F5, срабатывает когда инструкция должна выполнится)

    Разберём примеры.

    Дан адрес

     

     
    
    
    
    
    
    
    
    9. Жизнь игрока: 65

    Если вы поставите брейкпоинт (далее bp) на адрес 9 на чтение. То будет срабатывать прерывание на всех инструкциях, которые пытаются прочитать значение из адреса 9

    Например это

     

     
    
    
    
    
    
    
    
    mov eax, [9]

     

    Если вы поставите bp на адрес 9 на запись.

    То будет срабатывать прерывание на всех инструкциях, которые пытаются записать в адрес 9

    Например это

     

     
    
    
    
    
    
    
    
    mov [9],eax

     

    Если вы поставите bp на задрес 9 на доступ, то это тоже самое что поставить на чтение и запись одновременно, то будут срабатывать и чтение и запись. Соответственно это

    Ставя брейкпоинты на адресах и совершая поведения объектов можно отлавливать инструкции записи или чтения, что нам пригодиться при обмане игр.

    Ещё один пример работы с брейкпоинтами.

    Мы нашли адрес здоровья с помощью CheatEngine (CE). Это «адрес 9», значение 65, тип 1 байт.

    В CE мы поставим bp на доступ на этот адрес.

    Вошли в игру…. игра тут же прочитала значение жизни. Вернулись в CheatEngine и увидили что выскочила инструкция.

    mov esi,[eax+ebx+2] ///Вам уже не сложно определить, что это инструкция чтения.

    А также вам будут показаны значения РЕГИСТРОВ.

    eax=7

    ebx=0

    esi=65

    Далее вы заходите в отладчик CheatEngine по отловленной инструкции и обращаете внимание на стоящие рядом инструкции

     

    mov eax, [1] mov ebx, [2] mov esi,[eax+ebx+2] //зная значения регистров вы мысленно подставляете esi=[7+0+2]=[9]=65 …

     

    Проанализировав ход выполнения кода трёх инструкций выше. Вы должны хотя бы частично мысленно представить картину той которая ниже (которую вы уже видели, привожу её снова)

     

    2. «0» 3. 4. 5. 6. 7. Структура 1 8. Имя игрока: Игрок 1 9. Жизнь игрока: 65 10.Патроны пистолета игрока : 50 11. 12.Структура 2 13.Имя игрока: Игрок 2 14.Жизнь игрока: 80 15.Патроны пистолета игрока : 10 16. 17. Структура 3 …
    
    
    
    
    
    
    
    1. «7»

     

    Теперь вы знаете как работают брейкпоинты и как работает инструкция mov. Она означает перемещении данных при чём определённого размера. Об инструкциях я выложу справочный материал, советую его не зубрить, а обращаться к нему при надобности.

    Пойдём дальше...

    Хотим сделать именно игрока1 бессмертным.

    Поставим себе задачу, чтобы при выполнении кода превый игрок был бессмертным. Это и есть встраивание чит-кода.

    Можно догадаться , что когда ebx = 0, то имеем дело только с первым игроком. Поэтому нужно поставить фильтр «свой/чужой» на запись постоянного числа в адрес жизней.

     

    mov eax, [1] mov ebx, [2] mov esi,[eax+ebx+2] //зная значения регистров вы мысленно подставляете esi=[7+0+2]=[9]=65 …

     

    Приведён кусочек кода из скрипта CheatEngine:

     

    mov ebx, [2] cmp ebx, 0 // если это первый игрок (cmp это сравнение) jne x1 //прыжок если неравно mov [eax+ebx+2],#100 //то записать 100 жизней в [eax+ebx+2] x1: mov esi,[eax+ebx+2] // иначе выполнять только оригинальный код
    
    
    
    
    
    
    
    mov eax, [1]

     

    Так игроку1 при чтении (а чтение, обычно,повторяется очень часто) записывается 100 очков здоровья и в игре будет постоянно видно число 100.

    Ну это не полная картина иньекции. Ведь нам нужно вставить это условие вместо оригинальной инструкции

    mov esi,[eax+ebx+2]

    А места-то нехватает, потому что mov esi,[eax+ebx+2] занимает определённое количество байт и ниже этой инструкции идёт другой код, который нет возможности как-то "подвинуть" ниже. Но есть другой способ. Мы должны сделать прыжок в этом месте в участок памяти. В нём вписать чит-код соблюдая логику кода с прыжком обратно. К сожалению, это плохой пример для наглядности. Поэтому нужно разобрать иньекцию на примере какой-нибудь игры. В этом случае будет полезно почитать какую-нибудь статью про внерение чит-кода. Если что-то там не понятно, то вернётесь к этой статье в другой раз. Просто надо посмотреть и сравнить картины того что там и картины которой я тут написал.

    Вернёмся к скрипту.

    Если вставлять чит-код в инструкцию записи, то будет прописываться "100" только при уроне.

    Если вы встаиваете в инструкцию чтения, которая работает постоянно, то изменения в игре сразу видно. Советвую вам встривать и в обе инструкции, потому что инструкция урона может убить игрока раньше чем сработает постоянная инструкция чтения.

    2.2 Инструкции Ассемблера

     

    Скрытый текст

    В геймхакинге не в простом, а в продвинутом вам очень нужно знать как работают инструкции ассемблера для:


    • [*:1ppxw1g7]того чтобы знать, как работает игра, на участке бряка;
      [*:1ppxw1g7]того чтобы знать, как сделать инъекцию кода и знать какую инъекцию;

     

    Вы уже должны представлять что инструкции ассемблера оперируют данными, которые имеют размер, т.е. тип. Управления данными происходит с помощью регистров. В процессорах эти регистры разные и описываются в технической документации. Нам же с вами достаточно знать регистры 0х86 процессоров.

    Сначала вы можете пробежаться по справочникам:

    CPU

    FPU

    SIMD (MMX, SSE, SSE2, SSE3, SSSE3).

    А теперь после просмотра справочников рассмотрим основные инструкции.

    Я старался расположить материал от часто встречающихся "вещей" до редких. Вам будут попадаться игры с инструкциями на бряках чаще CPU, затем реже FPU и совсем редко SIMD.

    Инструкции можно разделить на три блока


    • [*:1ppxw1g7]CPU (работа над целыми числами),
      [*:1ppxw1g7]FPU (работа над вещественными),
      [*:1ppxw1g7]SIMD инструкции (работа с массивами чисел).

     

    Знакомьтесь CPU(окно регистров)

    60573846yq1.png

    CPU(основные команды):

    MOV

    mov рег, рег -записать в левый регистр, значение правого регистра

    mov рег,[] -записать в регистр значение памяти

    mov [],рег -записать в память значение регистра

    Важно. Не забываете указывать размер данных. Байт, 2 байта, 4 байта. Это касается всех инструкций работающих со значением адреса в памяти.

    Пример.

    mov eax,byte [410000] - занести в eax значение байта

    mov eax,word [410000] - занести 2 байта

    mov eax,dword [410000] - занести 4 байта

    NOP

    Эта команда самая знакомая команда. Она стерает код. Это даже и не команда вовсе.

    SUB

    sub рег,рег -вычесть из левого правый регистр и сохранить в левом

    sub рег,размер [] - вычесть из регистра значение адреса памяти и сохранить регистре

    sub размер [], рег - вычесть из значения адреса в памяти значение регистра и сохранить в памяти

    ADD

    Тоже самое что и SUB только сложение.

    CMP

    cmp рег,рег - сравнить регистры

    cmp рег, размер [] -сравнить значение регистра и значение памяти

    cmp размер [], рег -сравнить значение регистра и значение памяти

    *cmp, обычно, ставят сразу перед прыжком.

    сmp будет выскакивать, только если вы ставите бряк на чтение, ведь, здесь только сравнение ))

    DEC

    dec рег - уменьшить значение регистра на единицу

    dec размер [] - вычесть значение регистра из значения в памяти и сохранить в регистре

    sub размер [], рег - вычесть значение значения в памяти из регистра и сохранить в регистре

    INC

    Тоже самое что и DEC только сложение.

    LEA

    Вы будите встречать редко, это работа с регистрами.

    LEA EAX,[EBX+ECX*4+100]

    eax=ebx+ecx*4+100

    Эта инструкция нужна лишь для того чтобы вычислить смещение .Просто знайте о ней.

    PUSH

    push число - добавить в стек (времення память) число

    push рег - добавить в стек значение регистра

    push размер [] - добавить в значение памяти определённого размера

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

    POP

    Тоже самое что и PUSH только вытаскивание или восстановление. Вытаскивать нужно в обратном порядке.

    Положили 1 2 3 4 5. Вытаскиваем 5 4 3 2 1. Будьте внимательны.

    push eax

    push ebx

    add eax,ebx

    sub ebx,eax

    pop ebx

    pop eax

    PUSHAD Сохранение в стек регистров общего назначения edi, esi, ebp, esp, ebx, edx, ecx, eax.

    POPAD Восстановление регистров общего назначения edi, esi, ebp, esp, ebx, edx, ecx, eax

    PUSHF Размещение в вершине стека содержимого регистра флагов flags

    POPF Восстановление флагов

    XOR

    Исключающие или

    xor al, 01; изменить значение бита 0 регистра al на обратное

    IMUL

    Целочисленное умножение

    mov bx,186

    imul eax,bx,8

    DIV

    Без знаковое деление

    • если делитель размером в байт, то делимое должно быть расположено в регистре ax. После операции частное помещается в al, а остаток — в ah;

    • если делитель размером в слово, то делимое должно быть расположено в паре регистров dx:ax, причем младшая часть делимого находится в ax. После операции частное помещается в ax, а остаток — в dx;

    • если делитель размером в двойное слово, то делимое должно быть расположено в паре регистров edx:eax, причем младшая часть делимого находится в eax. После операции частное помещается в eax, а остаток — в edx.

    mov ax,10234

    mov bl,154

    div bl ;ah=остаток, al=частное

    Знакомьтесь FPU(окно регистров)

    72393145aj3.png

    Основные FPU(команды):

    Принцип такой есть 8 регистров ST. Эти регистры как барабан, который можно вращать некоторыми инстукциями. Также можно обратиться к каждомму регистру. Если регистр не указаывается, значит имеете дело с первым ST0 напримере комманды как fld [esi] (тоже самое что fld STO, [esi]).

    Существуют инструкции довольно часто встречающиеся:

    fld [] - загрузит из памяти в ST0 //fld St1,[] - загрузит в ST1

    stp [] - скопирует из STO в память

    fstp [] - выгрузит из STO в память

    ну и так далее...

    Знакомьтесь SIMD(окно регистров)

    83509477th5.png

    Эти регистры встречаются довольно редко и в основном в играх стратегиях, т.е. в играх в которых участвует большое количество объектов (юнитов, зданий, и т.п.)

    Про эти регистры вы можете посмотреть здесь, если будет нужно.

    • Понравилось 1
    • Плюс 1
  5. Постоянная ссылка на версию CE RUS

    Версия Cheat Engine 5.5 (v Rus_1.1.1. Beta)

    1. Изменены шрифты в окнах регистров.

    2. Добавлено мемо регистров в окно определения адресов.

    3. Возможно автоматическое внедрение чит-кода после запуска игры указав директиву {+A} в имени описания чит-кода при генерации трейнера.

    _______

    Версия Cheat Engine 5.5 (v Rus_1.2.1. Beta)

    Итак пока я смог сделать только такие обновления.

    1. Проверка совпадения проверочных байт

    Вы можете проверить ваши байты в конкретной игре или патче, эксперементировать и учиться определять какие байты нужно ставить.

    intro2k.gif

    2. Запомним адрес каждого уровня указателя

    Эта функция нужна для быстрого определения адресов начал структур.

    Умножение, логические операции и другие операции (такие как в MHS) не поддерживаются. Любое число по умолчанию имеет hex-вид

    introy.gif

    Для чего это нужно?

    Допустим мы с вами нашли две большие цепочки указателей и хотим быстро определить пересекаются ли их структуры. Лежат ли какие нибудь структуры чуть ниже начал других структур. Если лежат, то есть связь.

    _______

  6. Инструменты для обмана игр

    Основные инструменты:

    Artmoney (для новичков)

    CheatEngine (для опытных)

    Cheat Engine 5.6 RUS v1.0(для опытных, установить поверх английской CE 5.6) CheatEngine Rus 5.5 (для опытных)

    MHS (для опытных)

    Отладчики, дизассемблеры:

    IDA+(плагин hex-array) – ищете сами в Интернете.

    OllyDbgShadow+примочки (лежит в архиве ниже)

    Различные «мониторы»:

    ProcessExplorer (лежит в архиве ниже) – процесс окна игры, команда запуска и т.п.

    Procmon (лежит в архиве ниже) – слежение за записью и чтением на хард (помогает выйти на файлы сохранения или понять в чём ошибка игры)

    Работа с окном игры:

    D3DWindower (лежит в архиве ниже) – установка оконного режима

    InqSoftWindowScanner (лежит в архиве ниже) – информация об окне, перемещение окна…

    Ссылка на архив (редактируется)

    Если вам нужен софт по трейнерам, то вам нужно перейти в соответствующий раздел.

    Софт для обмана флеш-игр: (редактируется)

    Софт для обмана эмуляторных игр: (редактируется)

  7. Здесь будет рассматриватся и может обсуждаться/дополняться моё руководство по Autoassembler Engine.

    Нужные ссылки на CE:

    1. Сайт английской версии (последняя версия CE 6.0 на 20 апреля 2011 )

    2. Русская CE 5.6 (устанавливается поверх английской CE 5.6 находящаяся на официальном сайте; если хотите генерировать трейнеры, то только лучше на этой версии пока не вышла версия CE6.1)

    3. Русская CE 5.5

    Статья в которой обсуждается работа с автоассемблером (весь пункт 3):

    DevilMyCry.rar.

    Эту статью лучше прочитать после чтения информации ниже.

    Дополнительная информация:

    Если делаете читы для себя, то Вам будет достаточно автоассемблерных скриптов CE. Если нужны трейнеры, то их генерировать может CE 5.6 и будущая CE 6.1. CE 6.0 генерировать трейнеры не умеет, но зато поддерживает LUA - скрипты, которые могут создавать трейнеры скриптами только при наличии CE6.0. Чтобы делать трейнеры на LUA скриптах нужно иметь опыт программирования. Для новичков проще пользоваться автоассемблерными скриптами.

    На официальном сайте ожидается конечный реализ CE 6.1 с поддержкой русского языка.

    Зайдите в подфорум реализы Cheat Engine чтобы попробовать возможности CE 6.1 Альфа 8.

    -----------------------------------------

    1. Обзор автоассемблера

    Посмотрим с чем придётся иметь дело...

    post-3-1303268956,32_thumb.png

    Рис.1 Окно автоассемблера после генерации шаблона

    Если Вы решите исправить код игры, то вам придётся писать код в этом окне. Также Вам вручную придётся убирать комментарии если они вам мешают. К сожалению разработчик Дарк Байт не позаботился о том как убрать эти комментарии одним махом.

    Сейчас я напишу как сгенерировать такой шаблон. А затем как и что в нём редактировать.

    1) Подключитесь к процессу игры.

    Надеюсь Вы знаете как это делать. В версии CE 6.0 это можно сделать через значок "Компьютер"

    2) Найдите адрес нужного параметра1 в игре

    3) На адресе вызовете меню правым кликом мыши и поставьте брейкпоинт "на запись" или "на доступ". Надеюсь вы знаете как это сделать, если немного знаете английский.

    4) Войдите в игру и измените значение параметра1

    5) Если вы сделали всё правильно, то в окне брейкпоинтов появится инструкция или их будет несколько.

    6) Перейдите по инструкции в дизассемблер. Надеюсь вы знаете как это сделать, если немного знаете английский.

    Ну а теперь смотрите рисунок. Он сделан на основе статьи, которую я выложил выше:

    post-3-1303270075,17_thumb.png

    Рис.2 Создание скрипта инъекции кода

    Итак вы прошли весь путь создания скрипта. Вы не только узнали как генерировать шаблон, но и узнали куда вписывать новый код.

    С помощью скриптов вы можете:

    1) встроить чит-код удобно вклинив новое условие в код игры;

    2) быстро проверить работоспособность чит-кода;

    3) "получить" байты чит-кода для создания трейнера.

    Скрипт открывает перед вами МОЩНЫЕ возможности. Иногда нужно извернуться, чтобы написать скрипт. В этом есть кайф - изменить код игры под себя, обмануть игру.

    Это было знакомство, а теперь переходим к деталям.

    2 Скриптовые инструкций

    Скрипты включают в себя инструкции ассемблера (будут разобраны позже), а также ряд специальных скриптовых команд.

    Существуют две основные директивы


    [DISABLE] // восстановить оригинальный код
    [ENABLE] // включить новое условие

    Листинг 1

    Под каждой директивой располагается код активации и деактивации чита.

    Пример


    0081e159:
    db 90 90

    [DISABLE]
    0081e159:
    dec [ecx] // вычесть единицу из адреса ecx (ecx считайте «переменной»)
    [ENABLE]

    Листинг 2

    Этот приём позволяет очень просто внедрить чит-код. Вычитание никогда не произойдёт. Подробнее будет ниже.

    Бывают такие случае что в ecx, могут проскакивать разные адреса и поэтому требуется сделать сложное внедрение. Для того чтобы это сделать нужно, вклинить условие в место 0081e159: db 90 90 изменив и не нарушив логику кода. Сделать это можно вписав прыжок в адрес 0081e159, который затрёт часть других инструкции (располагающихся ниже) ноп-ами. Об этом внедрении будет позже. А сейчас вернёмся к простому затиранию инструкций нопами.

    На этапе внедрения чит-кода вы можете увидеть, что каждая ассемблерная инструкция занимает определённое количество байт кода. Будьте внимательны и соблюдайте размер и логику, чтобы не напортачить чего либо, а то будет вылет из игры. Наверно, вы сталкивались – запускаешь трейнер чей-то и тут ВЫЛЕТ. Вот чтобы этого не было надо быть внимательным и знать ассемблерные инструкции.

    Возьмём за пример.


    Code :0081e159 - ff 09 - dec [ecx] //(это можно посмотреть в окнах бряков или окне дизассемблера)

    Листинг 3

    Как видно тут два байта занимает инструкция dec [ecx]. Думаю вы знаете что она означает вычитание единицы из адреса в ecx. Допустим можно стереть эту инструкцию, чтобы, например, патроны не вычитались.

    Чтобы инструкцию «потереть» нужно забить её «ноп»-ами. И сделать это можно либо так


    0081e159:
    nop
    nop

    [DISABLE]
    0081e159:
    dec [ecx]
    [ENABLE]

    Листинг 4

    Либо так


    0081e159:
    db 90 90

    [DISABLE]
    0081e159:
    dec [ecx]
    [ENABLE]

    Листинг 5

    Либо так


    0081e159:
    db 90 90

    [DISABLE]
    0081e159:
    db ff 09 // тоже самое что dec [ecx]
    [ENABLE]

    Листинг 6

    db означает данные байта (data byte). Таким образом в данном случае патроны не будут изменяться.

    Но что делать, если я хочу чтобы патронов было жёстко 100 штук. Для этого нужно вписать


    Mov [адрес или регистр], патроны. 

    Листинг 7

    Я сейчас точно не помню, но эта инструкция занимает, вроде, пять байт. А у нас доступно только два свободных байта (см. листинг 3) и как же быть?! Скрипт ниже, естественно, работать не будет


    0081e159:
    Mov [ecx],#100 // крах игры
    //затираются нижестоящие инструкции с нарушением логики кода

    [DISABLE]
    0081e159:
    dec [ecx]
    [ENABLE]

    Листинг 8

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

    Смотрим нижестоящие инструкции, например, одна из них будет такой.

    Code :0081e159 - ff 09 - dec [ecx]

    Code :0081e15b - xx xx xx xx xx– mov eax,[ecx]

    Листинг 9

    (код байтов инструкции mov я точно не помню, ссори, смотреть лень)

    Прыжок на свободное место в котором мы укажем новое условие занимает пять байт это "eb xx xx xx xx" . Это значит, что прыжок затрёт пять байт, начиная с адреса 0081e159 и оставит два байта «ошмётка» последующей инструкции (ий) которые выделены красным. Ошмётки мы затираем ноп-ми (иначе будет вылет) и восстанавливаем инструкции в выделенной памяти соблюдая логику кода.

    Совет.

    Вам нужно обращать внимание, что когда вы внедряете чит-код, то вы затераете пять байт по стандарту прыжком

    Jmp адрес (занимает пять байт)

    или в редких случаях

    call адрес (занимает пять байт)

    Таким образом, скрипт примет вид ниже. Появляются новые скриптовые команды.


    Alloc(newmem,2024) //выделение памяти рамзмером 2024 байт, которые округляться до 4 кб
    Label(x1) //метка адреса

    newmem:
    Mov [ecx],#100
    mov eax,[ecx] //дописали стёртую инструкцию
    jmp x1

    0081e159:
    Jmp newmem
    x1:
    nop //наши 2 ошмётка
    nop

    [DISABLE]
    0081e159:
    dec [ecx]
    mov eax,[ecx]
    dealloc(newmem)//высвобождаем выделённую память,чтобы не засорять память.
    [ENABLE]

    Листинг 10

    Теперь игра не должна вылетать.

    Если вы знаете инструкции ассеблера, то можно закрепить основы давайте рассмотрим пример из игры.


    mov ecx,[eax]
    mov edx,[esp+04]//<< здесь сработал бряк
    ...
    core.dll+4285C: //<<адрес кода игры

    Листинг 11

    Инструкция mov edx,[esp+04] работает с адресом здоровья как моего игрока, так и других игроков. Что бы прописать здоровье моего игрока я нашёл многоуровневый указатель (как это делать напишу потом) и построил скрипт с фильтром. Сам фильтр можно видеть ниже.


    mov ebx,[core.dll+00155744] //строим многоуровневый указатель
    mov ebx,[ebx+350]
    add ebx,43C //ebx=[[core.dll+00155744h]+350h]+43Ch – многоуровневый указатель,
    cmp eax,ebx //если игрок наш, то прописать 250 очков здоровья
    pop ebx //восстановили ebx
    jne short originalcode
    mov byte ptr [eax],#250 //пишем здоровье нашему гироку
    originalcode: //метка оригинального кода
    mov ecx,[eax] //дописываем затёртые инструкции для восстановления логики кода
    mov edx,[esp+04]
    push ebx  //регистр нам будет нужен, поэтому запихнём его в стек и потом вернём обратно

    Листинг 12

    А теперь листинг 12 встроим весь скрипт.


    UnrealTournament2003+ (InfHealth)*/

    [ENABLE]
    alloc(newmem,2024)
    label(returnhere)
    label(originalcode)

    newmem:

    push ebx
    mov ebx,[core.dll+00155744]
    add ebx,350
    mov ebx,[ebx]
    add ebx,43C
    cmp eax,ebx //ebx=[[core.dll+00155744h]+350h]+43Ch
    pop ebx

    jne short originalcode
    mov byte ptr [eax],#250

    originalcode:
    mov ecx,[eax]
    mov edx,[esp+04]
    jmp returnhere

    core.dll+4285c:
    jmp newmem
    nop
    returnhere:

    [DISABLE]
    core.dll+4285c:
    mov ecx,[eax]
    mov edx,[esp+04]

    /*MasterGH(c) 04.01.08. 

    Листинг 13

    Обратите внимание на то, как мы встроили новое условие. Мы сравнили игрока со своим по его указателю и если это свой игрок, то запишем ему полное здоровье.

    Совет.

    Внимательно следите нужно ли сохранения регистра флагов pushf/popf. В большинстве случаев это не нужно, в противном будет измнена логика и может быть крах игры.

    В скриптах можно много чего «мутить». Разберём специальные команды скрипта (возможно это не все команды, см. справку CE)

    ALLOC(имя, размер)- выделение памяти

    DEALLOC(имя) - высвобождение памяти

    LABEL(имя) - объявление меток

    FULLACCESS(адрес/метка, размер) - установка полного доступа по адресу

    REGISTERSYMBOL(имя) - регистрация метки, метка будет доступна в окне адресов и вдругих скриптах

    UNREGISTERSYMBOL(имя) - убираем метку

    DEFINE(имя,инструкция) - почти неприменятся, если инструкция повторяется то удобно её обзвать и присвоить имя

    INCLUDE(имя файла) - учитывает метки других файлов-скриптов

    LOADBINARY(адрес,имя файла) - загрузка данных или кода из файла по данному адресу

    CREATETHREAD(адрес) - создание потока, который будет выполняться начиная с адреса

    LOADLIBRARY(имя файла) - подгрузка библиотеки

    READMEM(адрес,размер) - в скрипт вставляются байты с некоторого адреса.

    db, dw, dd - означает вставка байтов, 2 байтов, 4 байтов.

    Ну и примеры из англоязычной справки

    Базовая основа скрипта.


    jmp 00410000
    nop
    nop
    nop

    00410000:
    mov [00580120],esi
    mov [esi+80],ebx
    xor eax,eax
    jmp 00451031
    00451029:

    Листинг 14

    Использование меток.



    00451029:
    jmp 00410000
    nop
    nop
    nop
    mylabel:

    00410000:
    mov [00580120],esi
    mov [esi+80],ebx
    xor eax,eax
    jmp mylabel
    label(mylabel)

    Листинг 15

    Использование выделения памяти



    00451029:
    jmp 00410000
    nop
    nop
    nop

    00410000:
    mov [alloc1],esi
    mov [esi+80],ebx
    xor eax,eax
    jmp 00451031
    alloc(memloc1,4)

    Листинг 16

    Использование меток и выделения памяти


    label(mylabel)

    00451029:
    jmp 00410000
    nop
    nop
    nop
    mylabel:

    00410000:
    mov [alloc1],esi
    mov [esi+80],ebx
    xor eax,eax
    jmp mylabel
    alloc(alloc1,4)

    Листинг 17

    Установка полного доступа.

    Обычно, используется совместно с областью неиспользуемого кода. Мной не рекомендуется, разве что в очень специфических задачах. Стоит отказаться от codecave (дыр кода), чтобы это не приводило к краху игры, а пользоваться выделением памяти.


    //из-за выравнивания кратному 1 странице памяти…

    00451029:
    jmp 00410000
    nop
    nop
    nop

    00410000:
    mov [00400800],esi
    mov [esi+80],ebx
    xor eax,eax
    jmp 00451031
    FULLACCESS(00400800,4) //доступ будет не к 4-м байтам, а к 4 кб (в 32 разрядных системах и 8 кб в 64 рязрядных)

    Листинг 18

    Использование DEFINE, как переопределение инструкций.


    00400500:
    clear_eax
    DEFINE(clear_eax,xor eax,eax)

    Листинг 19

    Использование чтения памяти некоторого размера


    alloc(x,16)
    alloc(script,2048)

    script:
    mov eax,[x]
    mov edx,[x+c]
    ret

    x: // по этой метке будет записано 16 байт с адреса 00410000
    readmem(00410000,16)

    Листинг 20

    Пару слов стоит сказать о проверочных байтах. Все они вместе являются уникальной последовательностью (так предполагается) по которой можно установить адрес внедрения. Это нужно чтобы чит-код работал со всеми версиями игры.

    Пару слов про шаблоны.

    Шаблоны, возможно требуется доработать, поэтому о них пока писать руководство не буду.

    Опции Перехват API и переопределения кода, довольно специфичны и пока рассматриваться не будут.

    В общем если хотите научится писать скрипты, то учите ассемблерные инструкции и читайте темы на этом форуме.

    Если вам нужно в скрипте использовать указатели, то можно сделать их следующим образом.

    Так


    dd 0
    [[game.exe+3070A0]+68]+1e4: 

    Или так


    mov eax,[eax+68]
    mov [eax+1e4],0
    mov eax,[game.exe+3070a0] 

    3. Ассемблерные инструкции

    Ассемблерные инструкции.

    Чтобы научиться писать скрипты нужно:

    1) Учиться по примерам скриптов на нашем форуме или на форуме CE

    2) Много практики

    3) Читать справку CE, статьи и примеры. Хорошие статьи, но на английском можно найти также здесь.

    О скриптах CE.

    Скрипты CE обладают ограничениями. Сложно описать какими именно и в каких ситуациях, но один пример можно привести. Если Вам требуется чтобы скрипт изменялся в какой-то момент определённым образом например перед первым запуском, то вы НЕ сможете это сделать только скриптами Автоассемблера. Ну, может быть и можно в зависимости от ситуации - исправлять машинный код скрипта1 машинным кодом скрипта2 с помощью Автоассемблера. Однако, есть более удобное решение - LUA Engine. Информацию по LUA Engine вы сможете найти в соседней теме.

  8. Игра: Just Cause

    post-3-1295708117,65_thumb.gif

    Спрос на трейнер: средне актуален, т.к. игра, возможно, и популярна при этом нет универсального трейнера.

    Дата выхода: сентябрь 2006 г.

    Мин. системные требования: CPU 1,4 MHZ, 512 MB, 64 MB VIDEO

    Дополнительная информация: игра похоже на всем известную GTA3 и выше.

    -Таблица CE (для версии RUS).

    -Трейнер (трейнер должен работать со всеми версиями игры). Запускайте трейнер, затем игру, затем нажимайте на горячие клавиши - всё как обычно.

    Реализованы чит-коды:

     

     

    1. Чит-код на здоровье героя (автор MasterGH)

    Скрытый текст

    Инструменты: CE, MHS.

    Здоровье представляет собой полоску. Значение, которой изменяется плавно, значит, начнём искать с 4 байтов с точкой или (float).

    post-3-1295708122,72_thumb.gif

    рис. 1

    Ищу в MHS адрес типа float подставляя героя под удар правилом «уменьшилось» совместно с правилом интервала от 0,0 до 10000000,0

    Нахожу три адреса и, проверяя их заморозкой, нахожу, что один из них рабочий 05E41E64 = 1850 здоровья. В окне найденных адресов рабочий адрес не зелёный, значит динамический.

    Копируем в CE все адреса из MHS (не рабочие тоже могут пригодится).

    Ставим брейкпоинт на доступ на рабочий адрес.

    Идём в игру и наблюдаем такую картину.

    post-3-1295708130,88_thumb.gif

    рис.2

    Поверяем, что самый часто обращаемый адрес является типом А, т.е. работает только с адресом здоровья героя.

    post-3-1295708137,73_thumb.gif

    рис.3

    Поскольку на рис 3 постоянно находится один адрес при стрельбе во врагов и при их стрельбе в моего героя, то скорее всего мы имеем дело с инструкцией типа А.

    Совет.

    По рис.3 если дело имеем со здоровьем, то сделайте так чтобы несколько врагов отняли его у вас и вы отняли его у нескольких врагов…. Почти аналогично касается патронов, должны стрелять вы и враги.

    Поскольку мне некогда заниматься расструктуризацией объекта и его оружия, копаться в дизассемблере и т.п., то я пойду по простому пути. Вытащу указатель, который пригодится позже на объект из

     
    
    0046508a - d9 40 4c - fld dword ptr [eax+4c], (регистр EAX= 05E41E18 , который был при бряке) 

    Листинг 1

    и оформлю чит-код на здоровье. На рис.2 жму на «Скрипт». Далее «Чит-код->Указатель»

    Убираем лишний мусор и получаем.

     
    
    [ENABLE]
    globalalloc(newmem,2048)
    label(_originalcode)
    label(_returnhere)
    
    label(_buf1)
    registersymbol(_buf1)
    label(_cheat1)
    registersymbol(_cheat1)
    
    label(_pId)
    registersymbol(_pId)
    
    newmem:
    mov [_pId],ecx
    _cheat1:
    jmp short _originalcode
    push ebx
    mov ebx,[eax+48]
    mov [eax+4c],ebx
    pop ebx
    _originalcode:
    fld dword ptr [eax+4c]
    fdiv dword ptr [ecx+48]
    jmp _returnhere
    _buf1:
    db 90 90
    _pId:
    dd 0
    
    JustCause.exe+6508A:>45E08B4DE08B118955DC8B45DC8B4DDCYYxxxxxxxx48D95DD8D905889EA100
    jmp newmem
    nop
    _returnhere:
    
    [DISABLE]
    {JustCause.exe+6508A:>45E08B4DE08B118955DC8B45DC8B4DDCYYxxxxxxxx90D95DD8D905889EA100
    fld dword ptr [eax+4c]
    fdiv dword ptr [ecx+48]
    unregistersymbol(_pId)
    uregistersymbol(_cheat1)
    dealloc(newmem) }

    Листинг 2

    Связываем этот скрипт, переименовываем его на {+A}(здоровье) и активируем его.

    На скрипте кликаем правкой кнопкой мыши и в появившемся меню опции нажимаем «Новый». В новом окне скрипта опять взываем, меню и выбираем «Дополнительный». Генерируется скрипт, исправляем его немного.

     
    
    [ENABLE]
    _buf1:
    readmem(_cheat1,2)
    
    _cheat1:
    db 90 90
    
    [DISABLE]
    _cheat1:
    readmem(_buf1,2)

    Листинг3

    Добавляем этот скрипт, переименовываем на Здоровье и активируем его. Должно получится так

    post-3-1295708143,07_thumb.gif

    рис.4

    Теперь в игре игрок с максимальным здоровьем и бессмертен, враги при этом смертны.

     

    2. Чит-код на бесконечные патроны (автор MasterGH)

    Скрытый текст

    Инструменты: CE.

    Мне пришлось перезапустить игру, поэтому указатель на объект изменился. Он будет равен теперь

    [pId]=05E41F10

    post-3-1295708152,44_thumb.gif

    рис.1

    Возьмём какое-нибудь оружие без бесконечных патронов, а то, которое ниже на рисунке брать нельзя.

    Примечание.

    Какая-то странная игра, у некоторого оружия патроны бесконечны ))

    post-3-1295708157,67_thumb.gif

    рис.2

    Я взял пистолет с глушителем.

    post-3-1295708165,18.gif

    рис.3

    Нашёл два адреса целое 4 байта. Один экранный и другой рабочий, оба динамические (рис 1).

    Ставим бряк на доступ на рабочий адрес. Появляется сразу одна инструкция и определим сразу её тип.

    post-3-1295708170,51_thumb.gif

    рис.4

    Примечание.

    Если мы стрельнем или перезарядимся появятся больше инструкций, но они все типа не А. Также лучше внедрять в инструкцию на рис 4, чтобы изменения патронов видно было сразу.

    Примечание.

    Начало структуры определено неверно, не обращайте внимания. Т.к. eax сам себя затерает. Но если мы знаем адрес, который проскакивает на инструкции, то мы можем определить регистры, что я и сделал.

    После того как определили начало структуры патронов, теперь либо через сканер памяти, либо визуально найдём указатель на объект героя в структуре патронов и по нему я буду делать фильтр вычитания патронов.

    post-3-1295708175,29_thumb.gif

    рис.5

    По этим данным делаем чит-код.

    На рис. 4 выделяем инструкцию и нажимаем на кнопку «скрипт». Пишем скрипт с фильтром.

    Примечание.

    Позже в русской версии я доработаю шаблоны, чтобы не приходилось значительно убирать «мусор» скрипта.

     
    
    [ENABLE]
    alloc(newmem1,2048)
    label(_originalcode)
    label(_returnhere)
    
    newmem1:
    push eax
    mov eax,[eax+78]
    cmp eax,[_pId]
    pop eax
    jne short _originalcode
    mov [eax+00000184],#99
    _originalcode:
    mov eax,[eax+00000184]
    jmp _returnhere
    
    JustCause.exe+21FD11:>00008B55FC038284010000EB098B45F8YYxxxxxxxx008BE55DC3CCCCCCCCCC
    jmp newmem1
    nop
    _returnhere:
    
    [DISABLE]
    JustCause.exe+21FD11:>00008B55FC038284010000EB098B45F8YYxxxxxxxx908BE55DC3CCCCCCCCCC
    mov eax,[eax+00000184]
    dealloc(newmem)

    Листинг1

    Примечание.

    Надо помнить, что активирующий скрипт включается в первую очередь.

    post-3-1295708179,69_thumb.gif

    рис.6

    post-3-1295708183,62_thumb.gif

    рис.7

    Результатом активации двух чит-кодов является рисунок 7.

    Наш герой бессмертен и у него бесконечные патроны.

     

    3. Делаем машину бессмертной(автор MasterGH)

    Скрытый текст

    Машина бессмертная, но пока попадает под влияние выстрелов врагов в результате чего при пробитых колёсах, покорёженной трансмиссии машина передвигается не так хорошо как хотелось бы. На вертолёте опробовать чит не получилось.

    Ниже описан метод нахождения указателя на объект управления машиной внутри структуры объекта машины, так же показано на что правильно ставить бряк.

    Инструменты: CE.

    Запускаем игру, активируем активирующий скрипт.

    Смотрим в CE чему равна метка pID которая указывает на объект нашего героя.

    post-3-1295708189,52_thumb.png

    рис.1

    post-3-1295708194,15_thumb.png

    рис.2

    Т.к. мы помним, что по смещению 4с находится здоровье героя, то логично предположить, что и у машины по такому же адресу будет здоровье и что одна и также инструкция работает с адресами здоровья.

    Итак, крадём машину.

    Ставим бряк на запись на здоровье героя, наносим себе урон

    Примечание

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

    Получаем инструкцию,

    post-3-1295708197,89_thumb.png

    рис.3

    наверняка, она типа C - она работает с объектами, описанными более чем одним классом:: классом игрока и классом машины… Сейчас мы это проверим. Делаем что показано на рисунке выше и стрелам в машину, тут же появился адрес здоровья машины – ага, как предполагали так и получилось. Тип инструкции действительно С.

    post-3-1295708202,69_thumb.png

    рис. 4

    Итак, перед нами две структуры здоровья: игрока и машины.

    post-3-1295708208,78_thumb.png

    рис. 5

    Примечание.

    Берём листок бумаги и ручку. Рисуем рисунок выше и выделяем байты размером с величину страницы памяти.

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

    Я начал с этих поисков.

    1. Поиск. Заходим в машину и ищем в памяти адрес объекта героя, затем выходим из машины и отсеиваем ноль.

    2. Поиск. Заходим в машину и ищем в памяти адрес объекта машины, затем выходим и отсеиваем ноль.

    В итоге нашли по единственному адресу.

    post-3-1295708218,72_thumb.png

    рис.6

    Эти два поиска нам не особо помогли, т.к. указатель на машину не находится в структуре игрока и также указатель на игрока не находится в структуре машины. Отсюда следует какой вывод? )

    Вывод такой, что должен быть замешан какой-то другой объект типа «управления машиной». Если подумать, то объект машины должен содержать указатель на объект управления машиной: это либо указатель на объект управления пользователем, либо указатель на объект управления ботом. А что это значит?

    А это значит, что

    1. Мы ищем указатель на объект управления машиной в объекте машины.

    2. Ищем инструкцию типа А, которая чаще всех работает с указателем на объект управления машины и в неё внедряем чит-код с фильтром: если машиной управляет наш герой, то прописать машине макс. количество «здоровья».

    Очень простая логика, неправда ли, а ведь можно было исследовать дальше и глубже лесть в дебри указателей по адресам поиска 1 и поиска 2.

    К сожалению, я пришлось поменять машину, рисунок будет такой.

    post-3-1295708223,89_thumb.png

    рис.7

    Ставим бряк на рисунке выше. Получаем.

    post-3-1295708228,82_thumb.png

    рис.8

    Раз мы нашли инструкцию, которая работает только тогда, когда только наш герой сидит в машине, значит, в неё и будет внедрять чит-код на бессмертие машины. Правда, лучше внедрять в инструкцию чуть ниже (8569f9), чтобы было меньше гемора в скрипте.

     
    
    [ENABLE]
    alloc(newmem,2048)
    label(_returnhere)
    
    
    newmem:
    mov [edx+48],47C35000
    mov [edx+4c],47C35000
    mov ecx,[edx+000000b4]
    jmp _returnhere
    
    JustCause.exe+4569F9:>4DF883B9B400000000741E6A288B55F8YYxxxxxxxx00E8FC5DC3FF0FB6C085
    jmp newmem
    nop
    _returnhere:
    
    [DISABLE]
    JustCause.exe+4569F9:>4DF883B9B400000000741E6A288B55F8YYxxxxxxxx90E8FC5DC3FF0FB6C085
    mov ecx,[edx+000000b4]
    dealloc(newmem)

    Но данный скрипт не безупречен, машина не разрушается окончательно, но при этом происходит следующее: колёса простреливают, бампер и двери отрываются пулями взрывами =) Так что надо дорабатывать.

     

    4. Чит-код на гранаты (автор MasterGH)

    Скрытый текст

    Данный скрипт вместо описанного ранее скрипта для бесконечных патронов, даёт как патроны так и 99 гранат и возможность бросать пять гранат подряд. Интресно что в один момент времени не может быть более пяти гранат, т.е. если враг бросил одну гранату, то вы сможете бросить только 4-ре. Данное ограничение обусловлено игрой. Для пяти гранат существует структура с пятью 4-х байтовыми адресами. Это уструктура читается из многих мест. Т.е. если создать свою структуру с 100-ней гранат и записать её по другому адресу, то придётся кучу времени потратить на то чтобы код игры работал с новой структурой. Поэтому проще оставить возможно бросать одновременно пять гранат=)

    
    [ENABLE]
    alloc(newmem1,2048)
    label(_originalcode)
    label(_returnhere)
    label(_x1)
    newmem1:
    push eax
    mov eax,[eax+78]
    cmp eax,[_pId]
    jne short _x1
    mov [eax+0000090],#99 // гранаты
    mov [eax+0000918],0 // таймер гранат
    pop eax
    mov [eax+00000184],#99 //патроны
    jmp short _originalcode
    _x1:
    pop eax
    _originalcode:
    mov eax,[eax+00000184]
    jmp _returnhere
    JustCause.exe+21FD11:>00008B55FC038284010000EB098B45F8YYxxxxxxxx008BE55DC3CCCCCCCCCC
    jmp newmem1
    nop
    _returnhere:
    [DISABLE]
    JustCause.exe+21FD11:>00008B55FC038284010000EB098B45F8YYxxxxxxxx908BE55DC3CCCCCCCCCC
    mov eax,[eax+00000184]
    dealloc(newmem)

     

  9. Игра: kkrieger

    post-3-1303480361,51_thumb.gif

    Спрос на трейнер: не актуально.

    Дата выхода: не известна.

    Мин. системные требования: не известны.

    Дополнительная информация: особенностью игры является очень малый размер. Игру можно скачать в интернете. А главное на ней можно потренироваться новичку во внедрении чит-кодов.

    На данный момент по игре рассмотрены:

    Оконный режим (Автор MasterGH)]Инструменты: DirectX Windower, Process Explorer.

    Игрушка очень простая. Как раз для того чтобы потренироваться на ней во взломе патронов и здоровья, но мы будем делать оконный режим, который в настройках не был предусмотрен.

    Поехали..

    Любую игру удобно взламывать (а иногда просто необходимо), когда она находится в оконном режиме. Вот незадача наша игра не поддерживает оконный режим, а чтобы игру взломать в отладке нужно сделать оконный режим обязательно.

    1. Добавляем игру «+» в список.

    post-3-1303480367,47_thumb.gif

    2. Выделяем игру в списке и кликаем настройки.

    post-3-1303480371,42_thumb.gif

    Параметры окна.

    Для того чтобы курсор не прыгал в неактивной области окна игры параметры высоты и ширины окна игры должны быть не меньше половины параметров рабочего стола. В противном случае при игре у вас закружиться голова )))

    *Например, у меня рабочий стол 1680x1050 и я взял окно 900 на 700.

    Если всё же экран игры будет кружиться, опытным путём переместите окно в район верхнего левого положения.

    DLL

    Если вы не хотите запускать игру через значок компьютера, то нужно выбрать D3dHook.dll файл из папки в которой установлена программа.

    USE Background Priority

    Выполнять работу потока от заднего видеобуфера.

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

    USE Background Resize

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

    Дальше делаем настройки как на рисунке ниже.

    post-3-1303480374,81_thumb.gif

    В остальных вкладках ничего не отмечаем. Жмём «Ок»

    3. Аттачим .dll и запускаем игру.

    post-3-1303480379,63_thumb.gif

    4. Игра должна появиться в оконном режиме.

    post-3-1303480383,08_thumb.gif

    И не рассмотрены:

    1. Здоровье (нет автора)

    2. Патроны (нет автора)

    3. Невидимость (нет автора)

    4. И другие, которые вы можете рассмотреть.

  10. Игра: Command & Conquer 3: Tiberium Wars

    ris0.gif

    Спрос на трейнер: актуален, игра популярна и при этом нет универсального трейнера*.

    *Универсальный трейнер - это трейнер работающий с любыми версиями конкретной игры: с патчами, локализацией и т.п. Также универсальный трейнер не вышибает игру и выдаёт информацию почему он не сработал. (Памятка1 для админов, включть это определяние в отдельное место. Памятка2 создать трейнер с выводом ошибок внедрения чит-кодов: "код модифицирован не найдено соответствий отпечатка байт", "код модифицирован множество соответсвий - число соответсвий")

    Дата выхода: 30 марта 2007 г.

    Мин. системные требования: 2 ГГц, 512 Мб, видео GeForce 4/Radeon 8500

    Дополнительная информация: нет.

    На данный момент по игре рассмотрены:

    Оконный режим с параметром (авт. MasterGH)]Инструменты: DirectX Windower, Process Explorer.

    В игре не предусмотрен оконный режим. Дело в том, что отлаживать игру удобно в оконном режиме, поэтому он так нужен.

    Разработчики так сделали что, для запуска игры существует дополнительная программа CNC3.exe, а главный модуль игры cnc3game.dat. Последний запускается с параметром с помощью первого.

    Дерево процессов можно увидеть ниже.

    ris1.gif

    Рис.1 - Дерево процессов в Process Monitor

    В том же Process Monitor я нашёл параметры с которым запускался cnc3game.dat.

    F: Command & Conquer 3RetailExe1.0cnc3game.dat -config ""F:Command & Conquer 3CNC3_english_1.0.SkuDef"

    ris2.gif

    Рис.2 - Информация о процессе

    Я переименовал cnc3game.dat на cnc3game.exe и соответственно командная строка теперь будет

    F: Command & Conquer 3RetailExe1.0cnc3game.exe -config ""F:Command & Conquer 3CNC3_english_1.0.SkuDef"

    Для оконного режима понадобиться прога D3DWindower.

    1. В игре предварительно делаем разрешение 800*600 (минимальное). Закрываем игру.

    2. В D3DWindower выбираем путь библиотеки в папке с программой, пишем командную строку, устанавливаем опции.

    ris3.gif

    Рис.3 - Опции в D3DWindower

    4. Нажимаем на значок «плей», и на иконку с компутером ))

    ris4.gif

    Рис.4 - D3DWindower

    5. Появляется окно игры.

    ris5.gif

    Рис.5 - Окно игры

    6. В списке процессов убиваем тузлу, если она мешает отладчику.

    ris6.gif

    Рис.6 - Конечный результат.

    И не рассмотрены:

    1. Интерес и особую ценность представляет объектная структура игры.

    2. Чит-код на открытие скрытых участков карты.

    3. Чит-код позволяющий стрелять ракетами в любую область.

    4. Чит-коды позволяющие вашей рассе быть непобедимыми, быстроразвивающимися и т.п.

    5. И другие, которые вы можете рассмотреть.

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.