MasterGH

Курс для новичков

22 сообщения в этой теме

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

Вы можете пойти по следующим путям:

1) писать скрипты для CE (Cheat Engine)

2) генерировать трейнеры на CE,

3) можете писать трейнеры на языке программирования.

Во всех трёх направления на нашем форуме (если поискать) есть как простые примеры, так и очень сложные. Лучше всего начать со справки Артмани и использовании самой этой программы. Затем установить Cheat Engine и подробно смотреть и читать следующие темы:

1) Взлом денег Mafia 2(видео) + поищите видео или информацию создания трейнера на Cheat Engine

2) Туторы по CE Autoassembler Engine;

3) Devil May Cry 4 (видео)

4) Grand Theft Auto Vice City, метод указателей (использовалась TSearch, но вы должны всё понимать как если бы это было CE )

5) Везде полазайте по форуму Информации по Cheat Engine

6) Внедрение чит-кодов Medieval 2: Total War

7) Ну и чиаем всё что найдёте у нас на сайте и на форуме.

Для более опытных переходим на LUA Engine в CE для создания трейнеров.

Дело ваше, но я все-таки я рекомендуемую развиваться в LUA Engine в CE по направлению дизассемблирования и ассемблирования во время игры по адресам сигнатур байткода. CE это большая сформированная функциональная база. Можно ей пользоваться чтобы дойти в ней до высокого уровня создания читов, а уже потом можно писать оптимизированные свои трейнеры и на C++ и на других языках...

 


Термины

 

Скрытый текст

Опкод (Operation Code) - часть инструкции, равная одному байту

Ноп (Nop - Noop) - опкод "пустой", ничего не делающей инструкции. Используется для выравнивания оригинальных инструкций при создании Code Cave.

Нопить - забивать какую-либо инструкцию нопами (nop).

Типы данных - прежде всего тип данных обусловлен размером количества единиц информации битов или байтов. Затем процессор может их воспринимать как знаковое число, целое число, вещественное число или как текст.

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

Статический адрес - адрес в памяти, который не меняет своего положения в памяти игры. Виден как зелёный адрес в Cheat Engine и MHS. Находится в регионах памяти с типом Image.

Динамический адрес - адрес в памяти, который меняет своё положение в памяти игры после некоторого события.

Цепочка указателей - указатель на указатель больше чем одного уровня. Представление цепочки указателей обозначается фигурными скобками. Пример f[[game.exe+0x6454]+5*54h]. Более подробно в справке MHS.

Структура - структура это набор данных. Главные параметры структуры: есть начало и конец, соответственно размер. В структурах могут быть данные как одного типа так и разных.

Расструктуризация - раскрытие характеристик определённых структур данных при которой становится известно, на каком смещении от начала структуры какие данные находятся. Например, здоровье находится на смещении +0x48, от начала структуры или начала структуры объекта.

Объект (игровой объект) - объект можно воспринимать буквально как явление, предмет, на к-рый направлена чья-н. деятельность, чье-н. внимание (книжн.) . Объект в программировании или при обмане игр, когда речь идёт об инструкциях работающих с объектами стоит воспринимать как структуру данных в памяти, которая отражает поведение некоторой абстрактной сущности. Например, юнита в игре можно реализовать как объект на основе описания класса юнита. Объект наполняется данными по описанию класса, также к данным по смещениям от начала структуры объекта "привязываются" методы. Таким образом методы будут работать с некоторым объектом на основе описания класса.

Класс - это описание данных и методов объекта. На описании класса реализуются объекты или один объект. Класс также является типом.

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

Массив данных - массив представляет однотипную структуру данных. Например, массив байт или массив некоторых объектов.

Отладчик - обычно, включает в себя также дизассемблер. Позволяет ставить брекпоинты, снимать показания регистров изменять регистры и т.п.

Брейкпоинты - точки остановки программы. Можно поставить на адрес на чтение и запись. Можно поставить на инструкцию. В результате остановки игрового процесса можно снять показания регистров. Брейкпоинты бывают также условные, которые выполняются при определённых условиях (см. правку по ollyDbg)

Дизассемблер - позволяет перевести байт-код в ассемблерное представление. Ассемблер - язык программирования, самый близкий к машинному.

Регистры - информацию по регистрам смотреть в Интернете или у нас на форуме. Своими словами это операнды, которыми оперирует процессор, выполняя те или иные инструкции.

Инструкции - или ассемблерные инструкции, также смотреть в Интернете или у нас на форуме. Дизассемблированные инструкции отражают какую-то операцию происходящую в игре. С помощью программ CE, MHS можно изменять инструкции изменяя поведение игры и её игровых объектов.

Часто обращаемая инструкция - инструкция которая срабатывает очень часто (можно определить по хит-ам при срабатывании бряка).

Определение адресов на инструкции - определение результирующих адресов с которыми происходит работа. Например, есть инструкция mov eax, [ecx*4 + 64]. В квадратных скобках может проскакивать множество адресов, которые можно определить средствами CE или OllyDbg.

Классификация инструкций сработавших при брейкпоинте.

-Тип А

Данная инструкция работает с некоторым единственным параметром только определённого игрового объекта.

Например, здоровье от структуры находится по смещению +155. Инструкция А, работает только с этой структурой, только со смещением +155.

-Тип B

Эта инструкция работает с параметрами двух и более объектов, параметры которых находятся по одинаковым смещениям.

Например, у нас шесть объектов - игроков, у которых по смещениям +155 находится здоровье. Инструкция типа B получает указатель на начало некоторой структуры объекта игрока, прибавляет смещение +155 и работает с параметром (читает параметр из адреса или пишет в адрес). Таким образом, инструкция типа B может отнимать здоровье у героя, а также отнимать здоровье у врагов.

-Тип С

Данный тип инструкций может работать с данными находящимися не по одному (как при типах А и В), а по разным смещениям относительно одной или более структур. Стоит не путать тип А с С, т.к. инструкция А работает с одним смещением, тоже самое касается и B.

Отсюда мы получаем подтипы:

C(А) - работает с разными смещениями одной структуры (объекта);

C(B ) - работает с разными смещениями более одной структуры (объекта).

Часть 1. Редактирование параметра по адресу

 

Скрытый текст

Чтобы приступить к делу надо начинать с малого, а именно полностью разобраться с Artmoney. В чём нужно хорошо разобраться новичку читая справку Артмани.

1) Разобраться в типах данных:


  • [*:1ppxw1g7]Что такое 16-ричная система.
    [*:1ppxw1g7]Какие типы данных существуют, что обозначают.
    [*:1ppxw1g7]Какие типы данных следует выбирать при поиске, а не выбирать все подряд.

 

2) Разобраться в правилах поиска адресов и указателя.

3) Разобраться, что такое указатель на адрес.

Разобравшись во всём этом на множестве игр вы можете на этом остановиться, но у вас часто будут проблемы из-за многоуровневых указателей. В Artmoney поиск указателя, не очень удобен так как в ней нет отладчика. Если вы хотите чтобы ваш "обман" работал на принципе "включить чит/выключить чит" даже с самыми сложными указателями, то переходим на инструменты по мощнее чем ArtmoneyPRO, т.е. переходим на CheatEngine, MHS и OllyDbg.

Заметки.

Если с Артмани всё понятно, то стоит слега объяснить какой приоритет пользования у программ CheatEngine, MHS и OllyDbg.

CheatEngine является основным инструментом для внедрения чит-кода. У отладчика CheatEngine есть ряд неудобств которые компенсируются OllyDbg. MHS полезна в ряде случаев: различных приёмов поиска, встроенные калькулятором, конвертером знаковых и беззнаковых чисел и другими. Но MHS оставляет впечатление огромного функционального гиганта, по сравнению с малым CheatEngine в котором необходимые и достаточные функции более удобны к приминению.

Каснёмся такой сложной темы как поиск указателя в Артмани. Многоуровневые указатели Артмани оформлять научилась, а вот искать может только одного уровня.

[[Указатель]+смещение]=значение.

Многоуровневый указатель может быть вида [[[[xrGame.dll+5f5b54]+94h]+4]+388h], но, к сожалению, Артмани не обладает функции поиска подобных указателей. Данный указатель может помочь найти автоматический поиск в Cheatengine, но с ним нужно уметь обращаться. Надеюсь, методом проб и шибок у вас получится - нужно задать предполагаемый уровень указателя и ширину структур для всех заданных уровней. Из примера выше потребовалось бы задать 4 уровня и размер структуры (388h) переведённую в десятичную систему. Надеюсь, что вы уже прочитали вдоль и поперёк справку Артмани и обманули множество игр. Остановимся более подробно на системах счисления и правилах поиска, а в части 2 лучше вникнем, что такое указатели.

1.1 Система счисления, код и данные

 

Скрытый текст

Наверняка, вы знаете что помимо обычных цифр в 16-ричной (hex) системе присутствуют ещё и буквы A,B,C,D,E,F. Таким образом счёт идёт 0,1,2,3,4,5,6,7,9,A,B,C,D,E,F. Если число состоит из двух и более цифр 16-ричной системы, то дописывают букву «h». Например 24h, 14h… в этом случае понятно, что имеем дело с 16-ричной системой, а также иногда приписывают "0х" например 0x24. Переводить из одной системы в другую и производить расчёты можно в стандартном калькуляторе в инженерном виде удобнее это делать в строенным калькуляторе MHS. На этом с целыми числами закончим.

Другое дело обстоит с вещественными числами, т.е. числами с запятой (точкой). Стандартный калькулятор Windows не умеет работать с вещественными 16-ричными числами. А именно не умеет переводить их в десятичную и обратно. Для этого вы можете использовать программу конвертор Converter или калькулятор MHS.

converteral9.jpg

Converter.rar

Теперь рассмотрим представление кода и данных.

Код

В игре и данные и код оцифрованы в 16-ричной системе. Одни цифры это данные. Другие цифры это инструкции, которые выполняет процессор. Цифры кода можно понять с помощью дизассемблера, который является неотъемлемой частью отладчика. Дизассемблер есть в OllyDbg, CheatEngine, MHS.

Данные

Важную роль играет размер данных именуемый типом данных.

Почти никогда вам не потребуется искать данные бита (встречаются в очень старых игрушках).

1 бит (bit) это 0 или 1. Восемь последовательных бит составляют 1 байт. Поиск/отсев битов есть в CheatEngine.

Чаще всего встречающиеся размеры данных.

1 байт содержит значиния 00-FF или 00-255 в десятичной.

2 байта (word) содержат значиния 00 00-FF FF

4 байта (dword) содержит значиния 00 00 00 00-FF FF FF FF

8 байт ddword - или "двойной дворд", так как "содержит 2 дворда".

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

Данные с точкой содержат не меньше 4-х байтов и 8-ми. Чаще всего это капризные данные, один байт которых может поменяться, а видимое число в игре может остаться прежним.

Из своего опыта могу сказать, что в 32-х разрядных играх чаще всего будут попадаться значения типа 4 байта целое. Чуть реже 4 байта с точкой и ещё реже именно 1 байт остальные типы довольно редко. В 16-ти разрядных играх чаще попадаются данные 2-х байт и байта.

У вас есть программа Converter. С её помощью вы можете выбрать оптимальный тип данных для целых чисел и для чисел с точкой. К примеру с этой программой и какой-то игрой вы можете разобраться раз и навсегда как подбирать тип данных для целого и для вещественного чисел. Я об этом писать много не буду. Приведу только 2 примера наглядно показывающие как меняются байты.

В игре значение денег 456546.

Допустим я могу увеличивать деньги или уменьшать в пределах одного байта.

Значит я буду искать 1 байт.

456546= 06 F7 62

Увеличивать деньги нужно в пределах 1 байта, чтобы число было не больше чем 06 F7 FF, т.е.

456703 = 06 F7 FF

А уменьшать деньги нужно чтобы число было не меньше чем 06 F7 00

456448=06 F7 00

Таким образом промежуток денег видимый в игре при поиске и отсеивании должен быть от 456448 до 456703. Если я найду адрес этого последнего байта, то я смогу узнать адрес денег уменьшив найденный адрес на 3 и присвоив ему 4 байта (или адрес можно установить опытным путём посмотрев карту памяти или поставив брекпоинт в отладчике на этот адрес - об этом позже).

Допустим возникнет вопрос почему нельзя искать сразу 456546 тип 4 байта. Да можно и нужно, я просто показал пример как меняются байты и расширил ваши знания по типам данных.

Теперь по сложнее напримере для чисел с точкой.

Полоска жизней составляет промежуток от 0 до 100.00 (т.е. 00 - 42C80000)

100,0 - 42 C8 0000

99,0 - 42 C6 0000

90,0 - 42 B4 0000

80,0 - 42 A0 0000

70,0 - 42 8C 0000

60,0 - 42 70 0000

Можно видеть что меняется каждый второй байт. А теперь обратите внимание как будет дело с десятыми долями, какие байты меняются а какие не меняются.

100,0 - 42 C8 00 00 - Значение в игре 100

99.9 - 42 C7 CC CD - Значение в игре 99

99.8 - 42 C7 99 9A - Значение в игре 99

99.7 - 42 C7 66 66 - Значение в игре 99

99,6 - 42 C7 33 33 - Значение в игре 99

99.5 - 42 C7 00 00 - Значение в игре 99

99.4 - 42 C6 CC CD - Значение в игре 99

…..

99,0 - 42 C6 00 00 - Значение в игре 99

98.9 - 42 C5 CC CD - Значение в игре 98

Обратите внимание, что отображаемое значение округляется. При поиске нужно искать например не "95.0" тип 4 байта с точкой, а промежуток от 95,0 до 96.

Нетрудно догодаться что 4 байта с точкой можно найти по одному байту, если отображаемое значение в игре будет увеличиваться уменьшаться как минимум через 2 единицы от 100,0 до 32,0

99 - 42C60000

97 - 42C20000

95 - 42BE0000

...

32 - 42000000

Все это понять поможет практика, если хотябы раз в жизни вы будете взламывать кодированные значения. О примерах кодированных значений можно написать много. Я думаю это не так интересно поэтому двигаемся дальше.

1.2 Особенности поиска адресов

 

Скрытый текст

Пример. В игре "50", а на самом деле "50.44". Значит вы ищите от 50 до 51 число 4 байта с точкой.

Пример. В игре "50", а на самом деле на единицу больше "51" или меньше "49". Значит вы выбираете интервал от 49 до 51.

Пример. В игре "50", а на самом деле нужно искать "0,5000000012...". Из-за того что в игре есть такая операция 50/100=0,5000000012...,то рабочий адрес будет со значением "0,5000000012". Такое значение эффективнее искать в MHS,там вы выбираете "float" - вещественное число. Поиск интервалом, уменьшилось/увеличилось/равно 1(при полном значении).

Пример. В игре "50", а на самом деле кодированное. В этом случае описываю способы далее.

Прямая пропорциональность.


  • [*:1ppxw1g7]1. Способ. Изменения на определённую величину.
    Пример. В игре "50", стало "80". А на самом деле было "100", а стало "130"
    Ищу неизвестное. Как стало "80" отсеиваю "увеличилось на 30". Нахожу адрес со значением "130"
    Правило такое: "увеличилось на" или "уменьшилось на".
    [*:1ppxw1g7]2.Способ. Изменения уменьшилось/увеличилось
    Пример. В игре "50", стало "80". А на самом деле было "черт знает что =))) но вы предполагаете что при увелечении кодированное увеличивается, а при уменьшении уменьшается.
    Правило такое: "увеличилось" при увелечении в игре или "уменьшилось" при уменьшении.

 

Обратная пропорциональность.

 


  • [*:1ppxw1g7]1. Способ. изменения на определённую величину.
    Проще объяснить так.
    Если число в игре увеличивается, то ищем уменьшающиеся.
    Если число в игре уменьшается, то ищем увеличивающиеся.
    Пример. Число в игре 50, ищу неизвестное. Стало 80 . Ищу уменьшилось на 30. Но этот пример образно.
    [*:1ppxw1g7]2.Способ. Изменения уменьшилось/увеличилось
    Ну тут, почти также. Только без изменения на определённую величину.
    Если число в игре увеличивается, то ищем уменьшающиеся.
    Если число в игре уменьшается, то ищем увеличивающиеся.

 

Первые в отличии от вторых способов в обратной и прямой пропорциональности позволят эффективнее, т.е. более быстрее найти адрес.

Способ. "Изменилось не изменилось."

Этот способ самый мучительный способ отсеивания. Потому что сопровождается долгими поисками. Применяете его только в последнюю очередь с типами 4 или 2 байта целое. Один байт вряд ли будет. 4 байта с точкой не выбирайте, от этого толку ноль.

Правило: ищите кодированное. Если значение меняется, тогда отсеиваете "изменилось". Не меняется, тогда отсеиваете "не изменилось"

Приколы с несколькими адресами.

Встречал в некоторых играх, например, в CNC.

Прикол в CNC тибериума с деньгами.

Там было два адреса денег(или чего-то там минералов что ли)

1 Адрес =..... (до 3000, вроде)

2.Адрес= ... (любое число в пределах 4 байт)

Пришлось искать 1 Адрес когда минералов было до 3000. Потом когда я увидел несуразность в изменении денег при заморозке Адреса 1, а вы можете её себе представить?! Я замораживаю адрес, а минералы почему-то до какого-то числа могут уменьшаться. И я понял адрес "полурабочий". И когда я исследовал код поставив бряк на 1 Адрес в CheatEngine, только тогда я понял, что есть второй адрес. Вот так. А так бы без CheatEngine никогда бы не догадался.

Приколы с очень длинными данными.

В весьма редких случаях бывает так, что искать нужно 8 байт целое или с точкой. Надо быть к этому готовым smile.gif

Прикол, когда адрес нашёлся, но не работает.

Вам нужно искать другой адрес. Ниже привидён пример.

Пример. В игре "50", а на самом деле нужно искать "0,5000000012...". Из-за того что в игре есть такая операция 50/100=0,5000000012...,то рабочий адрес будет со значением "0,5000000012". Такое значение эффективнее искать в MHS,там вы выбираете "float" - вещественное число. Поиск интервалом, уменьшилось/увеличилось/равно 1(при полном значении).

Т.е. вы искали "50" и нашли не правильный адрес.

Бывают и такие случаи, что вы перепробовали все способы, а адрес по-прежнему не рабочий. В этом случае вступает в дело "реверс инжинеринг". Ставим бряки на адреса связанные со значением в игре и исследуем код в IDA,отладчике OllyDbg, отладчике CE... разбираясь в чём проблема.

Хочу отметить пару важных моментов.

smile.gif

Если нельзя найти указатель?

Поиск указателя не всегда простая задача всё зависит от вашего опыта. С помощью функций CE, таких как: поиск в памяти, определение прервавшихся инструкций на адресе и расструктуризации можно найти указатель повышенной сложности. Чем больше уровней тем труднее поиск. Особенно если адрес включён в свойства объекта из многомерного динамического массива объектов. Прежде всего, это касается таких игр как стратегии... Более подробно о поиске многоуровневых указателей читайте в моих статьях.

1.3 Архитектура Памяти Windows приложений(игр)

 

Скрытый текст

Когда вы редактируете какой-то адрес, то вы, наверно, не задумываетесь, что у этого адреса есть права доступа. Что у адресного пространства есть свои рамки и т.п. Это мы разберём в данной теме.

Рассмотрим чем может быть полезна карта памяти процесса игры.

Виртуальное адресное пространство для 32-рязрядной системы любого приложения занимает от 0x00000000 до 0xFFFFFFFF байт. Или 4 гигабайта с копейками. Для 64-разрядных процессоров от 0x00000000 00000000 до 0xFFFFFFFF FFFFFFFF. Рассматриваем с вами 32-разрядные игры и 32-разрядные операционки. Как обстоят дела у 64-рязрядных пока не знаю. Скорее где-то также.

Если мы посмотрим с вами на карту памяти процесса (напрмер Artmoney или CE), то увидим колонки с атрибутами защиты памяти.

Например:

Адрес, Адрес региона, Размер региона, Состояние региона, Защита региона, Защита, Тип.

Адрес(Address) – адрес

Адрес региона – начальный адрес региона в который входят блоки до размера региона.

Размер региона/размер блока – показан размер региона если это начало региона и блока если это блок.

Состояние региона (State) - состояние региона

Защита региона(Allocation Protect) - Защита региона

Защита блока (Protect) - Защита блока

1. Пункт

Обращаем внимание что блок кратен 1000h байтам, а регион 10000h байтам. Это связано с выравниванием данных – гранулярностью. А у 64-разрядных систем блок кратен 2000h байтам, а про регионы сами посмотрите...

2. Пункт

Состояние региона/блока (State) бывает:

COMMIT – память спроецирована на файл постраничный или файл образа

RESERVE – зарезервирована (но не доступна)

FREE –свободная (высбождена)

3. Пукт Тип региона/блока.

Free

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

Private

Этот диапазон виртуальных адресов сопоставлен со страничным файлом.

Image

Этот диапазон виртуальных адресов изначально был сопоставлен с образом ЕХЕ- или DLL-файла, проецируемого в память, но теперь, возможно, уже нет Например, при записи в глобальную переменную из образа модуля механизм поддержки «копирования при записи» выделяет соответствующую страницу памяти из страничного файла, а не исходною образа файла

Mapped

Этот диапазон виртуальных адресов изначально был сопоставлен с файлом данных, проецируемым в память, но теперь, возможно, уже нет. Например, файл данных мог быть спроецирован с использованием механизма поддержки «копирования при записи" Любые операции записи в этот файл приведут к тому, что соответствующие страницы памяти будут выделены из страничного файла, а не из исходного файла данных.

4.Пункт

Защита региона обычно совпадает с защитой блоков, отличия могут быть, если у блока стековый параметр Guard. И когда у региона параметр перезаписи «Write Copy» (об этом ниже)

Атрибут защиты (регионов и в частности блоков)

PAGE_NOACCESS

Попытки чтения, записи или исполнения содержимого памяти на этой странице вызывают нарушение доступа

PAGE_READONLY

Попытки записи или исполнения содержимого памяти на этой странице вызывают нарушение доступа

PAGE_READWRITE

Попытки исполнения содержимого памяти на этой странице вызывают нарушение доступа

PAGE_EXECUTE

Попытки чтения или записи на этой странице вызывают нарушение доступа

PAGE_EXECUT_READ

Попытки записи на этой сфанице вызывают нарушение доступа

PAGE_EXECUTE_READWRITE

На этой странице возможны любые операции

PAGE_WRITECOPY

Попытки исполнения содержимого памяти на этой странице выбывают нарушение доступа, попытка записи приводит к тому, что процессу предоставляется «личная» копия данной страницы

PAGE_EXECUTE_WRITECOPY

На этой странице возможны любые операции, попытка записи приводит к тому, что процессу предоставляется «личная» копия данной страницы

Общие выводы

1. Вывод

Статичные адреса, которые обычно не меняют своего местоположения это адреса входящие в блоки и регионы памяти IMAGE с параметрами защиты:

PAGE_EXECUTE

PAGE_ EXECUTE_READ

PAGE_EXECUTE_READWRITE

PAGE_WRITECOPY

PAGE_EXECUTE_WRITECOPY

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

Правда у статических адресов возможны и другие состояния, как Commit с защитой Read и типом mapped. Если адрес с типом региона mapped и защитой блока и региона read+write, то на этот адрес вам явно нужно искать указатель.

2. Вывод.

Блок памяти не может быть меньше 1000h байт, а регион не может быть меньше 10000h и всегда соблюдается кратность. Если вы нашли адрес ресурса в игре, то где-то в рядом в этом блоке или в регионе памяти вероятно нахождения другого ресурса. Поэтому нет необходимости искать всю память, достаточно задать параметры поиска в заданном промежутке адресов. Особенно это касается при поиске неизвестного значения.

3. Вывод.

Если тип адреса Image, то убедитесь, что это не подгружаемый модуль dll или файл с другим расширением. Если это так, то вам нужно вместо обычного адреса задавать смещение относительно начала модуля. Пример [[core.dll+1000]+20h]. Если у вас обычный exe файл игры, то всё в порядке можно заголовок игры не писать, например, не писать [game.exe+1000], а просто [401000]

P.S. Вот и вся польза от карты памяти процесса, если кто не знал.

Часть 2. Встраивание чит-кода

 

Скрытый текст

Встраивание чит-кода сложная тема. Перед тем как читать статьи в разделе для продвинутых нужна подготовка. Здесь как раз она и будет.

Мы рассмотрим как работает машинный код с указателями в ассемблерном представлении и вы при этом сможете понять принцип работы ассемблера.

Ассемблер это низкоуровневый язык программирования более понятный человеку чем машинные коды.

2.1 Поиск динамических «бегающих» данных и основы встраивания чит-кода

 

Скрытый текст

Указатели позволяют быстро перемещаться по схожим структурам информации.

Грубое представление указателей

 


2.
3.Структура 1
4.Имя игрока: Игрок 1
5.Жизнь игрока: 65
6.Патроны пистолета игрока : 50
7.
8.Структура 2
9.Имя игрока: Игрок 2
10.Жизнь игрока: 80
11.Патроны пистолета игрока : 10
12.
13. Структура 3







1. «3»(по адресу 1 находится указатель на начало структуры характеристик некоторого игрока)

 

Примичание: как видно все числа я привёл в десятичной системе, а не в 16-ричной и не указывал размер данных. Так, на мой взгляд, новичку проще понять,а по ходу чтения статьи и на практике работы с отладчиком можно будет соориентироваться без особого труда...

Как видно каждая структура содержит свой адрес в адресном пространстве и находится на одинаковом раcстоянни от какой-то базовой точки. В нашем случе базовая точка - это третий адрес. А на третий адрес, указывает первый адрес (!)

Вот что произойдёт когда данные «убегут»

1. «7»

2.

3.

4.

5.

6.

7. Структура 1

8. Имя игрока: Игрок 1

9. Жизнь игрока: 65

10.Патроны пистолета игрока : 50

11.

12.Структура 2

13.Имя игрока: Игрок 2

14.Жизнь игрока: 80

15.Патроны пистолета игрока : 10

16.

17. Структура 3

Ниже примеры c комментариями к выше описанному примеру.

 

mov eax,edi //eax=edi=7 mov ebx,[eax+2] // ebx =[7+2]=[9]=65 жизней Игрока 1







mov edi, [1] // записать в edi значение адреса 1, а именно  значение «7»

 

Теперь попробуйте самостоятельно.

 

mov ebx, [2] mov esi,[eax+ebx+3] Проверьте себя. Чему равен esi для адресного пространства ниже? [Указатель] 1. «7» [Указатель] 2. «5» 3. 4. 5. 6. 7. Структура 1 8. Имя игрока: Игрок 1 9. Жизнь игрока: 65 10.Патроны пистолета игрока : 50 11. 12.Структура 2 13.Имя игрока: Игрок 2 14.Жизнь игрока: 80 15.Патроны пистолета игрока : 10 16. 17. Структура 3 …







mov eax, [1]

 

Ответ:

ESI будет равен 10 патронам пистолета второго игрока.

Если вы научились это считать, то можно сказать, что вы поняли основной принцип работы ассемблера.

Обращение к адресам выглядит так (примеры)

[ ] - обозначение обращение к адресу

[[1]+[2]+2] - адрес жизни

[[1]+[2]+3] - адрес патронов

Как видно с помощью укзателей можно легко перемещаться по структурам, считывать и записывать данные в эти структуры.

Понятия чтения и записи.

ЧТЕНИЕ

 

mov esi,[eax+ebx+3]- чтение данных из адреса [eax+ebx+3] в esi







mov eax, [1] - чтение данных из адреса 1 в eax

 

ЗАПИСЬ

 

mov [eax+ebx+3], esi - запись данных из esi в адрес [eax+ebx+3]







mov [1], eax  - запись данных  из eax в адрес 1

 

Про брейкпоинты.

Брейкпоинт (Break Point) - точка остановки при работе с адресом.

Брекпоинт может сработать

при чтении данных,

при записи данных,

при прохождении (ставится в отладчике на инструкции, обычно, по кнопке F5, срабатывает когда инструкция должна выполнится)

Разберём примеры.

Дан адрес

 

 







9. Жизнь игрока: 65

Если вы поставите брейкпоинт (далее bp) на адрес 9 на чтение. То будет срабатывать прерывание на всех инструкциях, которые пытаются прочитать значение из адреса 9

Например это

 

 







mov eax, [9]

 

Если вы поставите bp на адрес 9 на запись.

То будет срабатывать прерывание на всех инструкциях, которые пытаются записать в адрес 9

Например это

 

 







mov [9],eax

 

Если вы поставите bp на задрес 9 на доступ, то это тоже самое что поставить на чтение и запись одновременно, то будут срабатывать и чтение и запись. Соответственно это

Ставя брейкпоинты на адресах и совершая поведения объектов можно отлавливать инструкции записи или чтения, что нам пригодиться при обмане игр.

Ещё один пример работы с брейкпоинтами.

Мы нашли адрес здоровья с помощью CheatEngine (CE). Это «адрес 9», значение 65, тип 1 байт.

В CE мы поставим bp на доступ на этот адрес.

Вошли в игру…. игра тут же прочитала значение жизни. Вернулись в CheatEngine и увидили что выскочила инструкция.

mov esi,[eax+ebx+2] ///Вам уже не сложно определить, что это инструкция чтения.

А также вам будут показаны значения РЕГИСТРОВ.

eax=7

ebx=0

esi=65

Далее вы заходите в отладчик CheatEngine по отловленной инструкции и обращаете внимание на стоящие рядом инструкции

 

mov eax, [1] mov ebx, [2] mov esi,[eax+ebx+2] //зная значения регистров вы мысленно подставляете esi=[7+0+2]=[9]=65 …

 

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

 

2. «0» 3. 4. 5. 6. 7. Структура 1 8. Имя игрока: Игрок 1 9. Жизнь игрока: 65 10.Патроны пистолета игрока : 50 11. 12.Структура 2 13.Имя игрока: Игрок 2 14.Жизнь игрока: 80 15.Патроны пистолета игрока : 10 16. 17. Структура 3 …







1. «7»

 

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

Пойдём дальше...

Хотим сделать именно игрока1 бессмертным.

Поставим себе задачу, чтобы при выполнении кода превый игрок был бессмертным. Это и есть встраивание чит-кода.

Можно догадаться , что когда ebx = 0, то имеем дело только с первым игроком. Поэтому нужно поставить фильтр «свой/чужой» на запись постоянного числа в адрес жизней.

 

mov eax, [1] mov ebx, [2] mov esi,[eax+ebx+2] //зная значения регистров вы мысленно подставляете esi=[7+0+2]=[9]=65 …

 

Приведён кусочек кода из скрипта CheatEngine:

 

mov ebx, [2] cmp ebx, 0 // если это первый игрок (cmp это сравнение) jne x1 //прыжок если неравно mov [eax+ebx+2],#100 //то записать 100 жизней в [eax+ebx+2] x1: mov esi,[eax+ebx+2] // иначе выполнять только оригинальный код







mov eax, [1]

 

Так игроку1 при чтении (а чтение, обычно,повторяется очень часто) записывается 100 очков здоровья и в игре будет постоянно видно число 100.

Ну это не полная картина иньекции. Ведь нам нужно вставить это условие вместо оригинальной инструкции

mov esi,[eax+ebx+2]

А места-то нехватает, потому что mov esi,[eax+ebx+2] занимает определённое количество байт и ниже этой инструкции идёт другой код, который нет возможности как-то "подвинуть" ниже. Но есть другой способ. Мы должны сделать прыжок в этом месте в участок памяти. В нём вписать чит-код соблюдая логику кода с прыжком обратно. К сожалению, это плохой пример для наглядности. Поэтому нужно разобрать иньекцию на примере какой-нибудь игры. В этом случае будет полезно почитать какую-нибудь статью про внерение чит-кода. Если что-то там не понятно, то вернётесь к этой статье в другой раз. Просто надо посмотреть и сравнить картины того что там и картины которой я тут написал.

Вернёмся к скрипту.

Если вставлять чит-код в инструкцию записи, то будет прописываться "100" только при уроне.

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

2.2 Инструкции Ассемблера

 

Скрытый текст

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


  • [*:1ppxw1g7]того чтобы знать, как работает игра, на участке бряка;
    [*:1ppxw1g7]того чтобы знать, как сделать инъекцию кода и знать какую инъекцию;

 

Вы уже должны представлять что инструкции ассемблера оперируют данными, которые имеют размер, т.е. тип. Управления данными происходит с помощью регистров. В процессорах эти регистры разные и описываются в технической документации. Нам же с вами достаточно знать регистры 0х86 процессоров.

Сначала вы можете пробежаться по справочникам:

CPU

FPU

SIMD (MMX, SSE, SSE2, SSE3, SSSE3).

А теперь после просмотра справочников рассмотрим основные инструкции.

Я старался расположить материал от часто встречающихся "вещей" до редких. Вам будут попадаться игры с инструкциями на бряках чаще CPU, затем реже FPU и совсем редко SIMD.

Инструкции можно разделить на три блока


  • [*:1ppxw1g7]CPU (работа над целыми числами),
    [*:1ppxw1g7]FPU (работа над вещественными),
    [*:1ppxw1g7]SIMD инструкции (работа с массивами чисел).

 

Знакомьтесь CPU(окно регистров)

60573846yq1.png

CPU(основные команды):

MOV

mov рег, рег -записать в левый регистр, значение правого регистра

mov рег,[] -записать в регистр значение памяти

mov [],рег -записать в память значение регистра

Важно. Не забываете указывать размер данных. Байт, 2 байта, 4 байта. Это касается всех инструкций работающих со значением адреса в памяти.

Пример.

mov eax,byte [410000] - занести в eax значение байта

mov eax,word [410000] - занести 2 байта

mov eax,dword [410000] - занести 4 байта

NOP

Эта команда самая знакомая команда. Она стерает код. Это даже и не команда вовсе.

SUB

sub рег,рег -вычесть из левого правый регистр и сохранить в левом

sub рег,размер [] - вычесть из регистра значение адреса памяти и сохранить регистре

sub размер [], рег - вычесть из значения адреса в памяти значение регистра и сохранить в памяти

ADD

Тоже самое что и SUB только сложение.

CMP

cmp рег,рег - сравнить регистры

cmp рег, размер [] -сравнить значение регистра и значение памяти

cmp размер [], рег -сравнить значение регистра и значение памяти

*cmp, обычно, ставят сразу перед прыжком.

сmp будет выскакивать, только если вы ставите бряк на чтение, ведь, здесь только сравнение ))

DEC

dec рег - уменьшить значение регистра на единицу

dec размер [] - вычесть значение регистра из значения в памяти и сохранить в регистре

sub размер [], рег - вычесть значение значения в памяти из регистра и сохранить в регистре

INC

Тоже самое что и DEC только сложение.

LEA

Вы будите встречать редко, это работа с регистрами.

LEA EAX,[EBX+ECX*4+100]

eax=ebx+ecx*4+100

Эта инструкция нужна лишь для того чтобы вычислить смещение .Просто знайте о ней.

PUSH

push число - добавить в стек (времення память) число

push рег - добавить в стек значение регистра

push размер [] - добавить в значение памяти определённого размера

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

POP

Тоже самое что и PUSH только вытаскивание или восстановление. Вытаскивать нужно в обратном порядке.

Положили 1 2 3 4 5. Вытаскиваем 5 4 3 2 1. Будьте внимательны.

push eax

push ebx

add eax,ebx

sub ebx,eax

pop ebx

pop eax

PUSHAD Сохранение в стек регистров общего назначения edi, esi, ebp, esp, ebx, edx, ecx, eax.

POPAD Восстановление регистров общего назначения edi, esi, ebp, esp, ebx, edx, ecx, eax

PUSHF Размещение в вершине стека содержимого регистра флагов flags

POPF Восстановление флагов

XOR

Исключающие или

xor al, 01; изменить значение бита 0 регистра al на обратное

IMUL

Целочисленное умножение

mov bx,186

imul eax,bx,8

DIV

Без знаковое деление

• если делитель размером в байт, то делимое должно быть расположено в регистре ax. После операции частное помещается в al, а остаток — в ah;

• если делитель размером в слово, то делимое должно быть расположено в паре регистров dx:ax, причем младшая часть делимого находится в ax. После операции частное помещается в ax, а остаток — в dx;

• если делитель размером в двойное слово, то делимое должно быть расположено в паре регистров edx:eax, причем младшая часть делимого находится в eax. После операции частное помещается в eax, а остаток — в edx.

mov ax,10234

mov bl,154

div bl ;ah=остаток, al=частное

Знакомьтесь FPU(окно регистров)

72393145aj3.png

Основные FPU(команды):

Принцип такой есть 8 регистров ST. Эти регистры как барабан, который можно вращать некоторыми инстукциями. Также можно обратиться к каждомму регистру. Если регистр не указаывается, значит имеете дело с первым ST0 напримере комманды как fld [esi] (тоже самое что fld STO, [esi]).

Существуют инструкции довольно часто встречающиеся:

fld [] - загрузит из памяти в ST0 //fld St1,[] - загрузит в ST1

stp [] - скопирует из STO в память

fstp [] - выгрузит из STO в память

ну и так далее...

Знакомьтесь SIMD(окно регистров)

83509477th5.png

Эти регистры встречаются довольно редко и в основном в играх стратегиях, т.е. в играх в которых участвует большое количество объектов (юнитов, зданий, и т.п.)

Про эти регистры вы можете посмотреть здесь, если будет нужно.

1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Оочень интересно! Продолжай в том же духе :lol:

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Мастер скинь пожалуйста эту программу "Converter (HEX, DEC, BIN)"

Не понимаю какого лешего этот вопрос тут, но раз хотели ответ, получайте http://www.hiew.ru/f.../sencalc106.zip он ещё и складывать умеет всё в ReadMe

// MasterGH: программу скинул. Сообщения почистил. Пользоваться ли этой программой решайте сами.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

mov eax, [1]

mov ebx, [2]

mov esi,[eax+ebx+3]

Проверьте себя. Чему равен esi для адресного пространства ниже?

[Указатель] 1. «7»

[Указатель] 2. «5»

А вот такой вопрос, если в еах указатель на 7, в еbx указатель на 5, то esi=(7+5+3) и равно это 15 ?

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

// eax = 7, ebx=5,

mov esi,[eax+ebx+3]

При выполнении этой инструкции esi будет равен не 15, а значению располагающемуся по адресу 15. Это все равно что написать

mov esi,[15]

Что именно лежит по адресу 15, посмотрите сами.

И учтите, что я писал пример в десятичной системе для упрощения, а в реальной ситуации всё в 16-ричной системе: и адреса, и смещения, и значения.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Есть ли способ сделать Kernel-mode на 64-битной ОСи? Как сделать поддержку DBVM? Читал что-то на офф-форуме Cheat Engine, там вроде какие-то драйвера подписывать какой-то прогой надо, но какие именно драйвера нигде не пишется.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

В соседней теме обсуждалось. Во время загрузки винды жмём F8 и ищем что-то вроде "загружать неподписанные драйвера", радуеимся. А если подписать, то всё будет проще) но я подписывать не умею, и без подписи работает)

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

помогите пожалуйста разобраться с одним вопросом.

В поисках базового адреса (или ка он там называеться) в CheatEngine дохожу до инструкций вида

mov eax,[edi+eax*4]

--

в регистрах вот это:

EAX=01EC0B70

EDI=01EC1A88

и не могу понят где тут смешение :(

по адресу 7B02DC0 (01EC0B70*4) нули. Или тут другой подход нужен?

help :unsure:

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Скорее всего, eax был перезаписан после выполнения инструкции. Можно изменить аппартный бряк на программный для того чтобы узнать eax до выполнения инструкции, а не после. Подробнее об этом было здесь.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А таблица "прыжков для флагов CPU" точно без ошибок ?

или просто я что то не так понимаю (((

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

вопрос по нахождения неизвестного значения.
Поиск по точному дает только видимое значение, но не настоящее и изменения ни к чему не приводят, только визуально.
пробовал через неизвестное, путем уменьшилось/увеличилось , но и там ничего не находилось ( доходил до 15-20 значений и фризив каждое проверял, но не вышло)
потом вспомнил, что где-то может быть обратное, т.е. когда увеличивается, надо искать уменьшилось. но там остается слишком много значений (более 100) и каждое фризить не получается, т.к. игра вылетала раньше, чем я находил нужное, (если оно там вообще было) а пробовал и с конца и сначала перебирать и рандомно, но не вышло.
а просто изменилось/ не изменилось находит под 300 значений и меньше не становиться.
подскажите пожалуйста, что в этом случае можно сделать?

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

вопрос по нахождения неизвестного значения.

Поиск по точному дает только видимое значение...

 

Если удалось найти только адрес с видимым значением в игре, то можно изучить отладочный код того как значение записывается в этот адрес (через бряк на запись). В одной из игр я так определил, что значение рассчитывалось из суммы других значений через цикл. В этот цикл я подставлял максимальные значения. Вот и все. В другой игре подсчитывалась сумма из количества структур и эта сумма выводилась как видимое значение. В другой игре значение поступало как расшифрованное из зашифрованного. Зашифрованное значение найти было довольно трудно, очень долго, бесконечные поиски изменилось/не изменилось.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если удалось найти только адрес с видимым значением в игре, то можно изучить отладочный код того как значение записывается в этот адрес (через бряк на запись). 

честно говоря не уверен, что у меня получатся такие действия :( я пока дальше обычного поиска не заходил. но буду пробовать.

если совсем ничего не пойму, то можно будет сюда скинуть код, который через БП получится? или лучше в новую тему?

Изменено пользователем krenovut
0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

вопрос по нахождения неизвестного значения.

Поиск по точному дает только видимое значение, но не настоящее и изменения ни к чему не приводят, только визуально.

пробовал через неизвестное, путем уменьшилось/увеличилось , но и там ничего не находилось ( доходил до 15-20 значений и фризив каждое проверял, но не вышло)

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

а просто изменилось/ не изменилось находит под 300 значений и меньше не становиться.

подскажите пожалуйста, что в этом случае можно сделать?

 

 

В таких случаях надо найти (если к примеру игрок) видимое и цифровое значение отображаемое на экране(патроны например) добавить адрес патрон в таблицу. Смысл в том что все параметры игрока хранятся рядом, то есть методом отсева изменилось не изменилось не отсеиваются адреса,то можно посмотреть на адрес патронов(прим) и таким методом определить нужный адрес. К примеру адрес патронов 1FBCADFC то нужные нам адреса скорее всего будут начинаться 1FBXXXXX. Много раз именно так находил значения когда отсев не убирает лишние адреса.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если удалось найти только адрес с видимым значением в игре, то можно изучить отладочный код того как значение записывается в этот адрес (через бряк на запись). В одной из игр я так определил, что значение рассчитывалось из суммы других значений через цикл. В этот цикл я подставлял максимальные значения. Вот и все. В другой игре подсчитывалась сумма из количества структур и эта сумма выводилась как видимое значение. В другой игре значение поступало как расшифрованное из зашифрованного. Зашифрованное значение найти было довольно трудно, очень долго, бесконечные поиски изменилось/не изменилось.

 MasterGH можно список этих игр? Хочу попрактиковаться и повысить свои навыки.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

1. Сумму значений я встречал в трех играх. Две не помню. Одна Тибериум какой-то версии. Там были кристаллы (общее количество было суммой из двух адресов). В одной из игр в шутере здоровье было у отдельных частей тела (руки, ноги, голова, торс) и складывалось в общее здоровье и в броню

2. Сумма количества структур. На моей памяти Сталкер, патроны. Я как-то ломал на Чернобыля, но на другой версии Сталкера не прокатило. Гранаты в Sniper: Ghost Warrior (я так и не взломал). В какой-то старой игре стрелы из лука (тоже не получилось). Чтобы увеличить до максимума можно попытаться исследовать перезарядку оружия или поднятие в инвентарь. В теории надо бы вызывать функцию "взятия" патронов в инвентарь. Можно еще поднятия оружия с земли, вызвав предварительно функцию создания его по id предмета (названия, или указателя на структуру предмета), координатами и кватернион углами.

На Unreal Engine 3 движке спавн игрового объекта вызывается например такой функцией

AActor* UWorld::SpawnActor
(
UClass* Class,
FName InName,
FVector const* Location,
FRotator const* Rotation,
AActor* Template,
bool bNoCollisionFail,
bool bRemoteOwned,
AActor* Owner,
APawn* Instigator,
bool bNoFail,
ULevel* OverrideLevel,
bool bDeferConstruction
)


Пример

AKAsset* SpawnedActor1 = (AKAsset*) GetWorld()->SpawnActor(AKAsset::StaticClass(), NAME_None, &Location);


В UDK главные классы это акторы и компоненты. От Акторов наследуют пользовательские классы, а компоненты связываются с ними для визуализации объекта, создания поведения и прочего.

3. Шированное значение мне помниться в игре Loki. Там float шифровался и расшифровывался через xor. Больше игр не припоминаю.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

чет я не понимаю на что именно надо внимание обращать  :-[  :(  если есть, можете дать ссылку на видео, где подобная тема разбирается? 

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Находишь экранное значение, как ты делал до этого, далее реверсишь код, чтобы отследить, как это значение формируется перед выводом на экран. Я бы сказал, это не для новичка. Советую тебе на первых порах взять игру попроще.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
073B1038 - 53                    - push ebx073B1039 - 6A 00                 - push 00073B103B - E8 08EEFDFF           - call 0738FE48073B1040 - 83 C4 10              - add esp,10073B1043 - 85 C0                 - test eax,eax073B1045 - 0F84 7E000000         - je 073B10C9073B104B - 8B 46 78              - mov eax,[esi+78]073B104E - 83 EC 08              - sub esp,08073B1051 - 50                    - push eax073B1052 - 6A 00                 - push 00073B1054 - E8 BF44CBFF           - call 07065518073B1059 - 83 C4 10              - add esp,10073B105C - 85 C0                 - test eax,eax073B105E - 74 2A                 - je 073B108A073B1060 - 8B 43 14              - mov eax,[ebx+14]073B1063 - 3D 09000000           - cmp eax,00000009073B1068 - 75 20                 - jne 073B108A073B106A - 83 EC 0C              - sub esp,0C073B106D - 53                    - push ebx073B106E - 39 1B                 - cmp [ebx],ebx073B1070 - E8 8358D2FF           - call 070D68F8073B1075 - 83 C4 10              - add esp,10073B1078 - DD 5D D0              - fstp qword ptr [ebp-30]073B107B - F2 0F10 45 D0         - movsd xmm0,[ebp-30]073B1080 - F2 0F2C C0            - cvttsd2si eax,xmm0073B1084 - 89 86 90000000        - mov [esi+00000090],eax073B108A - 8B 46 7C              - mov eax,[esi+7C]073B108D - 83 EC 08              - sub esp,08073B1090 - 50                    - push eax073B1091 - 6A 00                 - push 00073B1093 - E8 8044CBFF           - call 07065518073B1098 - 83 C4 10              - add esp,10073B109B - 85 C0                 - test eax,eax073B109D - 74 2A                 - je 073B10C9073B109F - 8B 43 14              - mov eax,[ebx+14]073B10A2 - 3D 08000000           - cmp eax,00000008073B10A7 - 75 20                 - jne 073B10C9073B10A9 - 83 EC 0C              - sub esp,0C073B10AC - 53                    - push ebx073B10AD - 39 1B                 - cmp [ebx],ebx073B10AF - E8 4458D2FF           - call 070D68F8073B10B4 - 83 C4 10              - add esp,10073B10B7 - DD 5D D0              - fstp qword ptr [ebp-30]073B10BA - F2 0F10 45 D0         - movsd xmm0,[ebp-30]073B10BF - F2 0F2C C0            - cvttsd2si eax,xmm0073B10C3 - 89 86 94000000        - mov [esi+00000094],eax073B10C9 - 8D 65 F8              - lea esp,[ebp-08]073B10CC - 5E                    - pop esi073B10CD - 5B                    - pop ebx

вот это находится если искать на запись. Находится только 1. 
но вот код я совсем не понимаю. если отдельные строчки еще понятны, тот же mov, но вот найти смысл в таком количестве... слабоват

073B1084 - 89 86 90000000        - mov [esi+00000090],eax

в том что я скопировал, есть какая-нибудь нужная информация?

*хотел убрать в спойлер, но не нашел как, только вот как код выделил
Изменено пользователем krenovut
0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

жалко  :( но все равно благодарю за внимание. буду потихоньку тренироваться на более простых играх значит

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

073B107B - F2 0F10 45 D0         - movsd xmm0,[ebp-30]073B1080 - F2 0F2C C0            - cvttsd2si eax,xmm0073B1084 - 89 86 90000000        - mov [esi+00000090],eax
В стеке проскакивает double тип и преобразуется инструкций cvttsd2si в float тип (или integer, фиг его поймешь сходу). Два варианта

 

1. Искать double число в промежутке от число-1 до число+1. "Увеличилось", "уменьшилось".  Лучше не использовать "равно", "изменилось", "не изменилось", если не уверен в этом

 

2. Идти вверх по коду (можно по стеку или через трейс после бряка с остановкой проецесса). Бряки с остановкой можно делать в CE или в OllyDbg, или других отладчиках.

 

В общем если второй пункт сложный, то смотри первый пункт.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас