Регистрация Главная Пользователи Все разделы прочитаны
Сообщения за день Справка Регистрация
Навигация
Zhyk.org LIVE! Реклама на Zhyk.org Правила Форума Награды и достижения Доска "почета"

Ответ
 
Опции темы
Старый 24.07.2016, 20:45   #1
 Разведчик
Аватар для VOLKyiv
 
VOLKyiv скоро будет известенVOLKyiv скоро будет известенVOLKyiv скоро будет известенVOLKyiv скоро будет известенVOLKyiv скоро будет известен
Регистрация: 02.05.2013
Сообщений: 4
Популярность: 439
Сказал(а) спасибо: 0
Поблагодарили 8 раз(а) в 4 сообщениях
 
Post Модификация игры ASM/C++ Часть 3.

Всем, привет!
После первых двух частей где мы подготавливали свою DLL к бою, в этой части я обещал что будет очень интересно.
А именно будет представлен сам процесс модификации, а именно мы будем в IDA Pro искать нам нужные функции и редактировать их.

Создадим класс FixGame.

И объявим статическую функцию Initialize
Эта функция будет главной, внутри её мы будем писать изменения. И она будет вызываться внутри DllInitializer.

FixGame.h


FixGame.cpp

Теперь запустим игру и попробуем что-то внутри нее изменить

Показать скриншот

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

Показать скриншот

И в качестве примера сейчас попробуем это убрать. Запускаем IDA Pro. Переходим на вкладку Imports.
И ищем WINAPI функции связаны с фокусом окна.

Показать скриншот

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

Показать скриншот

И выбираем Jump to xref to operand... IDA Pro покажет где эта функция вызывается, в нашем случае только 1 раз в функции sub_602410. Нажимаем снова два раза на название чтобы нас переместили в то месте где она вызывается.

Показать скриншот

Теперь мы видим дизассемблированый код этой функции sub_602410. Нажимаем кнопку F5, чтобы увидеть приближенный к С++ код.

Показать скриншот

Поставим вот здесь breakpoint для того чтобы определить здесь ли нам нужно патчить или нет. И запускаем игру в IDA Pro. Пытаемся поставить игру на паузу.

Показать скриншот

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

Показать скриншот

Погуглив я нашел что можно определять фокус окна с помощью функции GetActiveWindow, проделываем то же самое что и с GetFocus.

Показать скриншот

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

Когда я проверил все функции, я увидел в последней то что при запуске игры, игра записывает результат выполнения в какую-то переменную. Значит это значение анализируется в другом месте. Посмотрев эту функцию sub_5D4CC0
Можно сделать вывод о том что здесь создается главное окно игры. Здесь можно увидеть то что игра передает созданному окну указатель на класс создателя.

Показать скриншот

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

Показать скриншот

Найдем функцию WndProc, которая указывается при регистрации класса окна.
В нашем случае зарегистрирован класс с наименованием MainWindow. Попробуем найти его регистрацию. Откроем вспомогательное окно в IDA Pro, Strings.

Показать скриншот

Попробуем найти все места где упоминаются MainWindow. Всё точно так же как и с поиском функций.

И вот мы видим функцию WndProc. Зайдем внутрь её. Для того чтобы найти наш таймер. С помощью Visual Studio узнаем номер сообщения
Код:
WM_TIMER = 0x113
Показать скриншот

Ищем его

Показать скриншот

Теперь переходим на LABEL_28 и снова ищем 0x113. Найдя это сообщения можно увидеть что оно просто сбрасывает переменную в 0. И это никак не может относится к проверки фокуса окна.

Показать скриншот

Вернемся к функции sub_5D4CC0 в которой создавалось окно и куда-то записывался результат выполнения функции GetActiveWindow. И переименуем переменную dwNewLong на THIS. Так как это адрес объекта который управляет созданием окна.
На скриншоте показано как это я определил.

Показать скриншот

Помним что класс передается окну указатель на самого себя

Код:
SetWindowLongA(*(HWND *)(THIS + 884), -21, THIS);
SetWindowLongA(*(HWND *)(THIS + 0x374), -21, THIS);
884 = 0x374
Видим куда записывается состояние окна

Код:
*(_BYTE *)(THIS + 0x53E) = GetActiveWindow() == *(HWND *)(THIS + 0x374);
И возвращаемся к WndProc

Вначале находим получение указателя класса

Код:
v38 = GetWindowLongA(hWnd, -21);
То есть v38, это тот же THIS что и в функции создания окна.

Ищем смещение 0x53E, то есть наша переменная активности окна. Долго искать не пришлось, вот что я нашел

Код:
if ( v38 && !*(_BYTE *)(v38 + 0x581) && hWnd == *(HWND *)(v38 + 0x374) )
	*(_BYTE *)(v38 + 0x53E) = wParam != 0;
То есть пока идут сообщения окну, значит оно активно, как только будет 0, это значит что окно вне фокуса, посмотрим на дизассемблированый код этого участка.

Код:
.text:005D14B7                 xor     ecx, ecx
.text:005D14B9                 cmp     [ebp+wParam], 0
.text:005D14BD                 setnz   cl
.text:005D14C0                 mov     edx, [ebp+var_4]
.text:005D14C3                 mov     [edx+53Eh], cl
Что можно здесь сделать, так это заменить setnz cl, на mov cl, 1.

Давайте попробуем. Для того чтобы нам узнать какие байты нам нужно прописать запустим Cheat Engine, и подключимся к нашей игре, и откроем Memory View.

Перейдем по адресу 005D14BD и видим все ту же инструкцию, только Cheat Engine вместо z пишет e, на самом деле это одно и то же. (Не важно) Главное мы видим рядом что эта инструкция занимает 3 байта, теперь нажмем правой кнопкой и нажмем Assemble.

Показать скриншот

Напишем mov cl, 1. И нажмем YES чтобы забить оставшиеся байты нопами. Сейчас увидите почему соглашаемся. Новая инструкция занимает всего 2, и для того чтобы не испортить приложение, нужно оставшийся байт занопить.

Главное мы теперь знаем какие байты нам нужно писать.

Код:
PlantsVsZombies.exe+1D14B9 - 83 7D 10 00           - cmp dword ptr [ebp+10],00
PlantsVsZombies.exe+1D14BD - B1 01                 - mov cl,01
PlantsVsZombies.exe+1D14BF - 90                    - nop 
PlantsVsZombies.exe+1D14C0 - 8B 55 FC              - mov edx,[ebp-04]
А это B1 01 90. Пробуем пропатчить нашу игру

Изменим нашу функцию
Код:
void FixGame::Initialize(void)
{
	BYTE bytes[] = { 0xB1, 0x01, 0x90 };
	WriteMemoryBYTES(0x005D14BD, bytes, 3);
}
Компилируем и пробуем поставить игру на паузу

Видим что в фокусе находится окно проводника, но в игре паузы нет.

Показать скриншот

На этом все Отвечу на все ваши вопросы

Следующая часть будет не менее интересней этой

Так же сделал репозиторий с исходным кодом проекта.
[Ссылки могут видеть только зарегистрированные пользователи. ]

Если нужен исходник:
[Ссылки могут видеть только зарегистрированные пользователи. ]

1 часть
2 часть

Последний раз редактировалось VOLKyiv; 25.07.2016 в 17:06.
  Ответить с цитированием
2 пользователя(ей) сказали cпасибо:
crecker33 (15.01.2017), MembRupt (25.07.2016)
Ответ

Метки
модификация игры, создание читов

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[Руководство] Модификация игры ASM/C++ Часть 2. VOLKyiv С/С++ 0 24.07.2016 18:25
[Руководство] Модификация игры ASM/C++ Часть 1. VOLKyiv С/С++ 0 24.07.2016 16:48
Похоже, что новая часть игры Wolfenstein уже находится в разработке NewsMaster Игровые новости, анонсы и обзоры 0 03.10.2015 21:18
Анонсирована новая часть игры Warhammer 40,000: Inquisitor – Martyr NewsMaster Игровые новости, анонсы и обзоры 0 24.07.2015 16:43

Заявление об ответственности / Список мошенников

Часовой пояс GMT +4, время: 14:52.

Пишите нам: [email protected]
Copyright © 2024 vBulletin Solutions, Inc.
Translate: zCarot. Webdesign by DevArt (Fox)
G-gaMe! Team production | Since 2008
Hosted by GShost.net