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

Лидеры

  1. MasterGH

    MasterGH

    Ветераны


    • Баллы

      110

    • Постов

      2 999


  2. JustHack

    JustHack

    Разработчики


    • Баллы

      63

    • Постов

      342


  3. imaginary

    imaginary

    Помогаторы


    • Баллы

      19

    • Постов

      319


  4. roma912

    roma912

    Пользователи+


    • Баллы

      13

    • Постов

      223


Популярный контент

Показан контент с высокой репутацией за 26.05.2010 в Записи блога

  1. И снова, здравствуйте)) В этой части, мы с вами создадим NoRecoil. Здесь, я уже не буду всё разжевывать. Опирайтесь на прошлые статьи, кому что-то не понятно. Открываем дамп из прошлых частей. Поиск по строкам. Для начала, нам нужно найти IGameFramework. Вводим "Failed to create the GameFramework Interface!". Двойной клик по строке, попадаем сюда Через окно перекрестных ссылок, выходим на адрес Итак, мы нашли адрес IGameFramewrok = 0x1AF7E2C Теперь, в окне поиска строк, ищем "sp_difficulty" Двойной клик по строке. Меню перекрестных ссылок. Открываем псевдокод. Через ReClass x32 восстанавливаем классы. Переходим к написанию кода. classes.h main.cpp Собираем проект. Внедряем в игру. Готово. Продолжение следует...
    9 баллов
  2. Итак, мы вооружились всеми нужными инструментами и поверхностным пониманием того, что будем делать. Теперь, можно приступать к самому интересному. В этой части, перед нами стоит задача найти SSystemGlobalEnvironment и указатель на I3DEngine. Открываем PeTools и делаем полный дамп. Далее, запускаем IDA PRO и выбираем "новый проект". Открываем наш дамп игры. Выбираем IDA PRO, предложит указать расположение 3 библиотек. Выбираем место установки и нажимаем ОК. Дождёмся, пока IDA проанализирует файл. Вы услышите звуковой сигнал, по окончании. Также, можно будет видеть надпись "idle" (в простое). После окончания анализа, открываем список всех строк. Через меню View или нажав Shift+F12. Жмем Ctrl+F и вводим "ai_CompatibilityMode". Двойной клик по строке и оказываемся тут Выделяем строку и жмем 'X', в открывшемся окне перекрестных ссылок, нажимаем ОК. Оказываемся тут dword_18C23DC это и есть адрес нашего SSystemGlobalEnvironment = 0x18C23DC. Можете переименовать сразу (выделив и нажав 'N' ), можете оставить так. Кому как удобнее. Самое главное мы нашли. Теперь нам нужно найти I3DEngine и SetPostEffectParam. Повторяем шаги с поиском SSystemGlobalEnvironment , только теперь вводим "Dof_Active" в строке поиска. Нашли, выделили, перешли в окно перекрестных ссылок, выбираем первую и жмем ОК. Выделяем, жмем 'F5', для перехода к псевдокоду. Видим такую запись. Выделяем смещение '+136', жмем ПКМ, переводим в HEX. И получаем SSystemGlobalEnvironment + 0x88 это и есть смещение до I3DEngine В итоге имеем: SSystemGlobalEnvironment = 0x18C23DC SSystemGlobalEnvironment + 0x88 = I3DEngine Продолжение следует...
    7 баллов
  3. Привет всем. По просьбам людей с форума, дискорда и ютуба, я напишу цикл статей, по созданию мультихака, на примере CryEngine3 SDK. А может, я не буду вас мучать и ограничимся всего 2-3 публикациями. Всё зависит от вашего интереса и моего свободного времени. По итогу, мы создадим мультихак, содержащий примерно следующий функционал: Аимбот Силуеты врагов 3D боксы оружий и мин Линии до врагов Точность Отдача Антислепа Все описанные действия, могут быть реализованы и в других играх, на движке CryEngine3. Итак, начнем пожалуй с самого простого, а далее будем двигаться к более сложному. Здесь не будет объяснений, что такое дизассемлер, указатели, классы, интерфейсы, смещения и прочее. Если вы не знаете, что это, то вам придется самостоятельно восполнять эти пробелы. Движок CryEngine3, сделан на основе глобальных объектов. Глобальные объекты завёрнуты в одну структуру и являются указателями на абстрактные сущности, которые инициализируются в нужный момент, в нужном месте программы. Никаких дополнительных накладных расходов, никаких лишних надстроек, контроль за типом во время компиляции. CryEngine3 представляет собой достаточно старый проект, где все интерфейсы устаканились, а новое прикручивается подобно тому, что существует на данный момент. Поэтому нет необходимости придумывать дополнительные обёртки или способы работы с глобальными объектами. SSystemGlobalEnvironment - это основной базовый класс, где хранятся указатели на "стартовые классы". Примерное описание и содержание можно посмотреть на GitHub. Т.к. мы решили начать с самого простого, то на этом этапе, мы сделаем хак, который будет убирать эффект ослепления от светошумовых гранат (антислепа / noflash). Метод SetPostEffectParam (ознакомиться) Итак, наша задача найти адрес базового класса SSystemGlobalEnvironment, затем указатель на I3DEngine, восстановить класс и реализовать метод SetPostEffectParam, с нужными нам параметрами. Необходимый софт: Официальный SDK движка Visual Studio 2015+ PeTools IdaPro 6.8+ ReClass x32 Продолжение следует...
    7 баллов
  4. Продолжаем создавать наш noflash. Открываем Reclass x32 и создаем новый класс. Далее, переименовываем название класса в SSystemGlobalEnvironment. Сейчас наш класс очень мал. Нарастите класс до смещения 0x90, используя панель модификации. Переходим на смещение 0x88, жмем по зеленой стрелке, выбираем тип - Указатель. Переименовываем указатель в p3DEngine. Ниже строчкой, переименовываем класс в I3DEngine. Спускаемся еще на строчку ниже. Создаём виртуальную таблицу, указав тип VTable. Открываем и видим, что функций всего 9, а нам нужно 143. Смещение 572 / 4 т.к. 32 битный процесс. Если бы был 64 битный, то делили бы на 8. 143 это и есть наша функция SetPostEffectParam() Наращиваем количество функций, как делали с классом. Переходим на 143 функцию, двойной клик, вписываем саму функцию. И очищаем лишнее в классе. Далее жмем "генерировать" класс. Получаем готовый код класса, копируем в удобное место. Открываем Visual Studio, создаем пустой проект, тип проекта "Библиотека DLL". Добавляем исходный файл main.cpp и заголовочный файл classes.h . В main.cpp подключаем #include <windows.h> #include "classes.h" Прописываем нашу функцию В точке входа создаем поток CreateThread(0, 0, (LPTHREAD_START_ROUTINE)noFlash, 0, 0, 0); Открываем файл classes.h и вставляем туда сгенерированный код из ReClass. В итоге файл classes.h будет выглядеть вот так Собираем проект. Внедряем в игру. Готово. Продолжение следует...
    5 баллов
  5. Возможен бан в игре. Вы используете хак, на свой страх и риск. Перед использованием, ознакомьтесь с ЭТИМ Поддерживаемые ОС: Win7+ (x64) Поддерживаемая версия клиента: (x64) Поддерживаемая версия DirectX DX9, DX11 Поддерживаемые античиты: MRAC Версия от 11.11.20 (Последняя) Undetected ЕСП: Силуеты врагов Силуеты взрывчатки Силуеты капсулы Силуеты пауки Силуеты боссов миссий Аимбот: Супер аимбот Кость - наилучший выбор (простые враги - голова, джаггернаут - рюкзак и т.п.) Аим на турели Аим на пауков Аим на мины Аим на капсулы Аим на боссов Мемхаки: Отдача Точность Беск патроны АнтиАФК Кик с пве и спецопераций (в любой момент) Подсад в любой точке на карте Быстрый нож ПКМ, ЛКМ Без перегрева СЕД Видео: Инструкция: Запускаете игру Внедряете dll Нагибаете Активация/Деактивация хака - клавиша INSERT wfru.rar
    5 баллов
  6. Вот и настало время когда я вернулся снова к этой игре Только теперь уже для нее есть исходный код, который позволит находить всякие функции в разы быстрее и проще На этот раз будем делать карту ресурсов, рисовать ее и загружать прямо в игру Этапы которые этому способствуют 1. Распаковать саму карту из surfaces.pck 2. Достать саму карту, посмотреть каким образом она примерно отображается 3. Узнать координаты респа ресурсов Vec3 на карте 4. Перевести Vec3 игровые в Vec2 картовые 5. Нанести по Vec2 соответствующие иконки 6. Привести все в читаемый формат для игры 7. Запаковать все обратно 1. Распаковка pck этой игры уже не представляется сложностью, и есть довольно много софтов делающее это (Собственно как и упаковка обратно) А значит пункты 1 и 7 не сложны совсем 2. Карта в игре отображается довольно специфическим образом (Незнаю как до этого додумались разработчики, или же это движок сам режет так интересно) В целом картина такая Мировая карта состоит из 88 частей - т.е. 8 столбцов и 11 строк (В свою очередь каждый квадрат тут 1024*1024 пикселя) Из всех этих кусков собирается единая карта, которую можно будет увидеть в игре Формат файла dds, т.е. в итоге мы должны получить карту в 88 dds файлов как в оригинале 3. Координаты респа найти довольно легко, опять же распаковав configs.pck Внутри будет coords_data.txt в котором некоторым списком указаны Vec3 координаты нахождения ресурса / моба и т.п. Структура примерно такая Парсим нужные координаты по ID (Пишем вспомогательный парсер который выдаст c++ массив с Vec3) 3091 - ID, world - фильтрация только для основной карты Ну и достаем Vec3 - x y z координаты 4. Когда есть массив всех этих ресурсов, нужно перевести Vec3 (Т.е. внутриигровое положение в мире, на карту, которая 2D) Тут поможет исходник клиента PW, и метод который рисует стрелочку игрока на карте Вот та самая функция в исходном коде, далее надо ее найти и заменить координаты (т.е. оригинально передаются Vec3 игрока, и вычисляется Х-У для рисования на карте) Ничто не помешает нам подменить эти координаты на те, где находятся ресурсы Vec3 Далее дело техники, и создания хука (Учитывания calling conventions, определения аргументов и т.д.) Имея исходный код не так сложно найти функцию (Правда версия игры немного старее чем этот исходный код) Собственно вот и хук. В цикле перебираем массив который сделали на шарпе путем парсинга файла Выдаем результаты в виде массива (Далее пригодится) Таким образом я получил координаты для 4х видов ресурсов (Больше мне и не нужно. Vec2 координаты) ~320 штук 5. Далее необходимо нанести все это дело на карту. Дабы не скреплять все 88 кусков в каком-нибудь редакторе мне удалось найти (Не без помощи) карту 8*1024 х 11*1024 пикселей. Т.е. точно такую как и нужна Для добавления иконок на общую картину была написана еще одна вспомогательная программа на шарпе, которая грузит общую карту, а потом по координатам ставит маленькую иконку 16х16 по координатам из массива (Скрин выше) Ну соответственно наносим сами иконки на общую карту и сохраняем в jpg. Получаем на выходе карту в 113мб с нанесенными иконками Остается всего 2 пункта, один из которых пустяковый 6. Режем эту общую карту в фотошопе (Качаем фотошоп, да да у меня его не было на этой машине) с помощью инструмента "раскройка" И как раз получаем 88 изображений; 8 столбцов и 11 строк, где каждая картинка по 1024*1024 пикселя. Идеально Остается нерешенным только вопрос конвертации из jpg в dds. Но тут придется только ручками все делать. А также ручками приводить потом названия этих кусочков в вид который на скриншоте №1. (Не смертельно, но долго) Заменяем 88 dds файлов на новые в папке maps 7. Запаковываем все обратно в единый pck файл программой из п1. и проверяем в игре. Все работает. Отлично.. Сама по себе идея не новая, но вот реализации именно внутри игры пока что не видел нигде
    5 баллов
  7. Обход функции, снятия скринов античитами. 01.11.2020 Undetected Поддерживаемые системы: x64 only Windows 7+ Поддерживаемые режимы игры: Windowed mode FullScreen Инструкция: Для запуска требуются права администратора Запустить файл Запустить игру Играть В зависимости от античита, скрины не будут сниматься или будут чистые BpScr.rar
    5 баллов
  8. Вот тут показаны некоторые простые функции LUA и как сделать управление перемещением на примере игры Terraria. Первая часть: Вторая часть:
    5 баллов
  9. 11 декабря 2019 года форуму Gamehacklab исполнится 10 лет. Это дата первого пользователя форума. Поздравляю всех: активных пользователей, высший состав форума, админов и модеров, старожил, помогаторов, тех кто был на форуме очень давно и перестал заходить. Отдельно @Xipho, @srg91, @partoftheworlD, @Garik66, @LIRW, @SER[G]ANT, @gmz. Извините, если кого-то персонально пропустил. Можно пожелать всем бесконечного энтузиазма на тему поиска сигнатур и значений, сравнении структур и стеков, дизассемблирования и ассемблирования. Энтузиазма в программировании на C++ и WinAPI. Энтузизма в том, чтобы найти универсальное решение при создании любого чита для любой игры. P.S. Для энтузиазма. Подкину идею. Мне нравится видеть, как наборы инструкций можно условно разделить на: математические, логические, ветвления, чтения и записи и другие. При этом математические на мой взгляд наиболее выделяются, т.к. они заставляют в игре всему меняться. Хотя логические инструкции тоже могут что-то менять, но по ощущениям не так явно менять, как математические инструкции. По математическим в основном меняются перемещение камеры и перемещение персонажа и изменяются игровые значения. Можно отдизассемблировать весь игровой код и найти все математические операции и точно некоторые из них связаны с будущими читами. Это всякие добавить, отнять, умножить, разделить. Не думаю, что их будет за тысячу даже, которые именно нужны для читов, а не те которые что-то рассчитывают не понятно что) Если руки дойдут, то возьму IDA да пройдусь по какой-нибудь игре с поиском всех математических инструкций, поставлю на них счетчик срабатывания да прогуляюсь в игре персонажем... Если будет время...
    4 балла
  10. Всем привет. В этой статье, мы создадим 100% точность и разброс для нашего учебного проекта. В этом уроке, появляется всё больше самостоятельной работы. Хотя, для тех, кто освоил прошлые уроки, это покажется легкой прогулкой. Мы просто, заставляем ваш мозг производить какие-то действия, а не тупо идти по шагам и копипастить. Итак, для создания этого, нам понадобится узнать смещения 2 классов - IGame и ICVar. IGame - ищем "IsPlayer" Получили смещение класса IGame. Аналогично с ICVar - ищем "GetCVar" и проделываем предыдущие шаги. После этого, нам нужно найти смещения функции SetIPelletsDisp и CrosshairSpreadTuning в ICVar. Нашли, восстановили классы, пишем саму функцию: void noSpread() { while (true) { IGame* pIGame = pSSGE->pIGame; if (!pIGame)continue; ICVar* pIcvar = pIGame->GetICvar(); if (!pIcvar)continue; float iValue = 200; pIcvar->SetIPelletsDisp(iValue); pIcvar->CrosshairSpreadTuning(0); Sleep(1); } } Собираем, внедряем, готово. Продолжение следует...
    4 балла
  11. Случилось мне столкнуться с ситуацией, что есть "лёгкий" способ сделать очень интересные изменения в процессе, просто подменив URL адрес запроса, или ответ, получив при этом совсем другой результат, так появилась эта программа ?. Не работает на Windows 8 и 10 А вот и описание.. Программа URL drafter Основные функции: Отслеживание URL запросов программы: Позволяет отслеживать и логировать все передаваемые программой URL запросы. Это позволяет получить прямые ссылки на скачивание или просмотр файлов / информации которая запрашивается процессом. Например - htmp файл с параметрами, или 3ds модель, что угодно. Создание фильтров подмены: Позволяет создать фильтр, указав в нём полный запрос от программы, управлять его состоянием, сохранять файлы со списком фильтров, загружать эти файлы. Таким образом можно сделать много файлов для разных функций и загружать их когда нужно. Фильтр позволяет заменить URL запрос на свой, таким образом можно подменить файл, или что либо ещё необходимое процессу. Файл можно положить на свой локальный сервер (localhost), или туда куда удобно. Нужно учитывать что не все файлообменники отдадут файл по прямому запросу от не авторизованного пользователя (процесса). Побочные функции: Просмотр всех процессов в системе - их id и имени. Просмотр загруженных в процесс модулей. Команды программы можно посмотреть введя "help". Все команды могут принимать аргументы сразу, или по порядку. Например ввести "connect 3442" или сначала "connect" а потом "3442" это одно и тоже. Программа создаёт файлы в директории которой лежит, если не будет указан полный путь, потому лучше поместить файл в папку. Версия 32 бит: URLdrafter x32.exe Создание фильтра: *Удобнее создавать фильтры через файл Для создания фильтра нужно прописать "fcreate (название фильтра) (номер активности 1/0) (что найти) (на что заменить)" Название - может быть абсолютно любым. Номер активности - включён ли фильтр, позже можно изменить командой "fenable" Что найти - полная URL ссылка, без http, в таком виде как выводит программа. На что заменить - полная URL ссылка без http которой будет заменена найденная ссылка Пример: В файле фильтр выглядит вот так: ,1,WeaponModel,localhost/map.eax,abz/online.html, фильтры разделяются пробелом или переходом на новую строку, запятые обязательны в начале и в конце. *Фильтры работают только если включен перехват URl . Краткое руководство, если что то не понятно: Примеры использования фильтров на разных приложениях (НЕ будет пополняться): Небольшое видео работы: *Это консольное приложение написанное на C++. *Пока доступна только 32 битная версия, соответственно открывать 64 битные процессы ей не получится. 64 битная НЕ выйдет в ближайшее время. *Распространение разрешено с указанием данного форума как источника и авторства (хотя в программе всё указано).
    4 балла
  12. Рекомендации 1. Медленный условный брейкпоинт 2. Медленное определение адресов на инструкции
    4 балла
  13. Пошаговая отладка в 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 вручную. Вместо трейнера можно сделать программу патчер, который будет проверять версию игры и перезаписывать модуль с возможностью вернуть оригинальный модуль
    4 балла
  14. Проведено огромное количество опытов над структурами. Много переделок. Очень кратко напишу, что поменялось. 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 балла
  15. Охота на структуры и удивительное путешествие в мир структур в 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 тоже фигня. Это ошибки. Это быстро поправить, но могут быть еще ошибки. Не менее интересны еще вложенные структурки, которые удается раскрыть (не все). Вот одна из них и усеяна параметрами, которые можно покрутить Вложенные структуры пока отдельно можно создавать в окнах, чистить сканером, потом подставлять их в основную структуру по имени. В общем пока рано об этом писать. Больше всего меня волнует польза, т.е. что можно с этим сделать. Пока только сразу вышел на скорострельность. Еще шесть параметров покрутил байтовых, ничего не дало. Надо еще попробовать выводить только смещения, которые работают на инструкцияъ чтения, а не "чтении и записи". Запись скорее всего не нужна. Значения просто активно перезаписываются в структуре. А вот оставлять смещения, с которыми работает только "чтение" скорее всего даст куда больше вероятности найти параметр настройки.
    4 балла
  16. 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 может помочь автоматизировать анализ структур и пока я думаю об этом. Данные структур могут сильно повлиять на поведение персонажа, на прохождение потоком отладочных инструкций игры по разным условиям — выполнять и не выполнять ответвления кода с разными условиям. В общем есть над чем подумать. Всегда было приоритетным менять код, но теперь стал задумываться о том чтобы больше смотреть в сторону правки данных структур. Фактически код мы не правим, а меняем данные и код работает уже с другими данными.
    4 балла
  17. Описание: Инжектор с ручным отображением (Extended) + скрытый запуск процесса 31.03.2021 Undetected Поддерживаемые ОС: Только 64 бит Windows 7 Windows 8 Windows 8.1 Windows 10 Инструкция: Запустить jhinj.exe (требуются права администратора) Выбрать ID процесса из списка и нажать ENTER Указать расположение dll для инжекта или модуля для скрытого запуска Нажать ENTER Профит Внимание! После 1 запуска, имя инжектора отображаться не будет. В последующем вам необходимо запускать файл ".exe" СКАЧАТЬ
    3 балла
  18. Вступление В CE выделим участок кода и функцию Sub eax,edx - вычитание и наиболее значимее чем запись и чтение. После декомпиляции Если выделили две инструкции Обращать внимание будем на математику, логику, условия и потом на чтение и запись. В данном случае, нужно найти вычитание из адреса "eax4->f1152 = eax4->f1152 - (eax3 + 1)" Как поставить декомпилятор 1. С форума Cheat Engine качаем архив 2. Распаковываем в папку с Cheat Engine 3. В настройках открываем плагин cesmartdec.dll 4. Идем на инструкцию, выделяем функцию 5. Декомпилируем на первой выделенной инструкции из всех выделенных
    3 балла
  19. Я решил рассмотреть три новые функции: Пользовательские типы данных в hex-окне Фильтр на окне определения адресов Поиск данных в окне Tracer 1. Пользовательские тип данных в hex-окне Пример как сделать: Фильтр на окне определения адресов 3. Поиск данных в окне Tracer Обычный поиск, как на прошлых скринах Примеры Ну и более интересная версия перебора и одновременного выделения записей. Здесь нужно открыть окно "Трейсера" и рядом в Lua окне писать свои условия в функции "Compare()", "PrintData()", Selected() Документация Для вывода referencedBytes из трейслога можно использовать byteTableToDword(referencedBytes) (смотрим документации выше) получая из TfrmTracer.Entry[index].referencedBytes или в строке поиска у Трейслога вбить byteTableToDword(referencedBytes) > 0 and print(string.format("0x%08X - 0x%08X", RIP, byteTableToDword(referencedBytes))) == 1 Практическое применение Больше всего могут интересовать реальные практические примеры. Если будет время, желание может быть сделаю, а так просто общий обзор.
    3 балла
  20. Уже множество раз разными участниками форума поднимался вопрос о внедрении своих функций (например на С++) в чужой процесс и что бы они там правильно исполнялись. То есть что бы можно было написать свой код, потом включить компиляцию, и функция добавляется в чужой процесс без всяких проблем, на неё можно послать поток игры, сделать прыжок и так далее, изменять когда хочешь на высоком уровне, а не на ассемблере. Мною было проведено исследование в котором было поставлена цель сделать это, и по итогам это вполне возможно! и это просто замечательно! ☺️ Нужно просто написать внедряющую часть, которая учитывает различные моменты и восстанавливает зависимости функции в новом процессе. В этих трёх видео показан процесс исследования с нуля, до успешной работы ? В них нет звука вообще, даже кликов, так что советую включить какую то музыку если будите смотреть А ещё в них прокомментированы действия, и некоторые функции взаимодействия с памятью других процессов, что может быть полезно: В первом виде всё медленно из за моей сонности ? Во втором кульминация продуктивности! В третьем к завершению дополнительно рассмотрено как сделать бегающий по экрану квадратик (к сожалению на видео он мерцает, на самом деле это не так), а ещё в нём почему то гора пропусков в конце, постоянно само ставилось на паузу, но это уже после основной части, где эксперимент объявлен успешно завершённым ? (если кто то что то заметит странное то скажите пожалуйста если не лень) Тут показан общий принцип, если кому ни будь это будет интересно, могу продолжить и добавить перенос других зависимостей что бы можно было писать используя типы, или же вызывать другие функции, которые не помечены как внедряемые (то есть перенос вложенных функций) Добавлены видео: Скучное видео в котором делается AOBscan для автоматического поиска Часть 5, в которой код приводится в порядок и создаются универсальные функции, а потом демонстрируется автоматическое размещение на разные адреса, это лучшее видно в плане принципа работы и кода? Демонстрация того что можно сделать, но уже на 64 бит ☺️
    3 балла
  21. Спавн итемов удалось сделать через dnSpy. При клике на любой предмет на меню крафта он создается в инвентаре, а если там занято, то выкидывается на карту. Я переписал метод клика на рецепт, вот он оригинальный На этот Для спавна заменить Assembly-CSharp.dll из архива, сделав копию предварительно Assembly-CSharp.rar
    3 балла
  22. В таблице поиска есть колонки ссылающиеся на название 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)
    3 балла
  23. Эта программа полезна тем кто: Хотят поиграть в новые игры, но возможности приобрести самые современные устройства для этого нету Хотят увеличить разрешение в какой либо игре, выше системного - аналог сглаживания Хотят развернуть на весь экран приложение, которое это не поддерживает Описание: Программа позволяет изменять разрешение на заданное пользователем и растягивать окно на весь экран, пока работает определённый процесс. Например, таким образом можно оптимизировать игру, (уменьшив разрешение), растянуть на весь экран и тому подобное. История: В некоторых играх, например в Watch Dogs 2, есть такая настройка - качество разрешения. Изменяя её, можно уменьшить качество выводимого на экран изображения, и очень сильно увеличить fps. К сожалению далеко не все разработчики делают такую настройку, и мне захотелось создать такую программу, которая будет делать тоже самое, но с любой игрой. Инструкция: При первом запуске программа создаст в своей папке (там где лежит exe) файл games.ini, в нём будет 2 строчки заполненные для примера. Все команды программы и инструкцию можно узнать в ней, написав help. Файл нужно заполнять вот так: Название_процесса.exe Xразрешение Yразрешение Пример: witcher3.exe 800 600 terraria.exe 640 480 Каждая игра должна начинаться с новой строки, расстояние между элементами должно быть один пробел. Если игра имеет права админинстратора, то программа тоже должна быть запущена с такими правами. После запуска программа сразу начинает работать, если файл заполнен правильно, остаётся только запустить игру. После запуска игры разрешение изменится, окно игры разместится под размер экрана, после закрытия игры разрешение будет восстановлено, игру лучше всего запускать в оконном режиме без рамки. потому что некоторые игры в полноэкранном режиме принудительно пытаются поставить своё разрешение, если программа не сможет переспорить игру в таком случае, она об этом сообщит Если возникают проблемы с узнаванием названия процесса игры, можно посмотреть все активные процессы и процессы использующие DirectX с помощью команды show Если написало что игра запущена и разрешение, но оно не изменилось, значит это разрешение не подходит к вашему монитору, монитор не поддерживает любые разрешения, потому например 274 x 367 может и не сработать. Используйте правильные разрешения, например если хотите получить разрешение 2/3 от своего, разделите X и Y своего разрешения на 3, умножьте на 2 - такое вероятней всего будет записано. Эксперементируйте, или посмотрите таблицу поддерживаемых разрешений для вашего монитора с помощью команды list. Если в названии процесса используются пробелы, пишите его в кавычках, например: "For See.exe" 800 600 Файл: 64 бит: ResFitter x64.exe 32 бит: ResFitter x32.exe
    3 балла
  24. Сегодня рассмотрим старую, но все еще актуальную ммо под названием Perfect World Берем конечно же не актуальную версию официального клиента, а пиратский сервер с его старенькой версией 1.5.3 (Summer PW) Официальная версия 1.6+ На данном пвп сервере изменены некоторые полеты для персонажа, введены некоторые, так называемые "рисованные" вещи которые довольно плохо влияют на баланс сервера Да к тому же сервер заточен еще и под донат, т.к статы вещей могут быть рандомными (Классно...) Как раз 4 стата и считаются рандомными, выпадают с некоторым шансом из общего пула. Ну и начнем собственно, посмотрим что можно сделать в этой игре интересного Начнем копать от локального игрока Ищем его указатель. Это довольно просто, не возникает никаких трудностей Указатель имеет всего одно смещение по типу *(LocalPlayer*) + 0x4 И собственно так мы вышли на структуру персонажа Далее нашли оффсеты до координат и прочего. Самое интересное оказалось то, что можно изменить скорость персонажа прямо с клиента, а сервер будет воспринимать это как действительную скорость персонажа Обычная скорость игроков на сервере порядка 5-6 м/с в зависимости от класса персонажа, довольно обычная расстановка в ммо играх Изменив скорость персонажа с клиента у сервера не возникло вопросов, а легально ли это и просто съело это. Путем проб и ошибок я подобрал значение скорости [м/с] которое допустимо записью в адрес. Это 15 м/с Скорость 15 м/с считается максимальной скоростью передвижения персонажа на сервере (Когда мы передвигаемся пешочком) Но скорости в 15 м/с ведь мало , без каких либо бафов на ускорение и пр. Поэтому пробуем увеличить до 20 м/с простой записью и персонажа начинает откидывать назад при перемещении Тут у меня есть предположение исходя из пошаговой отладки, что переходе через порог допустимого значения, сервер начинает сбрасывать скорость персонажа до 5-6 м/с опять же в зависимости от класса Но на сервере есть всякие плюшки на ускорение персонажа, этим мы и воспользуемся Установлено что максимальная скорость без бафов 5-6 м/с. С бафами 15-20 м/с Опять же путем проб и ошибок было выяснено что можно преодолеть эти 15 м/с А преодолеть их можно путем наложения бафа ускорения на персонажа, которое работает примерно по такому принципу curSpeed = (15.0*2) Значит мы можем это легко использовать и нас не будет откидывать. Звучит неплохо Делаем бинд на запись значения в адрес скорости. Пусть это будет 30 м/с, включаем баф на ускорение и радуемся скорости в 30 м/с без каких-либо откидываний назад Правда такое будет работать только пока на нас весит баф на ускорение, т.е ровно 15 сек А после окончания действия бафа нам придется довольствоваться скоростью в 15 м/с, но все равно это скорость останется постоянной и уже превышает скорость обычных игроков примерно в 2-3 раза Вопрос остается в том, как же обойти или сделать так, чтобы значение подстраивалось в нужное когда на нас висит нужный баф Делается довольно просто, путем чтения ID бафа на ускорение и его проверки на существование Необходимо найти какой-то список бафов и после читать его каждые допустим 20 мс А при нужном ID бафа просто менять значение скорости персонажа. Все довольно примитивно Выйти на массив бафов нам поможет счетчик кол-ва бафов персонажа, который должен быть где-то в памяти игры *Стандартные процедуры в СЕ. 1-2-3-4 бафа, сканируем, потом находим указатель на этот счетчик* И в итоге оказывается что этот счетчик лежит прямо в структуре персонажа, хотя мб и логично В некоторых играх может быть и иначе Выше над счетчиком и лежит наш список бафов, смещение между бафами ровно в 0x12 Узнаем наш ID ускорения и запоминаем Остается теперь написать программу которая поможет нам делать все манипуляции с памятью Запускаем, проверяем
    3 балла
  25. Наверняка многие из вас не задумывались о том, можно ли запустить онлайн или одиночную flash игру из браузера отдельно, например для повышения производительности и разворачивания на весь экран? Так вот - такой способ есть, и даже очень простой. Нам понадобится вот эта программа, это официальный flash проигрыватель - вся его функция это проигрывать приложение по ссылке, с компьютера или же из интернета. Теперь такая инструкция - идём на сайт с интересующей нас игрой, к примеру я пойду на сайт где можно сыграть в "bad pigges". Теперь идём во вкладку позволяющую просматривать загружаемые файлы, у меня это "сеть" и в фильтр поиска вписываем .swf Запускаем плагин (если у вас нету такого, перезагрузите страницу вместо запуска плагина). Видим что нашлись файлы: Копируем URL файла, и идём в нашу программу. Зайдя в программу нажимаем на Файл --> Открыть... и получаем такое окно: В него вставляем ранее найденный URL и нажимаем ОК. Запускается игра, и мы можем развернуть на любой размер. Вот на весь экран у меня: С онлайн играми та же история, но тут есть одно но. Если в игре есть авторизация которая происходит через соц сеть или же через сайт, а не через flash, то вам нужно будет авторизовавшись в игре сразу получить ссылку не дав ей загрузиться, и сразу закрыть, так как по этой сесси вряд ли пустит ещё раз (защита от взлома аккаунта).После этого можно открывать эту ссылку во flash. Кстати, открываемые ссылки сохраняются, так что вам не придётся постоянно искать их заново. Нужно будет просто выбрать из меню.
    3 балла
  26. Пост для тех, кто интересуется Lua в Cheat Engine. Можно подхватить разные моменты активации и деактивации записи в таблице CE и рассчитать размер кода между метками 1. По шаблону вставляем АА код для туториала Cheat Engine 2. Регистрируем метки-маркеры в АА коде 3. Этими метками в Lua считаем и выводим ""endCode - startCode" размер байтов Пример, который подсчитал 15 байтов Пример скрипта Документация кому интересно
    3 балла
  27. Плагин ведет историю поиска, отсева, отмены. Логи выглядят следующим образом Для чего может применятся На шаге отсева посмотреть в логах, какое значение искали до этого и какой способ поиска использовали. При неудачных поисках мы просматриваем как и что мы сканировали раньше. Если вообще ничего не получается при сканировании, то логами можно обмениваться. Горячие клавиши, которые настраиваются из окна настроек CE работают и в логах. Установка: скопировать GHL_log.lua в директорию "/autorun" Lua скрипт: В комментариях можно написать про ошибки или про идеи улучшения плагина.
    3 балла
  28. UserData в Lua это пользовательский тип. Точно не знаю, но я думаю в документации в CE Lua (celua.txt или здесь на офф. сайте) тип userData у всех классов или большинства классов. Например, проверим, что главная форма CE это userData тип local mainFormCE = getMainForm() print(type(mainFormCE)) > userdata (вывод из консоли) Выводим список свойств следующим образом через getmetatable функцию. Метатаблица — это особая таблица свойств Lua-переменной (подробнее здесь) local mainForm = getMainForm() local listUserData = createStringlist() for k,_ in pairs(getmetatable(mainForm)) do listUserData.add(k) end local allowCustomInput = false local id, name = showSelectionList("Title", "Caption", listUserData, allowCustomInput) print ('Index: '..id..", Name: "..name) listUserData.destroy() Результат в виде списка свойство переменной mainForm Чтобы наглядно было. Свойства эти похожи на свойства из Дельфи. Можно загуглить, они поддробно описываются. Берем например свойство цвет. Прочитаем оригинальное и запишем свое любое local mainFormCE = getMainForm() print(mainFormCE.getColor()) > 536870912 -- в hex-е это 0x20000000. Можно перевести в калькуляторе или через print(string.format("%08X", 536870912)) Случайное свое впишем ради наглядного примера mainFormCE.setColor(546484)
    3 балла
  29. В оригинале, если нет всех компонентов рецепта, то нельзя скрафтить вещь. Цель: скрафтить без компонетов по нажатию кнопки Игра на Unity и можно пробовать использовать в dnSpy модифицировать файл Assembly-CSharp.dll Открываем файлик и смотрим на классы связанные с крафтом Так находим кнопку, которая создаст указанное количество вещей крафта в CreateItem Задача скрафтить по имеющемуся рецепту любую вещь. Для этого я добавляю проверку количества вещей и удаляю лишний код. Под сполерами оригинальный и модифицированный код Визуальное сравнение Модифицированный код Оригинальный Изменяем весь класс или метов в этом окне Если выводит ошибки при компяляции, то скачиваем IlSpy и его код вставляем в код в dnSpy. Или качаем DnSpy 3.2.0 или ранее Изменения сохраняем в модуль, запускаем игру и крафтим. Получить все рецепты (не проверял правда, попробуйте если хотите) Вещи не ломаются. Убрать отнятие "здоровья" у вещи
    3 балла
  30. Решил попробовать написать CE Lua скрипт, который прочесывает структуру и в Dissect data/structures окне создавал бы структуру только со смещениями, с которыми код работает, т.е. читает или пишет. Например, мой персонаж прогуливается по городу, а каждые 200 мс ставится брейкпоинт на смещение +1 до гипотетической N границы структуры (например до 4096). Я не успел сделать определение типа, но смещения внутри структуры получить я успел. Итак, находим начало структуры любой. Запускаем Lua скрипт и просто что-то делаем в игре. Потом вылазит текст с дизассемблированными инструкциями и смещениями. Уже по этим логам можно определить вручную 1) к каким смещением было обращение (адреса по ним мы и будем менять или сравнивать структуры между собой позже) 2) по виду инструкции и соседнему смещению уже примерно можно определить тип данных и их размер Осталось сделать определение типа, а это не так уж долго сделать и осталось взять код из предыдущих записей в блоге формирования структуры в окне dessect data. Так мы получим структуру только с активными смещениями, (а зачем нам пассивные?) и определим в них тип, я надеюсь определим правильно Пример кода, который я использовал
    3 балла
  31. Наконец-то дошли руки до третий части. Речь пойдет о создании структур программно. Пример, что будет в конце записи Сразу к делу. Нужен поинтер и процесс. Запустим туториал из 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: спрятал код под спойлеры
    3 балла
  32. Где писать 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
    3 балла
  33. Появилась такая опция асинхронного выполнения скриптов Если эту опцию поставить на скрипты, то появляются вот такие часики АА-шные скрипты могут искать в этот момент сигнатуру. Lua скрипты потестить было интересно, узнать действительно ли асинхронно выполняется. Например, один скрипт выполняет счет, второй выполняет счет. По выполнении выводится результат. Во время выполнения включаем первую галку. Тут CE подвисает. Затем успеваем нажать на вторую галку. Видим как две иконки часов работают. После выполнения Если продублировать 4 скрипта, то видим, что нельзя запустить асинхронно более двух скриптов Возможно, я Lua код где-то не правильно написал. Вот такой вариант еще делал Asynchronous testing.CT
    3 балла
  34. Я задался вопросом, что такое pointermap. Вообще о нем не слышал и речь пойдет о нем. Я узнал о нём и прикинул, что возможно круто, а возможно и не круто иметь готовую цепочку указателей перед тем, как что-то делать в отладке. Цепочки можно раскрыть в окне структур и прикинуть, что там в них и "около" каких адресов будет происходить отладка. Во время отладки можно смотреть на окна структур. Может быть, а может быть и нет что-то интересное связать в отладке и с данными об указателях... На видео сравниваются два способа поиска указателей в Cheat Engine 6.7: классический и используя pointermap. Судя по видео последний эффективнее по времени, действиям и результатам поиска. Конкретно для этого случая с помощью pointermap сканирования нашлось несколько цепочек указателей. Можно предположить, что на других играх стоит попробовать этот способ. Способ с pointermap начинается со времени 9:21.
    3 балла
  35. Привет, читатель! Ты сейчас читаешь это, потому что в тебе есть интерес ко взлому игр и низкоуровневому программированию, ибо этот мини-блог будет посвящен как раз этой тематике. Если конкретнее, то я постараюсь показать и рассказать о том, как пишутся движки для трейнеров. Если ты вдруг не в курсе, то трейнер - это программа, позволяющая всячески изменять поведение компьютерной игры. Например, сделать ГГ (главного героя) бессмертным или же выдать ему миллион игровых очков. В общем, сделать нечто такое, чего штатный игровой процесс не подразумевает. Если ты вообще не понимаешь, о чем идет речь, то сначала поищи в интернете, как создаются читы для игр, а потом уже возвращайся сюда. Я буду предполагать, что взламывать игры (искать значения в памяти и немного пользоваться отладчиком/дизассемблером) ты уже умеешь. Итак, поехали! Весь исходный код я буду хранить в репозитории на github, ссылку на него и на нужный коммит буду выдавать в конце статей, если это потребуется. С чего начнем? А начнем мы с выбора инструментов. Мои коллеги по цеху давно и очень успешно создают подобные этому обучающие материалы, но на высокоуровневых языках - C++ и C#, а местами и на Delphi. К счастью, мы от подобного избавлены, так что выбор у нас один - Ассемблер. Первая проблема заключается в том, что их много и они местами сильно различаются, так что отныне и в обозримом будущем я буду использовать [flat assembler]. Идешь на сайт в раздел "Download" и качаешь последнюю версию flat assembler for Windows (на момент написания этой статьи - 1.71.63). Скачанный архив нужно куда-то распаковать и можно запускать местную среду разработки - fasmw.exe. А вот и код на сегодня: ; main.asm format PE GUI 4.0 include 'win32wxp.inc' invoke ExitProcess,0 data import library kernel32,'KERNEL32.DLL' import kernel32,\ ExitProcess,'ExitProcess' end data Что происходит? ААА! Да ну, все в порядке. Разберем построчно. Символ точки с запятой обозначает комментарий. Сразу берем за правило, что в каждом файле исходного кода первой же строчкой будет идти его имя. В местной среде разработке (как и в любой другой) есть возможность запустить программу на исполнение, предварительно ее скомпилировав (если язык разработки является компилируемым). В твоем случае нужно выбрать меню "Run->Run" или ткнуть F9. Если звезды сложатся удачно, то с виду ничего не произойдет. Отсутствие ошибок - это половина успеха! Но вернемся к разбору исходного кода. Первой осмысленной с точки зрения компилятора строчкой идет вторая. Она указывает, что же за формат такой должен получиться на выходе. Формат, в смысле - исполняемого файла. EXE, то есть. В Windows основным таким форматом является PE, он же Portable Executable. Подробнее про него можно почитать в Интернете, например [тут]. GUI говорит компилятору о том, что это будет приложение с графическим интерфейсом пользователя, а не консольно-текстовое, что нам и нужно. И пока хватит с этой строчки, подробности про нее можно почитать на сайте ассемблера в разделе Documentation. Далее у нас идет директива include. Тут все просто - компилятор ищет файл с таким именем и банально вставляет вместо всей этой строчки его содержимое, как есть. Или ругается, если что-нибудь пошло не так. Если ты очень любопытен, то можешь найти этот файл в папке с ассемблером и посмотреть, что в нем написано. Пока что я скажу, что в нем описываются функции WinAPI - это такой здоровенный набор функций Windows, из которых и состоят, по факту, все программы. Запустить программу? WinAPI! Открыть файл? WinAPI! Поменять картинку на рабочем столе? WinAPI! И вот так всегда. Все в Windows сводится к большой стопке разных функций WinAPI, вызванных в нужном порядке. Хочешь подробнее прямо сейчас - ищи в Интернете (подсказка: MSDN). Что там идет дальше? Точно! Единственный, на самом деле, кусочек реального кода программы, а не какой-то вспомогательной фигни. invoke - это вызов функции. После этой команды идет имя функции и ее аргументы, если они есть. Самая настоящая команда ассемблера! На самом деле, конечно, это макрос, но об этом потом. Как бы это выглядело в реальной жизни? Представь, что надо заварить 10 чашек чая. И даже есть функция (по сути - просто набор действий) под названием "СделатьЧай". Что должна делать эта функция? Взять чашку, насыпать в нее чай, налить кипяток, добавить сахар, перемешать. Так и пишем: СделатьЧай: 0. Взять чашку 1. Насыпать в чашку чай 2. Налить в чашку кипяток 3. Добавить в чашку сахар 4. Перемешать Допустим, что мы пишем на ассемблере программу, которая заваривает чай. И что "СделатьЧай" - это функция WinAPI. Вот так будет выглядеть ее вызов: invoke СделатьЧай Ага! Ты сразу спросишь - "а нафига ноль в конце той строчки? что еще за аргументы такие?". Аргумент - это просто некое значение, передаваемое функции в момент ее вызова. Например, "СделатьЧай, 10 раз". Если бы наша функция, делающая чай, принимала аргумент "Количество" и была бы написана так, что был бы в ней цикл - "делать чай, пока количество не станет равным 0, после каждой чашки отнимать от количества 1", то делала бы она за один вызов 10 чашек и вместо: invoke СделатьЧай ; 0 чашка invoke СделатьЧай ; 1 чашка invoke СделатьЧай ; 2 чашка invoke СделатьЧай ; 3 чашка invoke СделатьЧай ; 4 чашка invoke СделатьЧай ; 5 чашка invoke СделатьЧай ; 6 чашка invoke СделатьЧай ; 7 чашка invoke СделатьЧай ; 8 чашка invoke СделатьЧай ; 9 чашка Можно было бы написать всего лишь: invoke СделатьЧай,10 ; 10 раз И оно бы внутри в цикле 10 раз вызвалось. Удобно ведь? Конечно! И места меньше занимает. Функция у нас вызывается всего одна - "ExitProcess" с аргументом в виде нуля. Знатоки английского языка могут догадаться, что эта функция делает. Завершает процесс. Выходит. Совсем. Да, все так - все, что программа делает на данный момент - это успешно завершает свою работу. Успешно, потому что аргумент у нее "0". Аргумент этой функции - это так называемый код возврата. Он сильно нужен (зачем-то) Windows и она решает именно по коду возврата, хорошо ли было программе во время работы или плохо. Вот случись ошибка - завершаешь программу с не-нулевым кодом возврата и все, Windows об этом будет знать. Когда-то давно это была единственная возможность узнать результат работы - эти самые коды возврата были описаны в документации к программам. Так-то! Итак, выяснилось, что оно начинает работу и сразу же ее завершает, зато успешно. Ну а что, надо ведь начинать с чего-то, верно? Остался последний кусок. Кусок этот отвечает за предоставление нашей программе доступа к WinAPI. Эти все функции - не магия и не само собой оно работает, а где-то в системе хранится. Если точнее, то хранится в библиотеках, которые имеют расширение DLL, хотя тоже являются исполняемыми файлами. Да, они тоже исполняемые, просто не умеют сами запускаться - их должен загрузить в себя другой процесс (работающий EXE файл) и можно будет вызывать функции загруженной библиотеки. То, какие функции можно вызывать, а какие нельзя, определяется библиотекой, а процесс, загрузивший ее, может только попросить указать ему место, где в библиотеке нужные ему функции лежат. Этим и занимается секция data import - end data. Мы указываем, что нам нужно загрузить библиотеку kernel32.dll, а из нее - функцию по имени ExitProcess. Что происходит при запуске? EXE-файл загружает библиотеку. Та сообщает ему, где искать адрес функции ExitProcess. После этот самый адрес и подставляется команде invoke. Такой вот компилятор умный. На этом пока закончим. [Репозиторий] на github. [Коммит].
    3 балла
  36. Существует три логических оператора: and, or, not. Те, кто уже знаком с языками программирования знают, как эти логические операторы работают. Например, A = true B = true if A and B then print('Условие "A and B" выполняется') end if A or B then print('Условие "A or B" выполняется') end B = false if not (B == A) then print('Условие "not (B == A)" выполняется') end Но, дальше интереснее. Все логические операторы считают false и nil ложными, а все остальное — истинными. Оператор "and" возвращает свой первый аргумент, если он ложен и в противном случае возвращается второй аргумент Оператор "or" возвращает свой первый аргумент, если он не равен false и в противном случае возвращается второй аргумент. Сходу можно запутаться, но с примерами станет понятнее print (4 and 5) --> "5". В этом примере '4" не ложный, а значит при операторе "and" вернется второй аргумент "5". print(0 and 13) --> "0". Аналогично print(false and 13) --> "false". В этом примере первый аргумент false(ложный), а значит при операторе and вернется "false". print(4 or 5) --> "4" В этом примере "4" не ложный, а значит при операторе "or" вернется уже первый аргумент "4". print(false or 5) --> "5" В этом примере "false" ложный, а значит при операторе "or" вернется уже первый аргумент "5". Если кто вспомнил, то в C# есть такой оператор "?" (условный) string result = 4 == 4 ? "равно" : "не равно"; // result будет равен true На Lua это эквивалентно local result = ( (4 == 5 and "равно") or "не равно") А если опустить все скобки, то local result = 4 < 5 and "равно" or "не равно". Скобки можно опустить, потому что "and" имеет выше приоритет чем "or." Или вот еще пример compactmenuitem.Caption = state and 'Compact View Mode' or 'Full View Mode' Вот такая интересная штука для ускоренного сравнения вместо конструкции if условие then -- код else -- код end Идем дальше. Полезной идиомой Lua является x = x or v что эквивалентно if not х then х = v end Т. е. x равен значению v, когда x ложное. Оператор "not" всегда возвращает true или false print(not nil) --> true print(not false) --> true print(not 0) --> false print(not not nil) --> false
    2 балла
  37. Перед использованием, ознакомьтесь с ЭТИМ Поддерживаемые ОС: Win7+ (x64) Поддерживаемая версия клиента: (x64) Поддерживаемая версия DirectX DX9, DX11 Поддерживаемые античиты: MRAC Версия от 27.08.21 (Последняя) Undetected РЕЖИМ РАБОТЫ: PvP PvE Спецоперации ЕСП: Силуеты врагов Силуеты взрывчатки Силуеты оружия Силуеты капсулы Силуеты пауки Силуеты ресурсы Силуеты активаторов Силуеты мини боссы Силуеты боссов миссий СуперАимбот: Кость - наилучший выбор (простые враги - голова, джаггернаут - рюкзак и т.п.) FOV 360 Аим на игроков Аим на ботов Аим на летящих врагов Аим на турели Аим на мини боссов Аим на боссов Мемхаки: Отдача Точность Без затвора Быстрая перезарядка Увеличенный FOV игрока Самоубийство (клавиша END) АнтиАФК Кик с пве и спецопераций (в любой момент) Быстрый нож ПКМ, ЛКМ Без перегрева СЕД Инструкция: Запускаете игру Запускаете ghl.exe Нагибаете pass : !WFhw~26_Av2.0
    2 балла
  38. В данной статье, мы научимся определять тип комнаты, в которой мы находимся и что-то делать в зависимости от этого. Есть множество вариантов использовать это. Например, вы хотите, чтобы какая-то ваша функция работал в одном режиме, но не работала в другом. Ещё пример, рисовать скелеты на противниках (когда мы до этого дойдём). Порядок костей в PvE и PvP разный, поэтому, без определения типа комнаты вам не обойтись. В игре существует 10 типов комнат: Лобби игры Командный бой Захват флага Игроки против ботов Подрыв Штурм Каждый сам за себя Уничтожение Доминация Выживание Для того, чтобы успешно определять тип комнаты в которой мы находимся, нам необходимо посмотреть это через структуру ICvar и смещение в ней. Для типа комнаты, это смещение равно ICvar + 0x600 Добавим в наш код новое смещение Добавим в перечисление CvarOffsets новое значение Теперь наше перечисление со смещениями, выглядит так Добавим в класс ICvar новый метод. Теперь класс ICvar выглядит так Создадим перечисление со всеми возможными видами комнат Далее, получение типа комнаты И всё, что вам остаётся сделать, это сравнить тип комнаты с нужным вам и что-то сделать Если вам что-то не понятно, не стесняйтесь задавать свои вопросы в ЛС Discord или ниже в комментариях.
    2 балла
  39. Сложность: 1/5. В этом видео рассматривается способ взлома игры "Удаление инструкций" (noping). С помощью этого способа игровое значение не будет перезаписываться игрой, потому что в игре удаляется инструкция записи значения.
    2 балла
  40. В этой статье, мы с вами расширим наш проект, функцией для исключения любого союзника с любой спецоперации или PvE миссии, в любой момент. Система кика игроков со спецоперации и PvE работает по следующему принципу: Автоматическое исключение за бездействие (по таймеру) Исключение голосованием игроков Проблема заключается в том, что если игрок активен (например, использует афкбот), система не сможет автоматически исключить его. У вас остаётся только единственный вариант, это голосование игроков. Но и здесь есть проблема. Она заключается в том, что после 2-3 контрольных точек, флаг возможности голосования переключается и запустить голосование игроков невозможно. Наша задача включить функцию кика и указать количество контрольных точек, в течении которых она будет активна. Добавим в наш код новые смещения В итоге, мы имеем такой набор смещений Добавим в перечисление CvarOffsets новые значения Теперь наше перечисление со смещениями, выглядит так Пишем функцию, для включения кика игроков в любое время Если вам что-то не понятно, не стесняйтесь задавать свои вопросы в ЛС Discord или ниже в комментариях.
    2 балла
  41. В этой статье мы с вами создадим внутриигровой Радар Внутриигровой радар в этой игре работает по следующему принципу: Отображать союзников время отображения == время жизни союзника. отображение == всегда дальность отображения == зона видимости радара Отображать противников отображение == иногда время отображения при визуальном столкновении столкнулись вы == время отображения 5с столкнулись союзники == время отображения 3с при вооруженном столкновении столкнулись вы или любой союзник == время отображения 10с столкновения не было, противник стрелял == время отображения 3с дальность отображения == зона видимости радара Наша задача в том, чтобы противники всегда отображались на радаре, не зависимо от того, были столкновения / стрельба или нет. В этом нет ничего сложного.Нам просто нужно получить необходимые смещения, указатели, получить итератор сущностей, перебирать их в цикле и отображать на радар, указав время отображения. Класс IGameFramework выглядит теперь вот так: Класс IGameRules: Класс IActorsystem: Класс IEntity: Класс IEntityIterator: И самое простое во всём этом: Если вам что-то не понятно, не стесняйтесь задавать свои вопросы в ЛС Discord или ниже в комментариях.
    2 балла
  42. В этой статье, мы с вами создадим функцию для отключения задержки анимации игрока. Это позволит вам выполнять так называемый "Спам Х", "Спам CTRL" и "Движения лягушки", т.е выполнять данные движение лечь - встать движение присесть - встать движение вправо-влево (стрейф) движение лежа - в правый бок / левый бок движение лежа - вперед / назад действия без какой-либо задержки. Добавим в наш код новые смещения В итоге, мы имеем такой набор смещений Добавим в перечисление CvarOffsets новые значения Теперь наше перечисление со смещениями, выглядит так Пишем функцию, для отключения задержки анимации игрока Если вам что-то не понятно, не стесняйтесь задавать свои вопросы в ЛС Discord или ниже в комментариях.
    2 балла
  43. В данной статье мы с вами создадим АнтиАфк. Cуществуют разные проверки, в том числе активен игрок в данный момент или нет. Если игрок находится в созданной комнате и не активен в течении 90с(это значение меняется каждое обновление), то он автоматически исключается из комнаты и на его место может зайти другой игрок. Однако, у него сохраняется возможность заново присоединиться в комнату, из которой его исключили за бездействие. Также, помимо проверки активности игрока в комнате, существует проверка игрока в любом бою, будь то PvP матч или PvE миссия. Если в бою игрок не активен более 120с(это значение меняется каждое обновление), то система автоматически исключает его за бездействие и присоединиться в бой, из которого его исключили он уже не может. Проверки осуществляются в 2 этапа. Первая проверка локальная и её можно просто отключить. Вторая проверка зашита в античит и чтобы отключить её, нужно отключить IN-GAME античит или передавать необходимые значения. Если вы просто отключите проверку, IN-GAME античита, вы получили бан в течении 10 минут. В данной статье, мы будем передавать нужные нам значения, а отключение IN-GAME античита мы осуществим в одной(или двух) из будущих статей. Для того, чтобы обойти эти 3 проверки, нам нужно просто получить указатель на нашего игрока, отключить локальную проверку активности и установить нужные значения на проверку от античита. Адрес ICvar вы найдётё вот так: С остальным, у вас не должно возникнуть проблем, т.к мы уже изучали поиск всего необходимого для создания этого проекта. Если вам что-то не понятно, не стесняйтесь задавать свои вопросы в ЛС Discord или ниже в комментариях.
    2 балла
  44. Наткнувшись на тему вспомнил, что не все написал. В прошлом посте блога рассматривал бряк через DBVM. К сожалению, та версия dbvm из поста блога пропускала очень много инструкций и практически смысла нет её юзать. Например она определяла 16 инструкций, когда их было несколько тысяч, т.е. например 500 оффестов и на каждой по 10 инструкций. По DBVM надо, конечно, писать Дарк Байту, но желания нет. Так вот. Не только с DBVM можно ставить бряки на участок памяти. Есть еще тип брейкпоинтов page exceptions. О нем давно-давно известно и он как на ладони, но почему-то я пропустил его, когда искал оффсеты в структурах С ним можно работать с lua и без. Ловит огромное количество инструкций. Желательно мощное железо, т.к. игра скорее всего будет очень тормозить по 2-5 fps. Но на короткий запуск сойдет. 5 секунд и достаточно для снятия логов. На пару действий в игре тоже сойдет: выстрел или пермещение персонажа, прыжок или вообще ничего не делаем просто снимаем логи. 1) способ поставить бряк из окна памяти. Подопытная программа "Tutorial-x86_64.exe" Здесь видно, что размер 720 байт Логи из окна инструкций CE 2) Способ через Lua (подробнее в документации) debug_setBreakpoint(structure_address, sizeMemory, bptAccess, bpmException, onBreakpoint) P.S. Я написал про два способа установки брейкпоинта на множество адресов без DBVM. Вручную можно ставить такие брейкпоинты, но дальше уже кропотливый просмотр на предмет того чем это может помочь. Это может помочь определить типы данных и помочь прикинуть размер структуры, а также найти активные оффсеты. Можно на Lua автоматически определять активные offsets по базовому адресу структуры и эту структуру создать и заполнить в dessectData. Если будет время напишу скрипт.
    2 балла
  45. Так, давно что-то ничего не писал в блог Собственно время пришло Данная статья является примером метода о котором рассказано в данном видео Рассмотрим вызов игровой функции на примере перовой части игры Dishonored В данном примере будем восполнять себе количество маны, которая в игре не может регенерироваться полностью после использования череды способностей Для начала нам необходимо найти само значение маны, благо оно храниться 4мя байтами в памяти и тут нет ничего сложного Теперь когда у нас есть адрес маны или же указатель на данный адрес, нам необходимо найти метод который как раз и перезаписывает значение Делается это очень просто (F6) Нас интересует инструкция которая перезаписывает значение 1 раз Выходим на эту инструкцию в дизассемблере и ставим брейк Вот мы и нашли инструкцию, далее просто выходим из него (Кнопка Execute till return) Для того чтобы вызвать метод, необходимо узнать и проанализировать его параметры. Этим и займемся В метод передается 2 параметра, один из которых находится в ecx (Указатель на базовый класс) А второй передается в регистре ecx, до инструкции которая перезапишет значение Данный кусок: push ecx mov ecx,esi Регистр edx содержит все время один и тот же не изменяющийся адрес, т.е он статичен Распишу параметры чтобы было более нагляднее push ecx (Значение 50 в данный момент) mov ecx, esi (В ecx записывается значение из esi (0x0AD0A000)) Теперь если немного проанализировать, то можно понять что 50 - это значение маны, которое будет присвоено игроку после применения способности А 0x0AD0A000 это указатель на начало структуры игрока, т.е PlayerController* player; Таким образом метод выглядит так: ManaMethod(PlayerController* player, int ManaOut); Теперь можно приступать к написанию самого кода на c++, чтобы вызывать этот внутреигровой метод (При этом заранее найдем работающий указатель на класс игрока PlayerController) Для вызова метода нам необходимо определить его соглашение о вызове, т.е в каком порядке туда передаются аргументы Посмотреть все соглашения можно тут https://ru.wikipedia.org/wiki/Соглашение_о_вызове Немного почитав можно увидеть что это соглашение __thiscall thiscall — соглашение о вызовах, используемое компиляторами для языка C++ при вызове методов классов в объектно-ориентированном программировании. Аргументы функции передаются через стек, справа налево. Очистку стека производит вызываемая функция. Соглашение thiscall отличается от cdecl соглашения только тем, что указатель на объект, для которого вызывается метод (указатель this), записывается в регистр ecx. В самом коде объявляем этот метод для его вызова далее //Метод принимает PlayerController* и ManaOut //0x00AB17C0 - адрес которых хранился в edx и он статичен typedef void*(__thiscall * _ManaType)(PlayerController* Player, int Mana); _ManaType ManaFunc = (_ManaType)(0x00AB17C0); Остается только написать вызов этого метода и на этом дело будет сделано /*PlayerConroller.h */ struct PlayerController { public: char pad_0000[2656]; //0x0000 int Mana; //0x0A60 }; /*Метод который вызывается при создании потока из dll*/ void onAttach() { while (true) { if (GetAsyncKeyState(VK_END)) { PlayerController* Player = reinterpret_cast<PlayerController*>(*(DWORD*)(Base + 0x01052DE8)); //Получаем указатель на игрока PlayerController* ManaFunc(Player, 100); } Sleep(150); } } Собственно на этом моменте статья закончена При нажатии на кнопку END внутри игры, мана восполняется до 100 единиц
    2 балла
  46. Вдохновение появилось после просмотра видео @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 (в новой версии появилось окно диаграмм)
    2 балла
  47. На днях решил с самого чистого нуля написать хук для Directx 9. Чтобы было хоть какое-нибудь отображение для пользователя внутри игры Собственно идея зародилась, осталось только воплотить Хук поддерживает Режим в окне / Полноэкранный Использование EndScene и библиотеки для рисования самого меню. Использованная версия игры: Metal Gear Rising - Revengeance v2, таблетка от Skidrow Пара скриншотов самого меню, все получилось довольно ярко На момент тестирования багов и вылетов не обнаружил. Для написания ф-ий и самого хука были использованы MS Detours. Вполне возможно что функционал я буду еще доделывать, постепенно Но это в том случае, если не переключусь на игру поинтересней Ну и конечно же видео
    2 балла
  48. Довольно интересная функция, мне понравилась. showSelectionList() позволяет просмотреть список класса Strings и выбрать свойство через список. Как пример посмотрим список свойств главной формы и выберем любое свойство local mainForm = getMainForm() local listProperties = getPropertyList(mainForm) local allowCustomInput = false local id, name = showSelectionList("Title", "Caption", listProperties, allowCustomInput) print ('Index: '..id..", Name: "..name) --> Примеры выполнения: --> Index: 55, Name: ShowHint --> Index: 10, Name: Top После исполнения Lua скрипта вот такой диалог появится. Можно искать свойство через ввод текста Список строк (Stringlist Class) используют: createStringlist(): Strings - постой список getAutoAttachList(): Strings - список имен процессов для автоподключения getPropertyList(class) : Strings - список свойств getCommonModuleList(): Strings - список пропускаемых при сканировании модулей getProcesslist(Strings) - список процессов getWindowlist(Strings) - список окон getThreadlist(Strings) - список потоков Database.Params: Strings - свойство базы данных SQL ListItem.SubItems: Strings - свойство подстрок в визуальном компоненте списка ComboBox.Items: Strings - комбобокс Memo.Lines: Strings - мемо компонент RadioGroup.Items: Strings - компонент RadioGroup ListBox.Items: Strings - компонент ListBox FileDialog.Files: Strings - выбранные файлы в диалоге
    2 балла
  49. Я обратил внимание на следующие поведения записи и чтения 1. Срабатывают только инструкции чтения до изменения параметра, адрес рабочий С адресом работают инструкции на чтение, но если в друг в этом адресе что-то поменять (например в CE), тот тут же выскочат инструкции на запись. Нельзя однозначно утверждать, что адрес является настроечным параметром, но и нельзя утверждать, что это не рабочий адрес. Какая-то инструкция может жестко менять значение, а может быть будет "стараться" изменить значение адреса в меньшую или большую сторону, но адрес при этом будет рабочим. 2. Срабатывают инструкции записи и чтения, адрес не рабочий Запись и чтение влияет только на часть игры, а не на все или вообще не влияет, а перезаписывается постоянно. Например, на визуальное отображение полоски со здоровьем. Получается, что адрес не рабочий, а у него есть как и в первом пункте инструкции и на запись, и на чтение. 3. Один раз срабатывает инструкция записи и потом всегда на чтение Если попался такой адрес в структуре, то он точно является "настроечным" и рабочим адресом. Например, это какой-то коэффициент, который добавляет, умножает, отнимает... в общем что-то меняет. Что с ним не делай, это адрес будут только "читать". Также это может быть булевой параметр "1 "или "0" и по нему может что-то резко меняться в игре. Окей. Вспоминается окно с кучей инструкций и счетчиков уникальных адресов (не более 8-ми логируется) Постреляв патроны с адресом патронов (в СТАКЛЕРЕ Зов Припяти) сработали инструкции как на запись, так и на чтение. Первая инструкция читает очень часто, вторая редко. В круглых скобках обозначаются количество проскакивающих адресов. Если был выстрел и значение поменялось, то вылезли инструкции записи (все после первых двух). Код читает в цикле адрес...и если, что поменялось, то запишет в него потом. Это похоже на пункт1, который обсуждали выше, но этот адрес патронов не тот, который нужен. С виду рабочий, но патроны потом не стреляют. Патроны это структуры в памяти, а адрес их как счетчик структур Как можно делать Создаем две группы (скрин ниже). Первая текущая и не замороженная. Вторая с двумя замороженными состояниями, когда стоим и ничего не делаем. Делаем несколько выстрелов. Цвет по +AC нас интересует больше всего, он соответствует логике состояний (стреляю и (не стреляю и не стреляю)) Выделяем и перемещаем адреса этого цвета и морозим в таблице. Первый праметр это прочность, второй не знаю. Третий счетик патронов. 3 и 5 адреса связанные, если правильно помню, с объектами патронов В Сталкере это не даст беск. патрнов, но в других играх может иметь смысл как прием сравнения структур и групп. p.s. По Сталкеру Зов Припяти, к сожалению, у меня не было времени взломать патроны или может быть я не умею, не знаю. Какие-то патроны в сталкерах ломал, но не помню как.
    2 балла
×
×
  • Создать...

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

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