GameHackLab[RU]
    • Категории
    • Последние
    • Метки
    • Популярные
    • Пользователи
    • Группы
    • Зарегистрироваться
    • Войти
    1. Главная
    2. paracetamol
    3. Лучшие сообщения
    P
    • Профиль
    • Подписки 0
    • Подписчики 0
    • Темы 3
    • Сообщения 11
    • Группы 0

    Сообщения

    Последние Лучшие сообщения Спорные
    • Предложка CE таблиц (Paracetamol)

      Предлагаю на общий суд и использование следующие таблицы Cheat Engine:

      • Capsule
      • Terraria 1.4.4.9

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

      • на каком языке лучше выкладывать на просторы необъятного?
      • стоит ли убирать из таблицы структуры или лучше оставлять?

      Буду рад вашим конструктивным замечаниям и предложениям!

      написал в Общий
      P
      paracetamol
    • RE: Как правильно сделать call в своём скрипте?

      Я нашёл решение и теперь у меня получилось успешно вызвать функцию - эффект от неё применился и никаких крашей! :blush:

      Рассказываю и читающему, если ему вдруг тоже интересно

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

      Причины предыдущих неудач
      Игра крашилась у меня не из-за того, что я что-то не так передавал, а из-за того, что вызываемая функция (SkipToTime, см.выше код) почему то:

      1. уничтожает значения регистров edi и esi
      Terraria.Main::SkipToTime+3- push edi
      Terraria.Main::SkipToTime+4- push esi
      Terraria.Main::SkipToTime+5- sub esp,08
      
      1. сразу за этим безобразием без бэкапов обнуляет eax
      Terraria.Main::SkipToTime+8- xor eax,eax
      

      Ну и соответственно после отработки функции и возвращения в исходный код начинали твориться "чудеса" из-за сбоя состояния регистров.

      Найденное решение:

      1. бэкап всех регистров общего назначения, а также edi и esi (понятное дело ebp и esp бэкапить не нужно)
        push eax
        push ebx
        push ecx
        push edx
        push edi
        push esi
      
      1. далее заполняем регистры необходимыми значениями (в моём случае это заполненные нулями ecx и edx)
        xor ecx,ecx
        xor edx,edx
      
      1. собственно сам вызов
      call Terraria.Main::SkipToTime
      
      1. ну и восстанавливаем состояние регистров (естественно в обратном бэкапу порядке)
        pop esi
        pop edi
        pop edx
        pop ecx
        pop ebx
        pop eax
      

      Всё.

      В Террарии наступила ночь, часики перемотались на 7:30 вечера, игра не вылетела, я счастлив, мир прекрасен!

      написал в Взлом игр (начинающим)
      P
      paracetamol
    • RE: Как правильно сделать call в своём скрипте?

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

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

      написал в Взлом игр (начинающим)
      P
      paracetamol
    • RE: Как правильно сделать call в своём скрипте?

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

        // начало скрипта (flgRain выведен в таблицу и назначена горячая клавиша на установку значения в 1)
        cmp byte ptr [flgRain],0              // проверяем не было ли команды на смену дождя
        je endRain                            // если нет - завершаем скрипт
        mov byte ptr [flgRain],0              // если была, то сначала сбрасываем флаг обратно (нам не нужно беспрерывно менять дождь туда-сюда, нужно выполнить код лишь единожды)
        pushad                                // сохраняем все регистры в стек
        call Terraria.Main::get_IsItRaining   // проверяем идёт ли сейчас дождь (результат вернётся в регистр EAX)
        test eax,eax                          // 0 - не идёт, 1 - идёт
        je @f                                 // прыжок к секции начала дождя (пропустить остановку дождя) если EAX==0
        call Terraria.Main::StopRain          // останавливаем дождь
        popad                                 // восстанавливаем регистры из стека
        jmp endRain                           // выход из скрипта (не нужно запускать дождь)
      @@:
        call Terraria.Main::StartRain         // запустить дождь
        popad                                 // восстановить регистры из стека
      endRain:
      

      За идею использования инструкций pushad/popad хочу поблагодарить пользователя "youneuoy" с Discord канала GamehackLab[RU].

      написал в Взлом игр (начинающим)
      P
      paracetamol