|
Создаем трейнер в Дельфи,
используя WinAPI
В этом учебнике я собираюсь обрисовать основной API, необходимый для создания
трейнера в Дельфи. Основы знания Дельфи предпочтительны, но Дельфи итак довольно
прост в освоении.
Концепция.
Хорошо, вот что мы хотим от трейнера. Мы запускаем игру. После этого ALT+TAB в
Windows. Мы запускаем трейнер, и жмем кнопку. Это действие запишет некие
значения в некоторые адреса в игре. Так, например, если мы знаем адрес денег в
памяти игры, мы сможем хакать деньги, используя этот трейнер.
Вот что нам надо для этого:
-
Название окна
игры
Запускаем игру, потом переходим в Windows по Alt+Tab. Ищем в
панели задач нашу игру и записываем е_ точный заголовок. (К
примеру, запустив Red Alert 2, в панели задач Вы увидите
кнопку с ее названием - Red Alert 2. Это и есть заголовок
главного окна программы. Кстати, Red Alert 2 взломать
способом, описанным здесь, не удастся - это DMA игра.
Читайте пару документов здесь, посвященных именно A.G.T. и
борьбе с DMA)
-
Адреса в памяти
игры (в шестнадцатеричном виде)
Используем программу, подобную GameHack или
MTC (Magic Trainer
Creator), мы можем найти любое значение в игре и
соответствующий ему адрес в памяти. К примеру, адрес в
шестнадцатеричном виде 41D090. Запишем и это тоже.
-
Значение, которое
мы хотим записать (в шестнадцатеричном виде):
Так, у нас есть адрес в памяти. Что мы хотим в него
записать? Скажем, я хочу 50 единиц золота. То есть первым
делом мне надо перевести 50 в шестнадцатеричную форму,
используя соответствующий конвертер (подойдет и Калькулятор
из Стандартных программ Windows - не забудьте включить
инженерное представление - прим.пер.) Конвертер скажет 32.
Так что запишите и это значение также.
-
Число байт,
которое мы хотим писать
В том значении, которое мы получили выше, мы должны знать
также сколько байт это займет в памяти. К примеру, число 32
займет только 1 байт, но FF07 займет уже два байта. В общем
случае, две цифры будут занимать один байт.
Начнем кодить
Мы собираемся использовать Win32 API чтобы записывать значения в память другого
процесса. Вот те функции, которые мы будем использовать. По порядку:
FindWindow
GetWindowThreadProcessID
OpenProcess
ReadProcessMemory
WriteProcessMemory
CloseHandle
(Прочтите описания этих функций в файле Win32.hlp (или MSDN -
прим.пер.) для полного описания. )
Я буду показывать только основы, так что начинающие могут просто копировать код
из этого документа и вставлять его в свой проект.)
Итак, начало. Во-первых, мы объявляем наши переменные. Скопируйте и вставьте это
в свой проект:
Var WindowName : integer;
ProcessId : integer;
ThreadId : integer;
buf : PChar;
HandleWindow : Integer;
written : cardinal;
Теперь надо объявить следующие константы. Скопируйте и этот раздел. Эти
константы устанавливаются в соответствии с тем, что вы записали выше.
Const WindowTitle = 'prog test';
Address = $41D090;
PokeValue = $32;
NumberOfBytes = 1;
Теперь, чтобы записать значения, вы должны получить хэндл памяти игры.
Невозможно сделать это в одно действие, поэтому мы сделаем следующее.
-
Получаем хэндл
главного окна
-
С этим хендлом мы
получаем идентификатор процесса (process identifier - pID)
-
С этим pID, мы
получаем хэндл области памяти.
-
С этим хэндлом мы
можем начинать хакать.
Во-первых, нам надо получить хэндл главного окна. Используем функцию FindWindow
WindowName := FindWindow(nil,WindowTitle);
If WindowName = 0 then
begin
MessageDlg('Игра должна быть запущена до трейнера.
Запустите ее, потом трейнер', mtwarning,[mbOK],0);
end;
Заметим, что код проверяет, равен ли нулю хэндл этого окна. Если оно равно, это
значит, что игра не запущена, так что мы предупреждаем пользователя и говорим
ему о том, чтобы он запустил игру.
Теперь нам нужен pID. Мы используем функцию GetWindowThreadProcessId. После
этого мы получаем хэндл области памяти через OpenProcess. Скопируйте код,
приведенный ниже.
ThreadId := GetWindowThreadProcessId(WindowName,@ProcessId);
HandleWindow := OpenProcess(PROCESS_ALL_ACCESS,False,ProcessId);
Вот оно. Теперь нам надо использовать WriteProcessMemory чтобы писать что-то
внутри этого хэндла. Как только мы это сделаем, мы закрываем хэндл. Так принято.
Так безопасно. Скопируйте код, приведенный ниже:
GetMem(buf,1);
buf^ := Chr(PokeValue);
WriteProcessMemory(HandleWindow,ptr(Address),buf,NumberOfBytes,write);
FreeMem(buf);
CloseHandle(HandleWindow);
Вот исходный код для всего трейнера. Для начинающих программистов, чтобы быстро
сделать трейнер, требуется только поменять константы, объявленные в начале
программы.
Var WindowName : integer;
ProcessId : integer;
ThreadId : integer;
buf : PChar;
HandleWindow : Integer;
write : cardinal;
Const WindowTitle = 'prog test';
Address = $41D090;
PokeValue = $32;
NumberOfBytes = 1;
###########################################################
# (Вставьте следующий код в обработчик OnClick кнопки )#
###########################################################
begin
WindowName := FindWindow(nil,WindowTitle);
If WindowName = 0 then
begin
MessageDlg('Игра должна быть запущена до трейнера.
Запустите ее, потом трейнер', mtwarning,[mbOK],0);
end;
ThreadId := GetWindowThreadProcessId(WindowName,@ProcessId);
HandleWindow := OpenProcess(PROCESS_ALL_ACCESS,False,ProcessId);
GetMem(buf,1);
buf^ := Chr(PokeValue);
WriteProcessMemory(HandleWindow,ptr(Address),buf,NumberOfBytes,write);
FreeMem(buf);
CloseHandle(HandleWindow);
end;
Автор: неизвестен www.tеаm-x.ru
|