В этом уроке мы научимся, записывать и считывать значения из адресов памяти игры GTA Vice City непосредственно из нашего плагина ASI. Как упоминалось выше, когда наш плагин загрузился игрой, то он стал неотъемлемой частью игры. Ради примера я приготовил кое-что для вас интересное. Мы изменим не сколько значений в памяти GTA Vice City для закрепления так называемых знаний. Мы изменим смещение в одной функции, что повлечет за собой перекрашивание всех цветов интерфейса. Для этой работы нам понадобиться база IDB для GTA Vice City, скачать ее можно тут. После того как скачаете, открывать ее нужно программой IDA pro. Как работать с базой мы разберем позднее а сейчас пока не будем заморачиваться над этим, а разберем простые задачи. Ниже приведен код, конструктора RGBA, который при вызове и задает цвета, различным текстурам на худе, в меню и прочее:
; RwRGBA *__thiscall RwRGBA__constructor(RwRGBA *, BYTE r, BYTE g, BYTE b, BYTE a)
RwRGBA__constructor proc near ; CODE XREF: DrawMessages+12Dp
r = byte ptr 4
g = byte ptr 8
b = byte ptr 0Ch
a = byte ptr 10h
mov eax, ecx
mov cl, [esp+r]
mov [eax], cl
mov dl, [esp+g]
mov [eax+1], dl
mov cl, [esp+b]
mov [eax+2], cl
mov dl, [esp+a]
mov [eax+3], dl
retn 10h
RwRGBA__constructor endp
Не стоит пугаться, это очень простой ассемблерный код, сам по себе конструктор класса прост:
RwRGBA::RwRGBA(char r, char g, char b, char a);
подробней будем разбирать еще это все поздней а сейчас наша цель значит b цвет передавать как g, и g передавать как b, т.е таким образом сделать подмену что повлечет за собой изменения всех цветов интерфейса, так как этот конструктор и используется для инициализации цвета, конкретной текстуре. Нам интересен в данной задаче только лишь этот кусочек участка:
mov dl, [esp+g]
mov [eax+1], dl
mov cl, [esp+b]
mov [eax+2], cl
после изменения должно выглядеть так:
mov dl, [esp+g]
mov [eax+2], dl
mov cl, [esp+b]
mov [eax+1], cl
Так откроем базу и давайте с легка настроим опции в программе IDA pro, для этого пройдите в Options->General и выберите вкладку Disassembly и расставьте галочки как на рисунке ниже:
Затем как настроите, в самой программе нажмите кнопку
“G” и введите этот адрес
00541570 и перейдите к данному участку кода, если все правильно то вы попадете сюда:
Вот по этому адресу 00541570 и располагается код самого конструктора RwRGBA, чуть-чуть разберем что к чему. Вот это “.text:00541570″ означает по какому адресу этот код находиться в самой памяти. Далее “000” – это глубина стека, очень хорошо помогает при обратной разработке и наконец последний такой вот байт 89 C8 код, это и есть ассемблерные инструкции.
Значит теперь для правки возьмем этот адрес 0054157C и этот 00541583 так, как надо сместиться к самому значению, а не записывать в сами ассемблерные команды, это будет наглядно выглядеть так:
Вот то что помечено красным то и будем изменять, значит наши правильные адреса будут такие:
0054157E = (0054157C + 0x2 )
00541585 = (00541583 + 0x2 )Первый опкод, равен к смещению + 0, так что имейте это веду. Это все можно посчитать в обычно калькуляторе, только надо выбрать вид “Программист”. Теперь перейдем к следующему этапу это мы напишем правки в MSVC C++:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
void Pacth_RwRGBA(){
DWORD _old;
VirtualProtect((LPVOID)0x054157E, 7, PAGE_READWRITE, &_old);
*(char*)(0x054157E) = 2;
*(char*)(0x0541585) = 1;
VirtualProtect((LPVOID)0x054157E, 7, _old, &_old);
};
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Pacth_RwRGBA();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Теперь разберем подробно наш код на C++ , что же тут у нас происходит, мы объявили обычную процедуру
void Pacth_RwRGBA();Сперва вызываем:
VirtualProtect((LPVOID)0x054157E, 7, PAGE_READWRITE, &_old);
Который меняет доступ к коду памяти, т.е мы присваиваем атрибут для чтения и записи, первый параметр это сам наш адрес, второй параметр это размер области, 3-тий это уже сам флаг функции, что сделать грубо говоря так, 4 параметр это у нас предыдущий флаг, который был ранее использован. Все как мы сделали для записи и чтения, мы смело записываем туда значения:
*(char*)(0x054157E) = 2;
*(char*)(0x0541585) = 1;
Как запись произвели, вернули атрибуты памяти, которые были до нашего вмешивания:
VirtualProtect((LPVOID)0x054157E, 7, _old, &_old);
Теперь как упоминалось ранее, при загрузке плагина вызываем нашу процедуру вот в этом участке:
case DLL_PROCESS_ATTACH:
Pacth_RwRGBA();
break;
Конечно если бы мы не изменили бы атрибуты в памяти, то просто бы не чего не удалось записать, очень часто новички при разработке таких модов для GTA Vice City забывают про атрибуты, так что имейте это введу, иначе записать не чего не получиться. Если вы сделали все правильно, написали код как я показал выше, то в игре все будет выглядит так:
gtavc_mod_hud.rar [7,29 Kb] (cкачиваний: 47)Вот таким вот образом, грубо говоря мы сделали мод HUD-а для GTA Vice City в виде ASI плагина.