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

MasterGH

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

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

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

    129

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

  1. MasterGH
    Пошаговая отладка в dnSpy позволяет ставить брейкпоинты на C# код во время работы игры, перемещаться по коду, просматривать значения переменных.
    Сэкономит кучу времени при поиске и отладке игрового кода,
     
    1. Страница загрузки dnSpy
    2. Скачиваем dnSpy и все архивы с mono.dll файлами
    Unity-debugging-4.x-win32.zip
    Unity-debugging-4.x-win64.zip
    Unity-debugging-win32.zip
    Unity-debugging-win64.zip
    3. Смотрим свойства exe файла игры и определяем по нему версию Unity. Например, "Версия продукта 5.5.0.3120186" или версия "файла 5.50.39994" может указывать на версию Unity 5.5.
    4. Определяем разрядность приложения через Process Explorer
    5. Т.к. версия Unity 5.5 и приложение 32 разрядное, то открываем Unity-debugging-win32.zip ищем там версию Unity и заменяем mono.dll в директории игры
    6. Запускаем игру и dnSpy x86 (игра 32 разрядная поэтому x86). Открываем файл "\...\Managed\Assembly-CSharp.dll" Запускаем отладку нажав F5 или кноgку Play
    7. Настраиваем соединение и жмем ок

    8. Ставим брейкпоинты, смотрим перемененные, перемещаемся по коду, пишем свой код и так далее
    9. После изменения кода, нужно перезаписать модуль предварительно сохранив его
     
    О других способах подключения пошаговой отладки есть на английском руководство.
    ----------------------
     
    Как работать в пошаговой отладке
     
    Работать можно почти также как и в Cheat Engine в пошаговой отладке или в среде разработки программ.
    Начать стоит с обзора названия пространств имен, названия классов, методов и полей, Названия могут подсказать логическую связь с читом, который хотим сделать.
    Стоит обратить внимание на такие названия как "IsPlayer, Player, Character, CharacterController, MainCharacter, Health, Inventory, Craft" и другие. Чтобы не искать вручную можно задействовать поиск сборкам. Поиск стандартного тега "Player" в виде в строки кода (в Unity выше версии 5.0) или свойства "IsPlayer" может помочь найти игрока или отличить от чужих.
     
    Важно представлять иерархию игровых объектов, которую мы не видим в dnSpy. Программист работая в Unity видит это окошко много лет и эту иерархию всегда представляет смотря на скрипты в dnSpy

    Скрипты наследники от MonoBehavior могут находиться на игровом объекте и могут работать как с ним так и с другими объектами. Получается такая штука, что игровой объект всегда имеет Transform компонент с полями позиций, углами и scale. Классы Transform и GameObject самые основные. Методами этих классов можно разместить объект в мире, создать или удалить его. В идеале удалив объект со сцены не должно быть никаких ошибок связанных с пустыми ссылками, потерей объекта. Также и клонировав объект, тоже не должно быть ошибок. Но не всегда так просто отспавнить игровой объект. Если это сделать методами UnityEngine, то другие классы ничего не будут знать о появлении игрового объекта. Нужно ставить брейкпоинт в функции Start или Awake в классе и трейсить по Shift+11 чтобы выйти на функцию разработчиков спавна этого GameObject. Функции Start или Awake (в классе наследника от MonoBehavior) срабатывают один раз при включении скрипта и инициализации. По ним можно выйти на строку кода, которая создает объекты в мире.
     
    Отдельно стоит сказать про количество скриптов. Практически в любой игре, которая мне попадалась в dnSpy много скриптов или очень много. Иногда и не будет понятных названий у типов (из-за обфускации). В любом случае при пошаговой отладке можно найти требующиеся участки кода для создания чита и использовать их по другой логике.
     
    Основные приемы
    В Update можно обновлять параметры только своего игрока. Например, в Character классе сделать сравнения в Update по IsPlayer свойству (если оно там есть) и у тебя за каждый кадр рендеринга будет максимум характеристик.
    В Update с классом Input можно считывать хоткеи.
    В Start и Awake можно подгружать свои ассеты с внутриигровым user interface. Код скриптов перед загрузкой ассетов должен быть внедрен через dnSpy
    Иерархию игровых объектов и инспектор, если очень нужно, то можно отрисовать в user interface. Обычно не требуется. (поищите по форуму в игрострое)
     
    В заключении
    Пока нет времени делать трейнер или таблицу на CE для включения опций в играх Unity. Для меня пока подходит способ через перезапись модуля в dnSpy вручную.
    Вместо трейнера можно сделать программу патчер, который будет проверять версию игры и перезаписывать модуль с возможностью вернуть оригинальный модуль
  2. MasterGH
    Чтобы получить цвет из компонента нужно найти его на форме CE через Lazarus. Этот компонент нельзя найти визуально, он скрыт.
    Узнал об этом случайно, когда зашел на форум Cheat Engine в тему расширений на Lua. Теперь в дизассемблере можно будет быстренько цвета менять

  3. MasterGH
    Спавн итемов удалось сделать через dnSpy.
    При клике на любой предмет на меню крафта он создается в инвентаре, а если там занято, то выкидывается на карту.
     
    Я переписал метод клика на рецепт, вот он оригинальный
     
    На этот
     
     
     
    Для спавна заменить Assembly-CSharp.dll из архива, сделав копию предварительно
    Assembly-CSharp.rar
  4. MasterGH
    Если нужно найти начало и конец подстроки. Пример
    Попробуем найти слово lab в троке gamehacklab.ru
    print(string.find('gamehacklab.ru', 'lab')) >9 11 Если не найдена подстрока, то вернет nil.
     
    С помощью string.match можем выводить не индексы, а строку
    print(string.match('gamehacklab.ru', 'lab')) >lab С помощью string.gmatch можем выводить последовательно строки
    Где 'a.' означает символ 'a' и еще один следующий любой
     
    Здесь комбинация символов "%a+" означает искать слово пока оно не закончится
     
    А здесь заполняем таблицу ключ — значение из строки, которую можно было бы взять из файла
     
    Пока на этом все... Более сложные примеры в предыдущей части записи
  5. MasterGH
    В оригинале, если нет всех компонентов рецепта, то нельзя скрафтить вещь.

    Цель: скрафтить без компонетов по нажатию кнопки
     
    Игра на Unity и можно пробовать использовать в dnSpy модифицировать файл Assembly-CSharp.dll
    Открываем файлик и смотрим на классы связанные с крафтом
     
    Так находим кнопку, которая создаст указанное количество вещей крафта в CreateItem
       
    Задача скрафтить по имеющемуся рецепту любую вещь. Для этого я добавляю проверку количества вещей  и удаляю лишний код. Под сполерами оригинальный и модифицированный код
     
    Визуальное сравнение
     
    Модифицированный код
     
    Оригинальный
     
    Изменяем весь класс или метов в этом окне
     
    Если выводит ошибки при компяляции, то скачиваем IlSpy и его код вставляем в код в dnSpy. Или качаем DnSpy 3.2.0 или ранее
     
    Изменения сохраняем в модуль, запускаем игру и крафтим.
     
    Получить все рецепты (не проверял правда, попробуйте если хотите)
     
    Вещи не ломаются. Убрать отнятие "здоровья" у вещи
     
     
  6. MasterGH
    Есть такой плагин "AA Maker" и там довольно интересные регулярные выражения на Lua. Разберем некоторые выражения
     
    Выражение ''%[(.*)%]' - захват всего, что в квадратных скобках
     
    Пример
    local s = 'mov eax, [ecx + 4]' print(string.match(s, '%[(.*)%]')) --> ecx + 4 Символ "%" нужно всегда ставить перед специальными символами такими как ^$()%.[]*+-?
    Символ "%[" и "%]" означают квадратные скобки в строке
    Разбирая комбинацию (.*).
    Точка означает любой символ, а символ умножить означает повторение любого символа
    Круглые скобки означают "подшаблон" 
    Т.е. можем извлечь содержимое инструкции.
     
    Примеры
    "(.*)" - захват всей строки "/(.*)/" - захват всего, что находится между КРАЙНИМИ символами / "/(.-)/" - захват всего, что находится между ПЕРВЫМИ ДВУМЯ символами / Пример из ААMaker плагина
    local _,_,x = string.find(opcode, '%[(.*)%]') из функции ниже Функция
    string.find("СТРОКА", "ШАБЛОН") возвращает номер позиции начала начала и конца шаблона
     
    Пример
    print(string.find('some string', 'me')) --> 3 4  
    Вся функция с комментариями из AAMaker
     
     
    Чтобы посмотреть результат, сделал скрин отладки Lua кода
     

     
    Функции по работе со строками. Link
    Используемые источники: link, link, link, link
    aamaker.lua
  7. 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: перемещение структуры



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

     
     
  8. 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)  
  9. MasterGH
    Связь точек линиями и связь через метод описанный в статье
     
    Пример1. Слева линии, справа работа алгоритма
     

     
    Пример2. Скриншот из pdf документа с разным значением коэфициента
     

     
    Пример3. С альфа и без альфа канала
     
     
    Ссылка на статью.
    Часть оригинала bundles_infovis.pdf
     
    Где можно применить? Пока не придумал, но впечатлило.
  10. MasterGH
    Я задался вопросом, что такое pointermap. Вообще о нем не слышал и речь пойдет о нем. Я узнал о нём и прикинул, что возможно круто, а возможно и не круто иметь готовую цепочку указателей перед тем, как что-то делать в отладке. Цепочки можно раскрыть в окне структур и прикинуть, что там в них и "около" каких адресов будет происходить отладка. Во время отладки можно смотреть на окна структур. Может быть, а может быть и нет что-то интересное связать в отладке и с данными об указателях...
     
    На видео сравниваются два способа поиска указателей в Cheat Engine 6.7: классический и используя pointermap. Судя по видео последний  эффективнее по времени,  действиям и результатам поиска. Конкретно для этого случая с помощью pointermap сканирования нашлось несколько цепочек указателей.
     
    Можно предположить, что на других играх стоит попробовать этот способ. Способ с pointermap начинается со времени 9:21.
     
     
  11. MasterGH
    В таблице поиска есть колонки ссылающиеся на название Lua перменных: "value" и "previousvalue"

     
    А что можно делать?
     
    Сравнивать текущее и предыдущие значения вместе или по отдельности, в том числе на разных вкладках CE

     
    Примеры:
    value == 65 value == 0x65 (или поставить галку hex) value ~= 65 (или поставить галку not) Можно и такое  сравнение сделать после поиска неизвестного используя математические функции:
    math.abs(value - previousvalue) < 10 Можно делать различные комбинации: 
    and (логическое И). or (логическое ИЛИ). not (логическое НЕ). + (сложение); - (вычитание); * (умножение); / (деление); ^ (возведение в степень); % (остаток от деления). == (равно); ~= (не равно); < (меньше); > (больше); <= (меньше или равно); >= (больше или равно).  
    Что на счет xor? Можно написать функцию xor
     
    Пишем глобальную функцию сначала:
    function BitXOR(a,b)--Bitwise xor local p,c=1,0 while a>0 and b>0 do local ra,rb=a%2,b%2 if ra~=rb then c=c+p end a,b,p=(a-ra)/2,(b-rb)/2,p*2 end if a<b then a=b end while a>0 do local ra=a%2 if ra>0 then c=c+p end a,p=(a-ra)/2,p*2 end return c end А потом применяем даже отдельные функции  как в этом примере
    "value > 0 and BitXOR(value, 100) "
     
    А может быть я хочу только 100 первых результатов
     
     
    CheckCount100() and value > 0 and BitXOR(value, 50)  

     
    Также хочу добавить те адреса, которые предположительно являются указателями
    getAddressSafe('['..value..']')~=nil
     
    Или наоборот не являются указателями
    getAddressSafe('['..value..']')==nil
     
    Еще можно попробовать добавить 50 красных и  50 синих указателей в таблицу CE, но это уже задание кому интересно.
     
    Можно в теории сравнивать адреса со значениями известных адресов и даже с известными указателями, с метками. Но поиск может затянуться, если адресов очень много.
     
    Можно попробовать указать условие, что значение адреса должно находиться в X структуре или в её вероятных указателях.
    Или попробовать оставить только одинаковые значения адресов, т.е. повторяющихся более 1 раза.
    Или попробовать искать только те адреса,  к которым применимы сразу несколько условий чтобы не кликать их постоянно:
    (изменилось) И (больше 0) И (меньше 10000)
    (не изменилось) И (больше 0) И (меньше 10000)
  12. MasterGH
    11 декабря 2019 года форуму Gamehacklab исполнится 10 лет. Это дата первого пользователя форума.
     
    Поздравляю всех: 
    активных пользователей,
    высший состав форума, админов и модеров,
    старожил,
    помогаторов,
    тех кто был на форуме очень давно и перестал заходить.
     
    Отдельно @Xipho, @srg91, @partoftheworlD, @Garik66, @LIRW, @SER[G]ANT, @gmz. Извините, если кого-то персонально  пропустил.
     
    Можно пожелать всем бесконечного энтузиазма на тему поиска сигнатур и значений, сравнении структур и стеков, дизассемблирования и ассемблирования. Энтузиазма в программировании на  C++ и WinAPI. Энтузизма в том, чтобы найти универсальное решение при создании любого чита для любой игры.
     
    P.S. Для энтузиазма. Подкину идею. Мне нравится видеть, как наборы инструкций можно условно разделить на: математические, логические, ветвления, чтения и записи и другие. При этом математические на мой взгляд наиболее выделяются, т.к. они заставляют в игре всему меняться. Хотя логические инструкции тоже могут что-то менять, но по ощущениям не так явно менять, как математические инструкции. По математическим в основном меняются перемещение камеры и перемещение персонажа и изменяются игровые значения.  Можно отдизассемблировать весь игровой код и найти все математические операции и точно некоторые из них связаны с будущими читами. Это всякие добавить, отнять, умножить, разделить. Не думаю, что их будет за тысячу даже, которые именно нужны для читов, а не те которые что-то рассчитывают не понятно что) Если руки дойдут, то возьму IDA да пройдусь по какой-нибудь игре с поиском всех математических инструкций, поставлю на них счетчик срабатывания да прогуляюсь в игре персонажем... Если будет время...
  13. 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
  14. MasterGH
    Долго не могу решить проблему
    Traceback (most recent call last): File "C:\air test\plugins\firebase\build.py", line 124, in run self.SIGNAL_INSERT_LOGVIEW.emit(_str.decode("GB2312").encode("utf-8")) UnicodeDecodeError: 'gb2312' codec can't decode bytes in position 11-12: illegal multibyte sequence QObject::~QObject: Timers cannot be stopped from another thread Если кто шарит на питоне просьба помочь. Питон 2.7
     
    Основная строка
    self.SIGNAL_INSERT_LOGVIEW.emit(_str.decode("GB2312").encode("utf-8")) При билде апк в firebase через плагин в AirTest (QA-тестирование на Unity)
     
    Среда разработки от уважаемых китайских разработчиков Я думаю в связи с этим ошибки с кодировкой GB2312. Гуглил, искал... пока безтолку
     
     
    Исходники
    Билд
  15. 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: спрятал код под спойлеры
  16. MasterGH
    Была задача получить два списка из документа, в котором было с пару десятков тысяч строк. На практике выяснилось, что искать текст после ключевого слова легче чем искать текст до ключевого слова. Об этом и будет дальше
     
    В утилите, которую я делал "Lua Regular Expressions (v. 1.0)"

     
    Текст во вкладке "gmatch"
     
    Game1
    gameCompany
    DAU
    53.21k
    -20%
    Game2
    gameCompany
    DAU
    20.35k
    -20%
     
    Поиск элемента после строки
     
    "DAU "DAU%c%c(.-)%c%c""
     > 53.21k;20.35k;
     
    Поиск элемента до строки
    Вот такой паттерн со двигом скобок для поиска прыдыдущеей фразы
     
    "%c%c(.-)gameCompany%c%c"
     
    не прокатит для вывода списка игр над фразой gameCompany
      
     > ;53.21k
     > -20%
     > 
     > Game2
     > ;
     
    Очевидно, можно сделать поиск по похожим фрагментам, которые идут последовательно сверху вниз. 
     
    Для просты сначала добавим первую пустую строку и видим повторяющиеся фрагменты
     
    %c%cGame1%c%cgameCompany%c%c
     
    пишем шаблон ".*%c%c(.-)%c%cgameCompany%c%c" и опять мимо
     
     > Game1;53.21k
     > -20%
     > 
     > Game2;
     
    Потому что текст над Game2 пошел выше Game2. Тогда делаем захват, только первой фразы и дальше не идем
     
    "%c%c(%w-)%c%cgameCompany%c%c"
     > Game1;Game2;
     
    И тогда все ок.
     
    Но это еще не все. Осталась первая пустая строка, которую добавили, если её удалить, тогда
     
    "%c%c(%w-)%c%cgameCompany%c%c"
     > Game2;
     
     Не видит Game1.
     
     Значит мы можем  убрать %c%c,
     
     "(%w-)%c%cgameCompany
     > Game1;Game2;
     
    Дальше название игры может быть таким "My Game: my Game". Здесь и пробел и двоеточие. В таком случае текст уже будет
     
    My Game1: my Game
    gameCompany
    DAU
    53.21k
    -20%
    My Game2: my Game
    gameCompany
    DAU
    20.35k
    -20%
     
    Пробуем
    (%w-)%c%cgameCompany
    > Game;Game;
     
    Что не верно, т.к. захват одним (%w-)
     
    Мы должны в скобках развернуть фразу имени игры. В ней могут быть пробелы, числа, текст и двоеточие
     
    ([%w%s]-)%c%cgameCompany
    >  my Game; my Game;
     
    Затем

    ([:%w%s]-)%c%cgameCompany

    > My Game1: my Game;

    > My Game2: my Game;
     
    Затем
    %c?%c?([:%w%s]-)%c%cgameCompany

    > My Game1: my Game;
    > My Game2: my Game;
     
    Вот и все. Если  попариться один раз, то тексты уже парсить будет гораздо быстрее.
     
    Так я вывел столбы DAU и названий игр в таблицу, что было в районе 500 строк из пару десятков тысяч строк
     
    p.s. Текст в консоли Lua отличается %c%c, а %с
    p.s.p.s. Можно разсплитить текст по "/n/r" или "/n" в таблицу строк и по индексам данных находить предыдущую или последующую фразу. Но мне проще две строки ввести "%c?%c?([:%w%s]-)%c%cgameCompany" и "DAU%c%c(.-)%c%c"
  17. MasterGH
    Legacy of Kain: Defiance
     
    Это старая PC игра выпущена в районе 2003-2004 годах, когда я еще учился в школе в классе 11-ом.
    В самом конце игры была сложная миссия сражения с боссом, никак не получалось её пройти.
     
    Кстати из этой игры есть персонаж на аватаре у пользователя с форума Cheat Engine
     
    Не мог пройти, как не пытался. То ли руки не из того места, пройти очень хотелось. Было у меня немного журналов игровых и там я много раз видел программу MTC. Казалось, что она очень сложная для понимания. Просто помнил о ней и не пользовался.
     
    Так вот игру пройти не мог и решил все-таки MTC научиться пользоваться. С помощью МТС я впервые сделал чит на HP и прошел игру. После этого я переломал все игры, которые у меня были, изучил в этой программе все что можно, хотя с большим трудом это все давалось. Потом появился Интернет. Узнал про Artmoney и другие сканеры. Кстати 9 мая разработчики обещали новую версию Artmoney.
     
    В общем с Legacy of Kain: Defiance и МТС, и началось увлечение взломом игр
  18. MasterGH
    Вдохновение появилось после просмотра видео @Xipho по Ultimap
    Когда в Ultimap появляются Nx адресов с одним счетчиком, то хочется увидеть эти связи на графиках IDA.
    Появилась идея загуглить как в IDA через IDC скрипт отрисовать ветвь кода или ветви кода, на которых эти самые адреса связаны между собой, а все вложенные другие скрывать.
     
    Пока из подсказок я нашел это и это
     
    Допустим для тренировки даны два адреса из одной ветви кода (это я точно знаю, т.к. получен не из ultimap, а из tracelog)
       
    Адрес1 - Tutorial-i386.exe+2578F - 29 83 AC040000        - sub [ebx+000004AC],eax" или адрес 0x00402B77
    Адрес2 - Tutorial-i386.exe+16DBED - 89 45 FC              - mov [ebp-04],eax или адрес  0x0056DBED
     
    И вот думаю, как  скрипт ниже переделать, чтобы сначала вывести текстовый маршрут, а потом и хотя бы одну ветвь кода. Т.е. поднимаясь вверх по иерархии вызовов нужно остановиться до Адреса2.
     
     
    Пока просто вывод от стартовой функции без условий
     
    Как будет время попробую доделать...
     
    p.s. Ну ничего так idc скрипты. Много всего, но смысл тот же, что и в CE Lua у некоторых функций. Еще не разобрался как Python подключить к IDA, пока на idc скриптах.
    Будет интересно еще посмотреть эту же задачу на Hydra и Radare, ну и в CE (в новой версии появилось окно диаграмм)
     
  19. MasterGH
    FINCSTP
     
     
    Похожа на FSTP, также вращает стек регистров FPU (я кстати не знал, увидел при тестах в CE), но только не перемещает значение по адресу.
     
    FSTP [здесь указывается адрес или регистр]
    FINCSTP
     
    Если нужно вытолкнуть значение из ST(0), а адрес куда его выталкивать не нужен, то можно сделать так
    FINCSTP
    Или аналог
    FSTP ST(0)
     
    При использовании стоит обратить внимание на флаги, возможно их состояние будет влиять на исполнение кода.
     
    *Вообще не помню почему я пишу "выталкивать значение" через fstp, когда оно появляется снизу в ST(8). Т.е. не выталкивается по сути.
  20. 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 тоже фигня. Это ошибки. Это быстро поправить, но могут быть еще ошибки.

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

     
    Вложенные структуры пока отдельно можно создавать в окнах, чистить сканером, потом подставлять их в основную структуру по имени. В общем пока рано об этом писать.
     
    Больше всего меня волнует польза, т.е. что можно с этим сделать. Пока только сразу вышел на скорострельность. Еще шесть параметров покрутил байтовых, ничего не дало. Надо еще попробовать выводить только смещения, которые работают на инструкцияъ чтения, а не "чтении и записи". Запись скорее всего не нужна. Значения просто активно перезаписываются  в структуре. А вот оставлять смещения,  с которыми работает только "чтение" скорее всего даст куда больше вероятности найти параметр настройки.
  21. MasterGH
    Новые директивы try/except в AA доступны Cheat Engine 6.8 Beta2
     
    Задача  try/except в AA обработать исключение, не допустить crash. Чтобы игра продолжалась, а чит в лучшем случае не закрыл бы процесс.
    В теории возможно определить, что был crash и что-то сделать. Например, отправить логи в свой или иной удаленный сервис аналитики, что такой-то чит не сработал...
     
    Пример от DarkByte для  try/except с счетчиком crashes
     
     
  22. MasterGH
    Немного комментариев к этой версии.
     
    1. Исправлены смещения
    2. Добавлены также инструкции на запись
     
    На скриноте ниже пример сравнения текущей структуры с координатами в СТАЛКЕРЕ Зов Припяти с копией структуры.
     
  23. MasterGH
    1. Нашел адрес патронов
    2. Поставил брейкпоинт
    3. Выкинул из рук Калаш с этими патронами
    4. Увидел инструкцию, которая срабатывает когда что-то выкидываешь.
     
    Решил зацепиться за эту инструкцию.
     
    Либо спавн до инструкции, либо после.
    Сделал трейслог из рутины на этой инструкции и второй — в рутину, которая срабатывала постоянно, когда ничего не выкидывали (маркеры слева на сриншоте снизу).
    Поставил кнопкой бряки на все инструкции ветвления
     
    Снимал бряки, когда в игре ничего не делал по F5
    Затем, когда прерываться перестал. Оказался на том месте на скриншоте. Там уже идет ветвление, когда выкидываешь.
    Сделал трейслог из рутины на этой инструкции и второй — в рутину, которая срабатывала постоянно, когда ничего не выкидывали.
     
     
    Получается что-то типа этого условия
    cmp [[edi+00048704]+10],[[edi+00048704]]
     
    Если предмет из рук не выкидывается на сцену, то условие истины и происходит прыжок. Если оружие было викинуто, то в правой части другое значение. Затем левая и правая где-то дальше обнулятся.
    ------------------
    Что я хочу сделать. Разобраться с поиском условий по ветвлениям, которые изменяют [[edi+00048704]+10] и [[edi+00048704]], делать это по аналогии как было описано выше. Для начала, для спавна не запускать поток на его функции, а поменять данные, которые проверяют условия (где-то по рутине), чтобы предметы сами из рук выкидывались. Пока так.
  24. MasterGH
    Открываем Lua консоль из дизассемблера
    Пишем Lua скрипт
    Дальше по шагам как на картинке

     
    Сколько я не пользовался CE я никогда не знал об этом отладчике. Когда я случайно узнал, то был приятно удивлен.
    Если мы пишем какую-то функцию и она дает сбой, то её можно отладить как на скриншоте. Это может быть и не функция.
    Например, код прочитал какой-то файл с текстом сохраненных параметров и подсмотрели в пошаговой Lua отладке что происходит дальше.
     
    *Действуют горячие клавиши. Например, F7— шаг, F9 — запуск без остановки.
  25. MasterGH
    Пост для тех, кто интересуется Lua в Cheat Engine. 
     
    Можно подхватить разные моменты активации и деактивации записи в таблице CE и рассчитать размер кода между метками
     
    1. По шаблону вставляем АА код для туториала Cheat Engine
    2. Регистрируем метки-маркеры в АА коде
    3. Этими метками в Lua считаем и выводим ""endCode - startCode" размер байтов
     
    Пример, который подсчитал 15 байтов

     
     
     
    Пример скрипта
     
    Документация кому интересно
     
×
×
  • Создать...

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

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