Написание тренера( Trainer ) для игры на C++

   Копание в памяти чужого процесса это интересное и увлекательное занятие. Помню, когда я первый раз познакомился с программой под названием ArtMoney, я был в восторге. Тогда я играл в Might & Magic 6, которая и послужила "подопытным кроликом" для меня. Весело было смотреть на запредельный уровень персонажей и огромное количество HP/MP у оных же. Да, да, меня за это можно полноправно назвать читером, но тогда я и слова такого не знал. Мой друг так же издевался над игрой, только в другую сторону, в то время когда я повышал количество золота и жизней, он, напротив, уменьшал уровень персонажей.
   Именно тогда мною предпринимались первые попытки написать свою программу по типу ArtMoney или хотя бы программу, заточенную под изменения характеристик MM6, но моих знаний как в программировании, так и в Windows API было недостаточно для этого. С тех пор много воды утекло, и я подумал, что возможно кому-нибудь будет интересно то, что было интересно мне, и данная статья должна немного помочь.
   По сути тут будут рассмотрены те функции, которые необходимы для написания самой простой программы, для считывания и изменения памяти другой программы.
   Для начала необходимо получить HWND тоесть Window Handle, это можно сделать функцией:


HWND FindWindow( 
	LPCTSTR	lpClassName, 	// Имя класса 
	LPCTSTR	lpWindowName	// Имя окна
);


   Функция возвращает NULL если окно не найдено. Для поиска окна достаточно знать его заголовок( window's title ), который и нужно передать заместо lpWindowName, в то время как lpClassName можно передать как NULL.
   Теперь необходимо получить идентификатор процесса с помощью функции:


DWORD GetWindowThreadProcessId(
	HWND	hWnd,			// Хэндл окна
	LPDWORD	lpdwProcessId		// Указатель на идентификатор процесса
);


   Хэндлом окна, в данном случае, и является переменная, полученая с помощью функции FindWindow. Следует обратить внимания на то, что lpdwProcessId именно указатель на переменную типа DWORD.
   Ну вот, собственно, практически все, осталось лишь получить Хэндл самого процесса и "открыть" его для чтения или записи. Это можно сделать функцией:


HANDLE OpenProcess(
	DWORD	dwDesiredAccess,	// Флаг доступа
	BOOL	bInheritHandle,		// Флаг наследования
	DWORD	dwProcessId		// Идентификатор процесса
);


   Переменная dwDesiredAccess может принимать множество значений, среди которых: PROCESS_VM_READ - только чтение из процесса, PROCESS_VM_WRITE только запись в процесс, PROCESS_ALL_ACCESS - полный доступ к процессу. В данном случае необходим полный доступ. bInheritHandle не нужен, поэтому установим его в false. dwProcessId - как уже было сказано выше, идентификатор процесса.
   Если не удалось получить доступ к процессу, то функция возвращает NULL, иначе возвращает хэндл.
   Функции чтения и записи совершенно аналогичны друг другу:


BOOL ReadProcessMemory(
	HANDLE	hProcess,	// Хэндл процесса
	LPCVOID	lpBaseAddress,	// Начальный адрес
	LPVOID	lpBuffer,	// Ссылка на буфер
	DWORD	nSize,		// Количество байт
	LPDWORD	lpNumberOfBytesRead 	// Ссылка на переменную
);

BOOL WriteProcessMemory(
	HANDLE	hProcess,
	LPVOID	lpBaseAddress,
	LPVOID	lpBuffer,
	DWORD	nSize,
	LPDWORD	lpNumberOfBytesWritten
);


   Я думаю с hProcess все ясно. lpBaseAddress это указатель на место откуда необходимо читать( записывать ) данные из процесса. lpBuffer - ссылка на буфер, куда следует помещать прочитанную информацию( откуда следует брать информацию для записи ). nSize - сколько байт нужно считать( записать ). lpNumberOfBytesRead - реальное количество байт, которое удалось считать( записать ). Функция возвращает true при удачном чтении( записи ).
   Для демонстрации работы с данными функциями мною было написано две программы.
   Программа, которую нужно взломать носит название Prog.exe, при запуске она создает файл addr.txt и пишет туда адрес переменной, которую нужно отследить и изменить. Нажатием стрелок "вверх/вниз". можно изменять значение переменной из самой программы.
   Программа artcrack.exe и есть набросок программы-тренера. Адрес нужной переменной в коде присвоен такой строкой:


#define			ID_CRACK_PROG_ADDR	0x00407030	// Число из addr.txt


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

Статью написал faceH0r 10.02.2007
Используются технологии uCoz