В этом учебнике я собираюсь обрисовать основной 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;