Лидеры
Популярный контент
Показан контент с высокой репутацией 18.08.2015 во всех областях
-
[terminus]-------------------------------------------------------------------------------- Я начал писать курс статей, рассказывающих и показывающих про язык ассемблера с абсолютного нуля. Тут будет оглавление со ссылками на статьи. Оглавление: ---------- Часть 0. [Установка и настройка] Часть 1. [Пишем первую программу] Часть 2. [Как работает процессор и что такое регистры] Часть 3. [Знакомимся с отладчиком] ------------------------------------ Весь исходный код можно взять [тут]. Критику, отзывы, мольбы о помощи и пожелания можно оставлять в этой теме. --------------------------------------------------------------------------------[/terminus]1 балл
-
Более полные справочники: [ENG] 64-ia-32-architectures-software-developer-vol-2a-manual.pdf 64-ia-32-architectures-software-developer-vol-2b-manual.pdf Instruction_Set_Reference.pdf CE ASM Basics 1 (*new) CE ASM Basics 2 (*new) CE ASM Basics 3 (*new) [RU] Архитектура x86 (*new) CPU FPU SIMD (MMX, SSE, SSE2, SSE3, SSSE3). Рассмотрим основные инструкции. Инструкции можно разделить на три блока * CPU (работа над целыми числами), * FPU (работа над вещественными), * SIMD инструкции (работа с массивами чисел). CPU (окно регистров) CPU(основные команды): FPU (окно регистров) Основные FPU(команды): SIMD(окно регистров) Эти регистры встречаются довольно редко и в основном в играх стратегиях, т.е. в играх в которых участвует большое количество объектов (юнитов, зданий, и т.п.) Про эти регистры вы можете посмотреть здесь, если будет нужно.1 балл
-
ООП состоит на основе трёх концепций: инкапсуляция, наследование и полиморфизм. Но модель ООП на этом не заканчивается. В каждом отдельном языке программирования добавлены свои "прибамбасы" относительно наследования и полиморфизма, что формирует модель ООП соответствующую языку программирования. Из всех языков которых я знаю или сталкивался С++ и его продолжения наиболее сильные в ООП. О концепциях ООП Тоже самое в IDA рис. 3 А вот так выглядит в псевдокоде рис. 4 При обмане игр у нас не будет исходника С++ и нам нужно научится понимать псевдокод. Сделаем немного понятнее псевдокод. Нажмём shift+F9 и опишем структуру класса Player с 3*4 байт рис. 5 Затем в псевдокоде нажмём на Y и определим тип структуры: рис.6 И получим более лучшее представление псевдокода Рис.7 И ещё давайте посмотрим, что будет если мы не иницилизируем некоторые данные объекта. рис 8 Результат такой: рис 9 Переменные x1.x2.x3 не инициализировались и остался мусорный код выделенной памяти. Когда выделяется память, то она не «подчищена», если вы не знали. Подведём итог. Познакомились с С++ (если не были знакомы) увидели на простом примере как оформляется структура объекта в С++ и как она выглядит в памяти и в псевдокоде. Увидели как псевдокод облегчает анализ игровых объектов. Главное научиться проводить аналогии между псевдокодом и дизассемблерным кодом для того чтобы представить как устроен объект. Если у вас возникли трудности в С++ то существует много информации в Интернете, которую вы можете легко найти самостоятельно. Часть2. Дальнейшее исследования игрового объекта в памяти Виртуальные функцииВиртуальные классы и множественное наследование 3.1 Виртуальные функции. Если вы не сталкивались с полиморфизмом ни разу и вообще с ООП знакомы мало, то понять эту тему будет, скорее всего, сложно. Виртуальные функции это одинаково объявленные функции в иерархии наследования, которые позволяют работать с данными объекта в контексте нужного класса. Объяснил как смог.. =) Очень важно понять, как это работает для исследования игровых объектов в дальнейшем, т.к. виртуальные функции попадаются сплошь и рядом. Разберём пример «на пальцах», показывающий выгоду виртуальных функции перед похожими, но не виртуальными одинаковыми функциями. Программа перемещает графические объекты по нажатым клавишам клавиатуры, но писать мне её некогда, поэтому разберу основное. { int x,y; public: Dot() {x=100; y=100;} // просто зададим координаты по умолчанию void show(){сделать пиксел белым}; void hide() {сделать пиксел черным}; void move (int dx,dy){ hide(); x+=dx; y+=dy; show()}; };class Dot Мы создали класс Точки, у которой описаны координаты положения и описаны функции перемещения с угасанием и отображения точки. Ключевое место здесь в том, что в функции перемещения присутствуют локальные вызовы угасания и отображения точки. Именно из-за локальных вызовов появится проблема в производном классе, т.к. в базовом классе будут вызываться свои локальные функции с тем же именем. Выходом будет определение виртуальных функций. Рассмотрим эту проблему. { int radius; public: Ring () {radius=200;}; //зададим радиус круга по умолчанию void show(){сделать окружность белой}; void hide(){сделать окружность чёрной}; };class Ring: public Dot Видим, что Круг наследует функцию перемещения, в которой происходят локальные вызовы hide и show. Т.е. если мы зададим движение Кругу, то двигаться будет Точка, т.к. вызываются локальные функции в контексте класса Точки. Ring *ring=new(Ring); ring->mov(50,60); // вызовет перемещение только точки,а не круга Чтобы решить эту проблему был введен механизм виртуальных функций. Вызов той или иной функции задается смещением (генерируемым компилятором), по которому в созданной таблице виртуальных методов (vftable) выбирается нужная функция, которая и вызовется. { int x,y; public: Dot() {x=100; y=100;} // просто зададим координаты по умлочанию virtual void show(){сделать пиксел белым}; virtual void hide() {сделать пиксел черным}; void move (int dx,dy){ hide(); x+=dx; y+=dy; show()}; }; class Ring: public Dot { int radius; public: Ring () {radius=200;}; // также просто зададим радиус круга void show(){сделать окружность белой}; void hide(){сделать окружность чёрной}; };class Dot Теперь ring->mov(50,60); // вызовет перемещение только круга в заданные координаты 50 и 60 ring->Dot::mov(50,60); // этот метод в принципе бесполезный, т.к. координаты точки уже были равны 50 и 60Ring *ring=new(Ring); Вызывать метод перемещения точки было не обязательно, главное то, что круг наследовал координаты x и y и можно и нужно перемещать только круг. Однако, если вы вызовете ring->Dot::mov(100,100), то это распространится и на круге... т.е. и точка и круг взаимосвязаны и буквально слеплены в одно целое как в симбиозе (кто биологию хорошо знает? ) Как мы увидели механизм «виртуальных функций (полиморфизм)» нужен для правильной работы с данными объекта в требуемых контекстах его описывающих классов. Чаще всего виртуальные функции объявляются без входных параметров, таким образом, их применение наиболее удобно и более расположено к полиморфизму. При полиморфизме в статичной области кода возникает таблица виртуальных функций vftable. Указатель на таблицу виртуальных функций находится по первому адресу объекта (см. рис. 1) рис. 1 Следует отметить, что vftable характерна только для определённого типа класса. Если вы найдёте в памяти игры адрес таблицы виртуальных функций (vftable) некоторого объекта и затем в сканере памяти найдёте 6 указателей на ту же vftable, то можете считать что вы «вышли» ещё на 6 объектов, которые наследовали vftable класса или некоторой иерархии классов. Соответственно по указателю на vftable в чит-кодах можно делать фильтры по изменению данных игровых объектов построенных по описанию конкретного класса или по описанию классовой иерархии. Учитывая всё выше известное, напишем программу с игровыми объектами и проанализируем формирование объектов с vftable. Результат программы будет таким. рис. 2. (Координат нет, это вы поймете на рис 6 ) В данной программе и в случае, кода виртуальные функции наследуются, то vftable сильно усложняется. Нам будет очень полезно рассмотреть случай ниже для обмана игр. Сначала посмотрим расположение данных двух объектов, после того как мы их заполнили. Так мы увидим данные после того как CE сама расструктуризовала их. рис. 3 Как мы видим, структуры объектов заполнены непонятными данными по смещениям 0x18-2С, 4C-0x64, 0x68-0x6C. Адреса по этим смещениям рассмотрим позже. Сейчас важно понять, как устроены таблицы на рисунке по смещениям 0x0, 0x30 и как они работают. Они выглядят вот так (так как и расструктуризавала CE) рис. 4 Для удобства переведём эти значения в hex- вид рис. 5 Я пока не знаю, правильно ли я определил, что по смещению 0хС значение 0х48 указывает на конец таблицы виртуальных функций в контексте всей иерархии классов... 00401017 – это указатель на функцию Player:: GetInfo 0040102B – это указатель на функцию Building::GetInfo Обращение к указателям компилируется в коде (вы это можете посмотреть в дизассемблерном листинге ниже), т.е. в объектах не содержится данных о том к какой именно функции, в каком описании класса в какой момент обращаться. Залезем в псевдокод в функцию main, т.к. именно по нему нам надо учиться обманывать игры и смотрим рис 5 и рис.6 В псевдокоде смещения в структурах объектов десятичные,но там не сложные числа можно перевести в 16-ричную систему в уме для того чтобы соотнести смещения структур на рис. 5 рис. 6 GetInfo в контексте класса control не сработала, из-за виртуальных функций, так и должно быть. Псевдокод показывает всё что необходимо и это гораздо нагляднее, чем смотреть дизассемблерный код в отладке. Для интересующихся (маньяков) привожу дизассемблерный код. Комментировать не буду, т.к. основное всё разобрал. Скопируйте его в отдельное место и можете тщательно разобраться как что и куда. С виртуальными функциями более менее познакомились. Возможно, в следующих статья разберём ещё более тяжёлые случаи (адские ) Продолжение следует. В следующей частях возможно будет рассмотрено. Множественное наследование. Виртуальные функции при множественном наследовании. Виртуальное наследование классов. Виртуальные функции при виртуальном наследовании классов. Статичные данные и функции в объектах. Дружественные функции в объектах. Массивы объектов. Объекты по шаблону. Объекты по стандартному шаблону . Сообщения. Методы дизассемблирования и отладки. Объекты совместно с lua – интерпритатором. Создаём объекты через конструкторы и команды lua. Обход антиотладочных ловушек xlive. Распаковка игровых ресурсов. Обман flash игр. Обман .NET игр. Обман JAVA игр. Обман эмуляторных игр, поиск нулевого адреса.1 балл
-
Название: Terraria.v1.3.0.7 RUS Добавил: LIRW Добавлен: 17 авг. 2015 Категория: Трейнеры для PC игр Бессмертие. Бесконечные предметы. Бесконечный кислород. Бесконечная мана. Супер скорость. Супер прыжок. Непобедимость. Замедление падения...( это для того что бы не разбиться летая как гастелло) Можно падать с большой высоты не разбившись - осторожно правда спускаться, он как на парашюте. Версия игры 1.3.0.7 а руссификатор брал на плейграунде для этой версии. P/S Клавиши в трейнере переназначил на numlock из за совпадения с игровыми. Нажмите здесь, чтобы скачать файл1 балл
-
На русскоязычном форуме Юнити разработчик этой игры написал, что там авторитарный протокол и все расчеты на сервере. Он не уточнял какие расчеты на клиенте и какие на сервере. Но мне кажется на сервер отправляются данные ввода от клавы и мышки. Положения и попадания по коллизиям вычисляются на сервере. Наверно, все что можно это отправлять оси "X,Y мышки" и нажатие на кнопки. float h = horizontalSpeed * Input.GetAxis("Mouse X"); float v = verticalSpeed * Input.GetAxis("Mouse Y"); Но их надо рассчитывать лучше чем это делает мозг глядя на экран монитора и двигая рукой мышку... А поскольку игра написана на Unity3d и все API доступны, то собрать .net модуль с отправкой осей мышки и её кнопок. Тот же рейкаст гораздо удобнее делать C# и функциям движка, там несколько строчек кода. Дистанция: Vector3.Distance Направление вектора: отнять дальний вектор позиции от текущего вектора позиции var heading = target.position - player.position;О том как внедрять код .net сборки я писал здесь (Внедряем свою dll-ку в игру на Unity3D с помощью CE AA). Ты уж извиняй, что готового кода нет и ломать нет желания Помог чем смог, да и то, моя инфа настолько простая, в качестве мелкого демо по работе игр на движке Unity3d.1 балл
-
Как найти идентификатор игрока ( ID players ) Это нужно когда одна инструкция работает с адресом к примкру нашего здоровья и адресами здоровья врагов.. И нужно для написания скрипта с фильтром.. для нашего здоровья.. и не только... На примере игры Magicka + Magicka.Vietnam.v 1.3.6.01.Поиск адресов. Для начала найдем адреса здоровья.. ( Свой и двух или трех врагов.. ) Подробнее об этом....1 балл
-
VirtualAlloc / HeapAlloc / malloc / new Первый вариант объяснения: Второй вариант: Тот кто усвоил - молодец.1 балл
-
1 балл
-
В системе Windows есть объекты ядра и ИХ описатели. Последние чаще называют дескрипторами, "хендлами", "hadle(s)". Вот пример использования хендла типа Окно (тип HWND): int WINAPI MessageBox( __in_opt HWND hWnd, __in_opt LPCTSTR lpText, __in_opt LPCTSTR lpCaption, __in UINT uType ); Сразу напрашивается расшифровка этой абривиатуры HWND. H- handle , WND - window. Получаем handle window. Для чего нужен этот описатель для казалось бы независимого диалога MessageBox?! Идём в справку MSDN и смотрим: A handle to the owner window of the message box to be created. If this parameter is NULL, the message box has no owner window. Оказывается этот параметр, если его указать, свяжет мессагу и описатель HWND. У мессаги появится "хозяин"... Если окно закроется, то и мессага закроется... Разбирать эту связь я не буду, кому надо глянут. Это был просто пример. Описатели или дескрипторы это структуры данных. Используются в работе разных режимов. На Windows cуществует два режима. Режим Ядра и "Пользовательский" Ошибки на уровне Ядра покажут вам Синий экран. Ошибки на Пользовательском уровне должны привести максимум к закрытию пользовательского приложения. "Должны" это не значит, что так и будет, но на все 100% нельзя быть уверенным. "Режим пользователя" это программирование на WinAPI где мы работаем с дескрипторами Пользовательского режима (а система в свою очередь обрабатывает эти дескрипторы работая с объектами ядра), и если что-то на этом уровне Пользователя пойдёт не так, то в предположительно в худшем случае ваше приложение закроется с критической ошибкой. "Режим ядра" это тот режим на котором писать программы очень "мерзко", если что, то синий экран. Если опять что-то, то опять синий экран. При чем компьютер после перезагрузки может не запустить операционную систему... Итак. В Пользовательском режиме Хендлы или дескрипторы это номера, по которым идентифицируются структуры данных в системе. Эти структуры разного размера в зависимости от названия типа хендла. Эти структуры созданы для взаимодействия процессов Пользовательского уровня в обход уровня Ядра. Более подробнее читаем Рихтера. Глава3.1 балл
-
Ссылка на необходимую краткую информацию по режимам. Кратко написаны функции режимов. Разделение обязанностей юзер- и кернел-модев на рисунке. Я не думаю, что стоит заморачиваться на режимах больше чем нужно. Возможно в нашем деле это потребуется тогда, когда, например, нужно писать в память процесса через кернел-режим, если сделать это обычными способами будет невозможно из-за защит.1 балл