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

MasterGH

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

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

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

    129

Записи блога, опубликованные MasterGH

  1. MasterGH
    Немного комментариев к этой версии.
     
    1. Исправлены смещения
    2. Добавлены также инструкции на запись
     
    На скриноте ниже пример сравнения текущей структуры с координатами в СТАЛКЕРЕ Зов Припяти с копией структуры.
     
  2. MasterGH
    Уже была запись про тестирование производительности.
    В этом примере тестируем разное обращение к функции со средним арифметическим значением
     
     
    Результаты при 4-х запусках
    avg = 0.93333998758048 avg = 1.0322099291325 avg = 0.92657961891689 avg = 1.1883763135947  
    Вывод. Разница не существенная.
  3. MasterGH
    Проведено огромное количество опытов над структурами. Много переделок.
    Очень кратко напишу, что поменялось.
     
    1. Название структуры состоит из адреса, количества адресов в ней и  времени в миллисекундах на один байт в структуре.
    Подчеркнуто красным

     
    2. Смещения отбираются только те, на которых за X времени не было обнаружено ни одной инструкции на запись. Чем больше та самая чувствительность,  тем точнее результат
    3. В именах структур теперь ценная информация. Это смещение, регистр и тип
     
    На скриншоте ниже можно посмотреть пункты 2 и 3.
    Также на этом скриншоте я заморозил по соседству адрес (поставил Lock) и пару раз пострелял в игре Сталкере Зов Припяти
     

     
    Выводы, которые я сделал за очень и очень скромное время пользования. За минут 15 и на паре структур оружия в двух разных играх L4D2 и Сталкер Зов Припяти
    1. Если править 4-х байтовые значения, то легко можно нарваться на вылет игры. Но подключившись снова, можно продолжить.
    2. Правки значений с типом в 1 байт могут заблокировать оружие (в двух играх) или же устроить скорострельность на полную катушку в L4D2.
    3. Правки значений с типом float. Можно легко нарваться на вылет в игре, если например поставить нолик. Деление на ноль или какая-то иная причина. Лучше ставить чуть больше нуля, можно положительные или отрицательные значения
    4. Частенько бывают адреса в структуре, на которых включаются инструкции записи только после изменения значения. Тут я пока ничего не смог сделать, просто удалить их из структуры как лишние.
    5. Для сканера используется 1 аппаратный брейкпоинт, остальные три штуки еще не используются, т.к. сложно их прикрутить. Если использовать все 4 аппаратных бряка, то скорость сканера была бы в 4 раза быстрее. Сейчас на 2К байт по 10 мс, у меня уходит где-то 150 секунд. Если я ставил 20мс, то находилось на 10 смещений больше или какие-то другие смещения пропадали.
     
    Код будущего плагина все еще находится на стадии тестирования. Поэтому пока плагин не выкладываю.
     
    upd1:  инструкции cmp, add, sub, xor, and, not, test, mulss, fsub, fmul, dec, inc, mul; теперь выводятся в имя элемента структуры.
    На скриншоте случайно вышел на координаты UI таймера. Сделал три скана трех структур в новых окнах

     
     
    upd2: перемещение структуры



     
    Итог перемещения двух структур в первую

     
     
  4. MasterGH
    Пример, который показывает как снять стек вызовов функций
    function A0() -- Здесь можно удалить ":gsub('\n','\r\n')", но тогда в консоли текст будет в одну строку print(debug.traceback():gsub('\n','\r\n')) end function A1() A0() end function A2() A1() end function A3() for i=1,3 do A2() end end A3()  
    Можно поставить пошаговую отладку в консоли Lua (как на скриншоте) и  пройти по шагам
  5. MasterGH
    Я обратил внимание на следующие поведения записи и чтения
    1. Срабатывают только инструкции чтения до изменения параметра, адрес рабочий
    С адресом работают инструкции на чтение, но если в друг в этом адресе что-то поменять (например в CE), тот тут же выскочат инструкции на запись. Нельзя однозначно утверждать, что адрес является настроечным параметром, но и нельзя утверждать, что это не рабочий адрес. Какая-то инструкция может жестко менять значение, а может быть будет "стараться" изменить значение адреса в меньшую или большую сторону, но адрес при этом будет рабочим.
    2. Срабатывают инструкции записи и чтения, адрес не рабочий
    Запись и чтение влияет только на часть игры, а не на все или вообще не влияет, а перезаписывается постоянно. Например, на визуальное отображение полоски со здоровьем. Получается, что адрес не рабочий, а у него есть как и в первом пункте инструкции и на запись, и на чтение.
    3. Один раз срабатывает инструкция записи и потом всегда на чтение
    Если попался такой адрес в структуре, то он точно является "настроечным" и рабочим адресом. Например, это какой-то коэффициент, который добавляет, умножает, отнимает... в общем что-то меняет. Что с ним не делай, это адрес будут только "читать". Также это может быть булевой параметр "1 "или "0" и по нему может что-то резко меняться в игре.
     
    Окей. Вспоминается окно с кучей инструкций и счетчиков уникальных адресов (не более 8-ми логируется)

    Постреляв патроны  с адресом патронов (в СТАКЛЕРЕ Зов Припяти) сработали инструкции как на запись, так и на чтение.
     
    Первая инструкция читает очень часто, вторая редко. В круглых скобках обозначаются количество проскакивающих адресов.
    Если был выстрел и значение поменялось, то вылезли инструкции записи (все после первых двух).
     
    Код читает в цикле адрес...и если, что поменялось, то запишет в него потом.
    Это похоже на пункт1, который обсуждали выше, но этот адрес патронов не тот, который нужен. С виду рабочий, но патроны потом не стреляют. Патроны это структуры в памяти, а адрес их как  счетчик структур
     
    Как можно делать
     
    Создаем две группы (скрин ниже). Первая текущая и не замороженная. Вторая с двумя замороженными состояниями, когда стоим и ничего не делаем.
    Делаем несколько выстрелов.
    Цвет по +AC нас интересует больше всего, он соответствует логике состояний (стреляю и (не стреляю и не стреляю))

     
    Выделяем и перемещаем адреса этого цвета и морозим в таблице.
     

    Первый праметр это прочность, второй не знаю. Третий счетик патронов. 3 и 5 адреса связанные, если правильно помню, с объектами патронов
    В Сталкере это не даст беск. патрнов, но в других играх может иметь смысл как прием сравнения структур и групп.
     
    p.s. По Сталкеру Зов Припяти, к сожалению, у меня не было времени взломать патроны или может быть я не умею, не знаю. Какие-то патроны в сталкерах ломал, но не помню как.
  6. MasterGH
    Охота на структуры и удивительное путешествие в мир структур в L4D2
     
    1. Игру L4D2 в оконный режим
    2. Установка плагина (позже)
    3. Установка VEH отладчика, иначе вылеты
    4. Первая миссия. Ищем адрес патронов. Бряк на адрес. Нашли инструкцию

    Красным показано, что я не всю структуру проанализирую позже. Долго было ждать. Структура больше 5К байт...
     
    5. Делаем сигнатуру любой инструкции при работе  с патронами на всякий случай, если игра вылетит.
    server.dll,83 BE 14 14 00 00 00 7F 4D 6. Переходим в код и ищем проскакивающие адреса на инструкции. Там один адрес нашего  пистолета. Клик на него и переносим адрес начала будущей структуры в окно Dissect Window.  Можно не создавать структуру (отказываемся). Кликаем "Scanner" (он будет на всех окнах dissrct data)
     

     
    7. Далее побежало сканирование.

     
    В игре можно что-то делать, можно ничего не делать. Долго ждать..
     
    Меняю опции. Чувствительность как была так и осталась минимальная (это время ожидания прерывания на адресе умноженное на коэфициент чувсвительности и на 100 мс).  Размер структуры меняю, до 1100

     
    Наконец ~30 секунд дождался без вылетов (иногда бывают,  возможно из-за VEH). Появился результат

     
    Самые интересны это байтовые и float значения. и инструкции чтения. Их определит можно пока только по логам...
     
    Меняю первый байт на 1 и пистолет стал очень быстро стрелять.

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

     
     
    Логи (для меня и для желающих) по определению типа по опкодам
     
    Плагин выложу позже. Надо еще доработать и потестить.
     
    Вот к примеру float распознал как Pointer и там где fst тоже по +42C тоже фигня. Это ошибки. Это быстро поправить, но могут быть еще ошибки.

     
    Не менее интересны еще вложенные структурки, которые удается раскрыть (не все). Вот одна из них и усеяна параметрами, которые можно покрутить

     
    Вложенные структуры пока отдельно можно создавать в окнах, чистить сканером, потом подставлять их в основную структуру по имени. В общем пока рано об этом писать.
     
    Больше всего меня волнует польза, т.е. что можно с этим сделать. Пока только сразу вышел на скорострельность. Еще шесть параметров покрутил байтовых, ничего не дало. Надо еще попробовать выводить только смещения, которые работают на инструкцияъ чтения, а не "чтении и записи". Запись скорее всего не нужна. Значения просто активно перезаписываются  в структуре. А вот оставлять смещения,  с которыми работает только "чтение" скорее всего даст куда больше вероятности найти параметр настройки.
  7. MasterGH
    Конечно не секрет, что типы данных не правильно определяются. Вот пример для 50-ти адресов
     
    Слева как определил данные CE. Справа как определил их я по логу ниже

    Понравились данные с размером в 1 байт, привлекают в нимание. Как только я переключил на ноль или 1, то персонаж перестал двигаться и не реагировал на движение.
     
    Лог инструкций
     
    Пытаюсь по логам определить алгоритм для Lua, чтобы скрипт сам ставил тип и смещение. Конечно есть сюрпризы, когда регистр перезаписывает сам себя и еще куча опкодов. Чтобы получить такой лог мож попробовать этот скрипт. Он черновой
     
     
  8. MasterGH
    Решил попробовать написать CE Lua  скрипт, который прочесывает структуру и в Dissect data/structures окне создавал бы структуру только со смещениями, с которыми код работает, т.е. читает или пишет.
     
    Например, мой персонаж прогуливается по городу, а каждые 200 мс ставится брейкпоинт на смещение +1 до гипотетической N границы структуры (например до 4096).
     
    Я не успел сделать определение типа, но смещения внутри структуры получить я успел.
     
    Итак, находим начало структуры любой. Запускаем Lua скрипт и просто что-то делаем в игре. Потом вылазит текст с дизассемблированными инструкциями и смещениями. Уже по этим логам можно определить вручную
    1) к каким смещением было обращение (адреса по ним мы и будем менять или сравнивать структуры между собой позже)
    2) по виду инструкции и соседнему смещению уже примерно можно определить тип данных и их размер
     

     
    Осталось сделать определение типа, а это не так уж долго сделать  и осталось взять код из предыдущих записей в блоге формирования структуры в окне dessect data. Так мы получим структуру только с активными смещениями, (а зачем нам пассивные?) и определим в них тип, я надеюсь определим правильно
     
    Пример кода, который я использовал
     
  9. MasterGH
    1. Персонаж падает с большой высоты и разбивается
     
    Ищем адрес скорости прыжка прыгая под speedhack. Находим эту скорость. Ставим бряк на доступ. Прыгаем.
    Инструкции на чтение добавляем в список адресов и там начинаем нопить
    - Либо по одной
    - Либо рискнем по половине от половины
    - Либо рискнем и все сразу занопим
     
    Если повезет, а должно повезти, то инструкция не прочитает то значение скорости, которое уложило бы персонажа на землю и можно будет прыгать на огромную высоту.
     
    2. Как делать супер прыжок
    Ищем под speedhack скорость float (назовем её velocityZ, Z - вертикальная ось) по вертикальной оси прыгая персонажем. Когда прыгаем. то скорость в один момент увеличивается. Затем, скорость постоянно уменьшается от положительного до отрицательного значения.  Когда на земле, то скорость быстро записывается и равна нулю.
    Дальше смотрим что это рабочий адрес. Прыгаем и замораживаем значение. Если адрес рабочий, то персонаж зависает в воздухе или движется.
    Дальше ставим бряк на запись на этот адрес и снимаем speedhack
    Прыгнули и увидели инструкции. Например одна из них будет
    movss [rdi+0000010C],xmm0 и работает каждый раз при прыжке по одному разу за прыжок (прыгнули — сработала, прыгнули — сработала).
    Вот в неё и легко сделать инъекцию с рядом стоящими адресами с умножением на scale величину. Все и персонаж будет с суперпрыжком. Чтобы он не разбивался при прыжке смотрим пункт1
     
    Еще один вариант — не писать инъекцию кода, а искать адрес силы прыжка в структуре.
    Это можно сделать меняя значения в структуре где-то рядом с [rdi+0000010C] и смотреть что происходит в игре. Можно найти, а можно и не найти, и возможно этот процесс будет долгий.
    Еще можно в пошаговой отладке пройтись, посмотреть стек, протресить и попробовать найти адрес в структуре (при чем структура не обязательно будет с адресом в rdi) без рандомного поиска в структуре. Но у последнего есть свои плюсы, можно найти разные параметры движения игрока и увидеть изменения в игре.
     
    3. Менять данные в структурах или менять код?
     
    В примере выше пришлось создать два новых поля
    scaleXY: dd (float)4 scaleZ: dd (float)4 И умножать их на скорости X,Y,Z персонажа.
     
    С одной стороны больше кода писать и добавлять новые поля, а с другой стороны выделить время и найти подход к поиску значения стартовой скорости в структуре. Можно в структуре ничего не искать, а написать скрипт выше и это может быть быстрее чем искать в структуре. С другой стороны если в структуре рандомно ставить параметры в течении времени X на 4К байт, то можно найти: адрес скорости, адрес гравитации, адрес чувствительности и много чего еще.
     
    И еще одно ограничение. Расструктуризация не всегда правильная. Упорно вместо float может видеть 4 байта.  Это в лучшем случае, в худшем разные смешения смержены и выводятся разные типы данных.
    В общем исследование игровой структуры эта тема интересная. Можно сказать это поиск свойств, по которым будет меняется поведения персонажа в игре. Структуру желательно обследовать какой оффест, что делает и какого он типа (через брейкпоинт). Это всего 4К байт проанализировать. Каждое смещение подписать и сохранить. Сделав это вы скажите себе я исследовал всю структуру и знаю, что делает смещение.
     
    Lua может помочь автоматизировать анализ структур и пока я думаю об этом. Данные структур могут сильно повлиять на поведение персонажа,  на прохождение потоком отладочных инструкций игры по разным условиям — выполнять и не выполнять ответвления кода с разными условиям. В общем есть над чем подумать.
     
    Всегда было приоритетным менять код, но теперь стал задумываться о том чтобы больше смотреть в сторону правки данных структур. Фактически код мы не правим, а меняем данные и код работает уже с другими данными.
  10. MasterGH
    Наконец-то дошли руки до третий части.
     
    Речь пойдет о создании структур программно. Пример, что будет в конце записи
     

     
    Сразу к делу. Нужен поинтер и процесс.
    Запустим туториал из Cheat Engine из меню Health->Cheat Engine Tutorial.
    Прохождение туториала подробно описано здесь
     
     
    Подключаемся к процессу идем на 8-мой шаг. В руководстве есть поинтер
    [[[["Tutorial-i386.exe"+XXXXXX]+C]+14]+0]+18  
    Вместо XXXXXX может быть любое смещение. Поэтому надо бы поискать
     
    Нашил адрес.
    Поставили бряк.
    Нашли esi
    Поставили бряк
     
    Вышли сюда
    Поинтер получили, дальше пойдет Lua.
     
    Открываем Lua консоль и проверяем поинтер
    Выведем адрес и его значение
    Окей. Поинтер верный.
     
    Другой вариант читать значение поинтера примерно такой
    local address = getAddress("game.exe") address = readPointer(address + 0x123) address = readPointer(address + 0x456) local value = readFloat(address + 0x789) Есть и такие варианты
    value = readInteger("[[[[[[[[[witcher3.exe + 028F3F60] +0] +18] +20] +40] +40] + 1c0] +10] +28]") value = readFloat("[[[[[[[[[witcher3.exe + 028F3F60] +0] +18] +20] +40] +40] + 1c0] +10] +28]") value = readDouble("[[[[[[[[[witcher3.exe + 028F3F60] +0] +18] +20] +40] +40] + 1c0] +10] +28]")  
    Теперь самое интересное — создание структур с помощью Lua
     
    Построим структуру [[[[005FD660]+C]+14]+0]+18. На +18 будет наш адрес.
     
    Сначала построим один уровень —"005FD660"
    Если выполнить скрипт выше, то мы построим структуру одного уровня.
     
    Построим теперь структуру двух уровней  "[005FD660]+C". Второй уровень нужно развернуть

    Для этого после создания структуры создам дочернюю
    myStructure2 = createStructure('MyStructure2') myStructure2.autoGuess('[005FD660]', 0, 50) -- И поместим её по индексу local offset = 0 myStructure.getElementByOffset(offset).setChildStruct(myStructure2) -- Чтобы развернуть список поитеров. К сожалению разворачивается только два уровня structureFrm.Menu.Items[1][6].doClick()   Итого получается такой скрипт до второго уровня
     

      Создадим и развернем весь указатель [[[[005FD660]+C]+14]+0]+18
      Не будем делать через цикл, чтобы не усложнять.

      Полный скрипт
     
    Результат

     
     Ну и на закуску.
     
    Допустим мы знаем что по адресу X будет всегда тип float (как X,Y,Z координаты). Но расструктуризация будет показывать другой тип, дизассемблер будет показывать другой тип — 4 байта. Что делать?
    И сразу еще допустим double тип всегда хотим как float тип (в виде комментов в дизассемблере или в расструктуризации)
     
    Воспользоваться следующей функцией
    -- Может менять тип адреса x в окне дизассемблере в комментариях, когда в инструкции существует адрес -- Может менять тип адреса в окне расструктуризации -- Изменив тип, будет ображаться значение другого типа onAutoGuess(function) : Registers an function to be called whenever autoguess is used to predict a variable type function override (address, ceguess): Return the variable type you want it to be. If no change, just return ceguess Ну и вот два примера
     
    upd: спрятал код под спойлеры
  11. MasterGH
    Где писать Lua код?
      Lua Engine окно, которое вызывается из главного окна CE.
      Lua Console окно, которое вызывается из окна отладки CE.
      Окно Autoassembler скрипта с вставки {$lua}, {$asm}

      Lua Engine окно и Autoassembler-ные скрипты могут сохраняться в файлах Cheat Engine *.CT. *.CETRAINER, *.EXE
      Lua Console для пошаговой отладки Lua кода и просмотров результатов ошибок и функции print()
     
    Моя первая программа
     
    Сначала узнаем версию для CE 6.7 и это будет первая программа
    Запускаем CE и жмем ctrl+alt+L и Lua Engine, вводим
    print(_VERSION) -->> Lua 5.3 Вторая программа
    showMessage('Hello World!') Следующий шаг — собрать справочные материалы и практические руководства.
    Неважно какими они будут по сложности и объему. Всегда можно будет обратиться к ним позже, когда потребуется что-то найти.
     
    Справочные материалы
    Если CE использует версию Lua 5.3, то нужен официальный справочник по этой версии.

    Ищем

    Я  обращаюсь к celua.txt и defines.lua. Находятся в директории Cheat Engine. В этих файлах краткое справочное руководство.
     
    Стоит также отметить, что Cheat Engine 6.7 написана на Lazarus. Написав, например программу по рисованию фигур, линий на форме на Lazarus или Delphi можно  будет понять, как сделать также классами и функциями на CE Lua. А что нельзя сделать CE Lua, то решается внедрением и исполнения кода в саму Cheat Engine.
     
    Продолжение следует...
     
    upd: добавил ссылку Category:Assembler
  12. MasterGH
    Как контролировать включение и выключение скриптов в таблице
     
    AA или "Autoassembler code" код похожий на язык программирования ассемблера.

    Обычный АА-скрипт состоит из двух директив и добавляется в таблицу CE как запись
    // Код срабатывающий как при активации, так и при деактивации [ENABLE] // Код активации [DISABLE] // Код деактивации Чтобы код активировался, нужно включить галку напротив записи в таблице и наоборот выключить.
    Есть такие директивы как {$lua} и {$asm}.
    Под {$lua} пишут Lua скрипт, под {$asm} пишут АА-скрипт.
    Мы можем проверить Lua скриптом любое условие и разрешить включать галку или выключать галку. Например, через "syntaxcheck" — проверку синтаксиса или другое условие .
    Если проверка не прошла, то не получится галку включить и не получится выключить, если что-то пойдет не так.
     
      В Lua строка из двух минусов "--", обозначает комментарий.

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

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

      process - зарезервированное переменная, показывает что процесс открыт

    В комментариях можно увидеть при каких условиях блокируются включение галки
     
     
  13. MasterGH
    Есть инструкции, которые добавляют мусора больше чем другие.
     
    Показываем объем памяти мусора
    print(string.format('Lua memory usage %.1f MiB',collectgarbage('count')/1024)) Ниже код того как попробовать узнать сколько мусора добавил код при парсинге ассемблерной строки двумя способами
     
    Пример результатов могут отличаться. Фиг его знает почему. Возможно работает сборщик мусора в разные моменты времени
    Lua memory usage 1.8 MiB Lua memory usage 1.8 MiB Lua memory usage 1.8 MiB 1.49 Lua memory usage 1.8 MiB Lua memory usage 2.3 MiB Lua memory usage 2.3 MiB 1.47 Lua memory usage 2.3 MiB Lua memory usage 2.8 MiB Lua memory usage 2.8 MiB 1.49  
  14. MasterGH
    Появилась такая опция асинхронного выполнения скриптов

     
    Если эту опцию поставить на скрипты, то появляются вот такие часики

     
    АА-шные скрипты могут искать в этот момент сигнатуру.
    Lua скрипты потестить было интересно, узнать действительно ли асинхронно выполняется. Например, один скрипт выполняет счет, второй выполняет счет. По выполнении выводится результат.
     
     
    Во время выполнения включаем первую галку. Тут CE подвисает. Затем успеваем нажать на вторую галку. Видим как две иконки часов работают.

     
    После выполнения

     
    Если продублировать 4 скрипта, то видим, что нельзя запустить асинхронно более двух скриптов

     
    Возможно, я Lua код где-то не правильно написал. Вот такой вариант еще делал
     
    Asynchronous testing.CT
  15. MasterGH
    Я задался вопросом, что такое pointermap. Вообще о нем не слышал и речь пойдет о нем. Я узнал о нём и прикинул, что возможно круто, а возможно и не круто иметь готовую цепочку указателей перед тем, как что-то делать в отладке. Цепочки можно раскрыть в окне структур и прикинуть, что там в них и "около" каких адресов будет происходить отладка. Во время отладки можно смотреть на окна структур. Может быть, а может быть и нет что-то интересное связать в отладке и с данными об указателях...
     
    На видео сравниваются два способа поиска указателей в Cheat Engine 6.7: классический и используя pointermap. Судя по видео последний  эффективнее по времени,  действиям и результатам поиска. Конкретно для этого случая с помощью pointermap сканирования нашлось несколько цепочек указателей.
     
    Можно предположить, что на других играх стоит попробовать этот способ. Способ с pointermap начинается со времени 9:21.
     
     
  16. MasterGH
    ИМХО отказываться от CE Lua скриптов из-за утечек памяти не стоит.
    Можно чистить память следующим образом
    function startCollectgarbageProcess(interval, showStatus) local timer1 = createTimer(true) timer1.Interval = interval timer1.onTimer = function () if (showStatus) then print(string.format('Lua memory usage %.1f MiB',collectgarbage('count')/1024)) end collectgarbage("restart") collectgarbage("collect") if (showStatus) then print(string.format('Lua memory usage %.1f MiB',collectgarbage('count')/1024)) end end end -- Собирать каждую 1 минуту и показать результат startCollectgarbageProcess(60000, true)  
  17. MasterGH
    Игра с рандомом. Есть счет.
    Запускается через таблицу в аттаче.
     
    Здесь мог быть AI на Lua, возвращающий номер клетки от 1 до 9.
    function InputAI() -- рандом return math.random (1, 9) end Извиняюсь, лучше рандома пока не могу предложить.
     
     
    Крестики и нолики.CT
  18. MasterGH
    1. Нашел адрес патронов
    2. Поставил брейкпоинт
    3. Выкинул из рук Калаш с этими патронами
    4. Увидел инструкцию, которая срабатывает когда что-то выкидываешь.
     
    Решил зацепиться за эту инструкцию.
     
    Либо спавн до инструкции, либо после.
    Сделал трейслог из рутины на этой инструкции и второй — в рутину, которая срабатывала постоянно, когда ничего не выкидывали (маркеры слева на сриншоте снизу).
    Поставил кнопкой бряки на все инструкции ветвления
     
    Снимал бряки, когда в игре ничего не делал по F5
    Затем, когда прерываться перестал. Оказался на том месте на скриншоте. Там уже идет ветвление, когда выкидываешь.
    Сделал трейслог из рутины на этой инструкции и второй — в рутину, которая срабатывала постоянно, когда ничего не выкидывали.
     
     
    Получается что-то типа этого условия
    cmp [[edi+00048704]+10],[[edi+00048704]]
     
    Если предмет из рук не выкидывается на сцену, то условие истины и происходит прыжок. Если оружие было викинуто, то в правой части другое значение. Затем левая и правая где-то дальше обнулятся.
    ------------------
    Что я хочу сделать. Разобраться с поиском условий по ветвлениям, которые изменяют [[edi+00048704]+10] и [[edi+00048704]], делать это по аналогии как было описано выше. Для начала, для спавна не запускать поток на его функции, а поменять данные, которые проверяют условия (где-то по рутине), чтобы предметы сами из рук выкидывались. Пока так.
  19. MasterGH
     
     
     
     
    Репозиторий
     
    1. На адрес устанавливается брейкпоинт.
    2. Идем в игру делаем или не делаем что-то
    3. Начинают срабатывать инструкции на брейкпоинте
    4. От каждой инструкции начинается трейслог, подобный тому, который есть у CE, но менее тормозной
    5. Заканчивается трейслог на инструкции, на 100-ом счетчике после ret-а (об этом пункте будет уточнение). Здесь выходим на коневой цикл
    6. Трейслог останавливается и ожидание следующей инструкции, которая сработает на брейкпоинте, она должна быть отличной
     
    В итоге мы имеем кучу трейслогов начинающихся с адреса работающего с параметром (например, кол-во патронов в обойме) и заканчивающихся на корневом цикле. Также мы собираем данные об адресах с рет-ами и счетчиками.
    По этим данным можно нарисовать схему, где ret-ы меняют направление пути прохождения потоком дизассемблерного кода
     
    На скриншотах ниже
    Вертикальные линии со кружками -— это ветвь трейслога
    Белый кружок — адрес ret-a, который не повторялся
    Пунктирный кружок — адрес ret-а, который повторялся. Стрелка от такого пунктирного круга будет указывать на белый круг.
     
    По схеме видим, где ret-ы меняют свое направление поднимаясь по рутине в корневом цикле
     
     
     
     
    По плану по визуальной части:
    1. Клик на кружок — переход на код
    2. Придумать что-то, чтобы стрелки не накладывались друг на друга
    3. Установка брейкпоинтов на кружках — становиться красными
    4. Легенда. Номер ветви, связанная инструкция, состояние брейкпоинтов. Комментарий к ветви
    5. Загрузка/сохранение легенды
     
    Для чего нужно. Для поиска условий, которые включают и выключают ветви кода. Т.е. чтобы можно было это условие быстро найти и изменив его, повторить выполнение кода ветви, которая "пробьётся" из корневого цикла. Таким образом попытаться повторить действие в игре, а если не получаться повторить, то определить дополнительные условия.
  20. MasterGH
    Поиск по модулям
     

     
    Исходник
     
    Поместить ModuleListRegioScan.lua в autorun.
     
    Что интересно, Дарк Байт решил написать на Lua. Эта функция жестко в CE не впиливается. Можно выбирать, хочу это расширение поставить или нет. Посмотрел, если понравится, то оставил. Cheat Engine перекомплировать не нужно и не нужно в нем делать опции скрывать или показывать функционал.
     
    Источник
  21. MasterGH
    Источник
     
    Как вступление. Мне нравится Lua, потому что в нем можно писать код в виде строковых данных (и Lua строки, и ассемблерные строки), а затем выполнять эти строки как код. В теории код может по фидбеку делать другой код в автоматическом режиме. Это на мой взгляд неисчерпаемые потенциальные возможности AI ограничивающиеся железом.
     
    В CE 6.7 функция autoAssemble вызываемая в Lua скриптах позволяет включать и теперь выключать скрипт со "своим" dealoc-ом.
     
    Пример.
     
    Функция активации и деактивации:
     
    enableInfiniteHealthCheat()
    disableInfiniteHealthCheat()
     
    // По стилю функции на Lua пишут с буквы в нижнем регистре. Вместо табуляции два пробела. Данные с большой буквы.
     
     
  22. MasterGH
    Напишем функцию, которая в 3.2 раз быстрее кода ниже
    splitDisassembledString(disassemble(address))  
    Сравнивая скорости получаем оптимизацию в ~3.20 раза быстрее.
     
    Пример использования
    function GetDebugString2(address) local clearString = string.gsub(disassemble(address), '%s','') return string.match(clearString, '^(.-)%-(.-)%-(.-)$') end local address, bytes, opcode = GetDebugString2(0x0045464A) print(address) print(bytes) print(opcode) gsub очищает пробелы, а выражение '^(.-)%-(.-)%-(.-)$' позволит захватить данные между тире в строке.
     
    Может пригодится, когда трейсим своим Lua кодом.
    Если заинтересовали регулярки: ссылка
  23. MasterGH
    Инфа по совместной работе с гитом. Может быть пригодится кому, а может и нет. Такую систему я использую на работе недавно.
     
    Можно совместно работать над одним большим проектом через git-flow. Возможно, кто-то из форумчан тоже использует git flow на работе.
     
     
    Кратко. Модель контроля версии построена на 4 ветках
     
    master - релизы
    develop - разработка
    feature - фичи
    hotfix - исравления
     
    С develop начинается разработка через копирования в ветку feature.
    Над фичей идет работа, а после завершения feature мержится с develop и feature сразу удаляется.
    После запланированных изменений develop мержится с master уходя в релиз.
    Если возникли баги, то от master создается ветвь на hotfix . После фиксов hotfix мержится с master.
     
    Доступ к мастер ветки может иметь один человек или его доверенные лица. Ветка Develop открыта для разработчиков. Это значит, что множество разработчиков колдуют в Develop ветке, а мержит изменения с master уже главный разработчик или несколько главных разработчиков.
     
    В мастере создаются теги с обозначением версии.
     
    Шпаргалка по git-flow: ссылка
    Семантическое версионирование : ссылка
  24. MasterGH
    Нажали checkbox — заполнились данные по базовому адресу

     
    Отжали checkbox — удалились данные

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

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

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