GameHackLab[RU]
    • Категории
    • Последние
    • Метки
    • Популярные
    • Пользователи
    • Группы
    • Зарегистрироваться
    • Войти

    Поиск и вызов игровых функций

    Запланировано Прикреплена Закрыта Перенесена Взлом игр (средний уровень и выше)
    1 Сообщения 1 Posters 508 Просмотры
    Загружаем больше сообщений
    • Сначала старые
    • Сначала новые
    • По количеству голосов
    Ответить
    • Ответить, создав новую тему
    Авторизуйтесь, чтобы ответить
    Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
    • S
      srg91
      отредактировано srg91

      [GTA Vice City] Простой спавн машин

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

      Для начала вспомним несколько читов для создания автомобилей.
      Я выбрал чит-код создания катафалка - THELASTRIDE , но так же можно использовать наш любимый чит создания танка - PANZER.

      Собственно ввод кодов - это операция по сохранению текущего введенного символа в строку и последующая проверка получившейся строки на соответствие.

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

      Но если поискать данный текст, мы его не найдем. Как же так спросите вы? На самом деле функция обработки чит-кодов срабатывает на вводе последней буквы, поэтому проще всего просто искать часть введенного кода.
      Выйдем в меню игры, введем чит-код THELASTRIDE и попробуем поискать подстроку TSALEHT (не забываем переворачивать чит-код) в игре:

      f1d20c48-0980-45a6-8b8f-8f6d0d37e105-изображение.png

      Ура, мы нашли текст по адресу 00A0F94F. Не будем его запоминать, он нам не пригодится, а сразу посмотрим, что же творится в памяти.
      Нажмем на адрес правой кнопкой мыши и выбираем Browse this memory Region.

      bcd73714-7af2-4096-a53f-9dd95131ddf2-изображение.png

      В памяти сразу поднимемся на пару строк вверх, обычно строки длиннее чем мы искали:

      6f5bde85-b403-4b24-a1bd-4f3f7f623c50-изображение.png

      Ура, видим часть введенного нами кода. Так же могут присутствовать и другие куски текста, например на скришоте я немного побегал перед вводом чит-кода.
      Теперь мы видим, что в реальности строка ввода чит-кода больше чем мы ожидали, а её начало находится там, где присутсвуют первые символы DW DIRTSAL, т.е. по адресу 00A0F94A. Добавим этот адрес в табличку (размер строки вычислен эмпирическим путем - посчитал не нулевые байты):

      a6f03172-fffa-4fc7-9f2e-0ed06a944841-изображение.png

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

      Посмотрим же, что использует этот буфер - попросим CE найти всех, кто использует данный адрес при вводе чит-кода
      Сначала жмем ПКМ на адресе в главном окне CE и выбираем Find out what accesses this address:

      868a4629-6756-4fdc-8fb7-a9e51f1877d1-изображение.png

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

      dd5a25bc-7d96-42e1-a2a9-d25cd5c703d2-изображение.png

      Теперь введем чит-код на создание автомобиля - THELASTRIDE. Внимательно следим за окном с инструкциями, т.к. в процессе ввода у меня появились еще несколько инструкций, которые используют адрес, но не влияют на появление машины. После ввода последней буквы видим следующую картину:

      39929b27-080c-49b3-b3fb-97585884933d-изображение.png

      Уже можно заметить несколько функций, выполняющихся один раз. Для того, чтобы отсеять лишние инструкции, попробуем ввести другой чит-код, не относящийся к созданию автомобилей, например LEAVEMEALONE:

      7b283ab0-4011-4a89-ad02-69f80a85b3ca-изображение.png

      Ура, из предыдущих инструкций у нас осталось одна - инструкция mov byte ptr [00A0F94A] по адресу 004AC84A. Давайте выделим её и нажмем Show disassembler, чтобы увидеть, где она выполняется:

      6f4a97e4-d885-45cb-ab40-2a1e2ba2c22f-изображение.png

      Собственно мы видим некое условие, после которого в наш буфер записывает 0x20, он же 32 он же пробел и вызывается некая функция gta-vc.exe+AE7C0 с аргументом AC. Заочно можно нас поздравить, потому что мы нашли нужную нам функцию, осталось только убедиться в этом.

      Попробуйте тем же способом найти чит-функцию для создания танка. Я её уже нашел, давайте посмотрим:

      b2f657ee-c347-4847-b56e-740831a5ce26-изображение.png

      Видно, что функция находится немного в другом месте, но отличие состоит только в том, какой аргумент передается в функцию - push записывает в стек A2 , вместо AC. В остальном код условия идентичен и я предлагаю попробовать просто вызывать функцию gta-vc.exe+AE7C0 с разными параметрами.

      Для вызова функции мы будем использовать AutoAssembe и функцию createthread.
      Зайдем в AutoAssembler (откроем Memory Viewer, меню Tools - AutoAssemble) и набросаем следующий скрипт:

      [ENABLE]
      // код, который выполнится при включении скрипта
      
      // выделяем память под нашу функцию, хватит и 64 байта
      alloc(our_func, 64)
      
      // начало нашей функции
      // фактически просто копируем код из игры
      our_func:
      // записываем в стек AC, он же 172
      push 000000AC
      // вызываем некую функцию
      call gta-vc.exe+AE7C0
      // убираем из стека наш AC
      pop ecx
      // конец функции
      ret
      
      
      // создаем поток, который прыгнет на нашу our_func и выполнит код
      createthread(our_func)
      
      [DISABLE]
      // код, который выполнится при выключении скрипта
      
      // просто освобождаем память от нашей функции
      dealloc(our_func)
      

      Добавим его в таблицу через File - Assign to current cheat table и можно закрывать окно Auto assemble.

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

      Обратите внимание, что аргументы в данную функцию передаются как push AC. В оригинальной игре после call мы можем заметить инструкцию pop ecx. Это значит, что функция не трогает стек и мы сам должны двигать его за ним (т.е. откатить push AC). Поэтому после функции выполняется pop и мы обязательно должны его скопировать, иначе ret будет пытаться вернуть поток не куда-то по адресу 0xAA123456, а по адресу 0x000000AC. Почему pop использует ecx? В данном случае - потому что левая пятка компилятора так решила и это ни на что не влияет (ecx спокойно можно заменить на eax и другие регистры).

      Ура, скрипт в нашей таблице, давайте же активируем его! Смотрим на результат и...:

      e5831e99-93cf-47f6-a98d-f6479f7d5467-изображение.png

      Наш скрипт вызвал чит-функцию создания катафалка! Наверное вы уже догадались, что если мы заменим push AC на push A2 мы увидим заспаунившися танк?

      d86d919f-0f3b-4fd7-afd1-26b620e203c5-изображение.png

      Получается, что AC - это катафалк, а A2 - танк. Поискав GTA Vice City Vehicle IDs, мы найдем, что действительно, A2 = 162 - это Vehicle ID танка, а AC = 172 - катафалк. Попробуем указать свой ID, один из списка, например 168 (такси). Передача аргумента превратится в push #168:

      0b1b7e49-109b-41d8-a72b-7282e493a66d-изображение.png

      Можно сказать, что наш скрипт работает! Осталось вынести ID модели как переменную:

      [ENABLE]
      // код, который выполнится при включении скрипта
      
      // выделяем память под нашу функцию, хватит и 64 байта
      alloc(our_func, 64)
      // выделяем память под переменную
      alloc(our_vehicle_id, 4)
      
      // объявляем нашу our_func как переменную,
      // чтобы можно было вызывать createthread из другого скрипта
      registersymbol(our_func)
      
      // объявляем нашу our_vehicle_id как переменную,
      // чтобы можно было обращаться из таблицы
      registersymbol(our_vehicle_id)
      
      // записываем начальное занчение
      our_vehicle_id:
      // sabre turbo
      dd #206
      
      // начало нашей функции
      // фактически просто копируем код из игры
      our_func:
      // записываем в стек наш ID машины
      push [our_vehicle_id]
      // вызываем некую функцию
      call gta-vc.exe+AE7C0
      // убираем из стека наш AC
      pop ecx
      // конец функции
      ret
      
      [DISABLE]
      // код, который выполнится при выключении скрипта
      
      // удаляем информацию о функции
      dealloc(our_func)
      unregistersymbol(our_func)
      
      // удаляем информацию о переменной
      dealloc(our_vehicle_id)
      unregistersymbol(our_vehicle_id)
      

      Я удалил из скрипта функцию вызова потока, чтобы переместить её в отдельный скрипт:

      [ENABLE]
      createthread(our_func)
      
      [DISABLE]
      

      Теперь можно добавить в таблицу адрес our_vehicle_id, в который после записи скрипта будет записано число 206 (ID наикрутейшего Sabre Turbo).

      Это число отвечает за то, что мы передаем в чит-функцию и меня его мы будем менять ID заспаунившегося автомобиля:

      61a53748-f154-4855-9665-9fe2c2c5d869-изображение.png

      Результат:

      020e4c2f-2b88-446d-8c57-166804a01519-изображение.png

      И о проблемах :)

      Скрипт фактически вызывает чит-код, поэтому мы начинаем слыть читерами, рейтинг в игре уменьшается и т.д. Это довольно легко обходится, т.к. если мы провалимся в функцию gta-vc.exe+AE7C0, перед самым ret есть две инструкции - add [gta-vc.exe+5B4F94],000003E8 и mov byte ptr [gta-vc.exe+60FB37],01. Первая накидывает очки читерства (они хранятся отдельно) и устанавливает флаг - "этот парень использовал коды". Если их занопить - игра никогда не узнает о ваших проделках.

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

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

      d2002f43-939d-4cf9-91b6-94a47fe7a6da-изображение.png

      Спасибо @Imaginary за перенос статьи на форум

      1 ответ Последний ответ Ответить Цитировать 3
      • Первое сообщение
        Последнее сообщение