Перейти к содержанию

Мой первый трейнер


helldrg

Рекомендуемые сообщения

Всем привет! До пилил наконец то кое как свой трейнер для игры C&C:Generals v1.8 с процессом generals.exe, урезав множество опций и упростивши интерфейс до нельзя. Урезал и упростил из - за подобного кода:

Скрытый текст

bytes[0] = '\xe9';
					(DWORD&)(*(bytes + 1)) = GetInAllocMemPos(1) -  (baseAddress + offsetAddress[1]) - 5;
					bytes[5] = '\x90';

					if (Process.WriteMemory(baseAddress + offsetAddress[1], (LPVOID)bytes, jmpSrcAddressSize[1]) == FALSE)
						wsprintf(buffer, "Ошибка!");


					bytes[0] = '\x50';	
					bytes[1] = '\x8b';	bytes[2] = '\x81';	bytes[3] = '\x44';	bytes[4] = '\x01';	bytes[5] = '\x00'; bytes[6] = '\x00';
					bytes[7] = '\x81';	bytes[8] = '\x78';	bytes[9] = '\x08';	bytes[10] = '\x70';	bytes[11] = '\x6c'; bytes[12] = '\x61'; bytes[13] = '\x79';
					bytes[14] = '\x0f';	bytes[15] = '\x85';	
					(DWORD&)(*(bytes + 16)) = (GetInAllocMemPos(1) + 53) - (GetInAllocMemPos(1) + 15) - 5;
					bytes[20] = '\x8b';	bytes[21] = '\x81';	bytes[22] = '\x10'; bytes[23] = '\x01';	bytes[24] = '\x00'; bytes[25] = '\x00';	
					bytes[26] = '\x3d'; bytes[27] = '\x00'; bytes[28] = '\x01'; bytes[29] = '\x00'; bytes[30] = '\x00';
					bytes[31] = '\x0f'; bytes[32] = '\x8e';
					(DWORD&)(*(bytes + 33)) = (GetInAllocMemPos(1) + 53) - (GetInAllocMemPos(1) + 32) - 5;
					bytes[37] = '\xd9'; bytes[38] = '\x40'; bytes[39] = '\x14'; 
					bytes[40] = '\xd9'; bytes[41] = '\x58'; bytes[42] = '\x08'; 
					bytes[43] = '\xc7'; bytes[44] = '\x81'; bytes[45] = '\x34'; bytes[46] = '\x01'; bytes[47] = '\x00'; bytes[48] = '\x00'; bytes[49] = '\x00'; bytes[50] = '\x00'; bytes[51] = '\xc8'; bytes[52] = '\x42';
					bytes[53] = '\x58'; 
					bytes[54] = '\xd9';	bytes[55] = '\x81';	bytes[56] = '\x34'; bytes[57] = '\x01';	bytes[58] = '\x00'; bytes[59] = '\x00';
					bytes[60] = '\xe9';
					(DWORD&)(*(bytes + 61)) = (baseAddress + offsetAddress[1]) - GetInAllocMemPos(1) - jmpDestAddressSize[1] + jmpSrcAddressSize[1];

					if (Process.WriteMemory(GetInAllocMemPos(1), (LPVOID)bytes, jmpDestAddressSize[1]) == FALSE)
						wsprintf(buffer, "Ошибка!");

 

Так как я понимаю, что все таки не правильно что то делаю. Хороший, качественный и чистый код не должен так выглядеть, поэтому я немного расстроился =) и решил подождать новых уроков от вашего сообщества, так как я люблю программирование, но вот такое программирование меня утомляет. Может кто то играет в эту игру ему пригодится этот трейнер. Его возможности можно увидеть на скрине:
download?id=y7sNi54RmrOSYvEiHtJz4kdmxjYm

Далее я попробую этот чит сделать в стиле metro, так как стандартными средствами winapi очень трудно добиться такого результата. 

Ну и если трейнер соберет больше 10 лайков, то я добавлю, то, что в последний момент урезал (по разным причинам: не доделал, доделал, но выглядит код ужасно как выше приведенный код и просто поленился) следующие функции:
- активацию опции по нажатию клавиш;

- описание трейнера в пункте об трейнере, который должен быть на серой полоске;

- опцию map hack
- опцию режим Бога

- ползунок для изменения положения камеры по оси Z (в настоящее время она отдаляется на 600 условных едениц, по стандарту стоит приблизительно 300)

- и на последок завезу оптимизацию, то есть проц будет нагружиться приблизительно в 15 раз меньше, во всяком случае на моем компьютере, то есть сделаю чтобы основной цикл программы проходил 30 раз за секунду, а не как сейчас несколько тысяч раз

PS:Последний абзац написан в лучших традициях байта на лайки :DDDDDD 

Ох да, чуть не забыл скинуть программу =) Трейнер будет доступен 90 дней с момента публикации
http://rgho.st/89Jw7rhCm

Особые благодарности: kenq - за отличные видеоуроки и Dino - за невероятно доступное, понятное объяснение непонятных мне аспектов

Изменено пользователем helldrg
  • Плюс 5
Ссылка на комментарий
Поделиться на другие сайты

4 часа назад, helldrg сказал:

Ну и если трейнер соберет больше 10 лайков

Добавлю свою долю лайков.

4 часа назад, helldrg сказал:

то я добавлю, то, что в последний момент урезал

Конечно пилите дальше. :D Тем более, что Вам нравиться программировать:

 

4 часа назад, helldrg сказал:

так как я люблю программирование

 

 

ЗЫ: 

4 часа назад, helldrg сказал:

До пилил наконец то кое как свой трейнер для игры C&C:Generals v1.8

С почином!!!:D

  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

28 минуты назад, keng сказал:

Никогда бы не подумал, что в моем нике можно ошибиться. :D

:D

 

29 минуты назад, keng сказал:

Предлагаю @helldrg переводить потихоньку в разработчики.

Я - за.

  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

Цитата

PS: Никогда бы не подумал, что в моем нике можно ошибиться. :D

аахахах извиняюсь, уже поздно было, спать хотелось :D

Спасибо всем, приятное сообщество здесь =)

Ссылка на комментарий
Поделиться на другие сайты

1 в DLL было бы круче +желательно когда жмешь Х что бы она зачистила все и выгрузилась xD
2 можешь удалить CRT мусор изменив ентри на.. например _Main (вроде в вс2015.3 исправили) - будет еще меньше по размеру
3 unicode билд обязательно (все равно на вин98 не запустится)
4 форс админ права не нужно (манифест тот)
5 для OpenProcess желательно подбирать права типа PROCESS_VM_OPERATION+PROCESS_VM_READ+PROCESS_VM_WRITE тд тп
6 K32GetModuleBaseName что там делает? в структуре от Module32Next уже есть имя ProcessEntry.szExeFile
7 можно заюзать K32EnumProcesses\K32EnumProcessModules\K32GetModuleBaseNameW - они быстрее (вин7+)
8 шрифт добавь! Lol

 

Ссылка на комментарий
Поделиться на другие сайты

9 minutes ago, gmz said:

1 в DLL было бы круче +желательно когда жмешь Х что бы она зачистила все и выгрузилась xD
2 можешь удалить CRT мусор изменив ентри на.. например _Main (вроде в вс2015.3 исправили) - будет еще меньше по размеру
3 unicode билд обязательно (все равно на вин98 не запустится)
4 форс админ права не нужно (манифест тот)
5 для OpenProcess желательно подбирать права типа PROCESS_VM_OPERATION+PROCESS_VM_READ+PROCESS_VM_WRITE тд тп
6 K32GetModuleBaseName что там делает? в структуре от Module32Next уже есть имя ProcessEntry.szExeFile
7 можно заюзать K32EnumProcesses\K32EnumProcessModules\K32GetModuleBaseNameW - они быстрее (вин7+)
8 шрифт добавь! Lol

 

Я хочу посмотреть на твой первый трейнер, нет, серьезно. :D

Ссылка на комментарий
Поделиться на другие сайты

Только что, keng сказал:

Я хочу посмотреть на твой первый трейнер, нет, серьезно. :D

gmz, кстати я тоже бы с удовольствием посмотрел на него (если конечно сохранился), причём с твоими теперешними замечаниями. :D;)

Ссылка на комментарий
Поделиться на другие сайты

Цитата

в DLL было бы круче

В dll я сделаю попозже, меню будет прямо в игре, я к директ икс устройству игры подключусь и там все выведу)

Цитата

2 можешь удалить CRT мусор изменив ентри на.. например _Main (вроде в вс2015.3 исправили) - будет еще меньше по размеру

Я давно что то читал про это, я помню как в консольном приложении это делали, а вот в винапишном не препоминаю

Цитата

3 unicode билд обязательно 

А можно по подробней?

Цитата

форс админ права не нужно (манифест тот)

Просто чтобы чит работал надо от имени администратора запускать, мне надоело постоянно так запускать я взял и в настройках поставил =)

Цитата

для OpenProcess желательно подбирать права типа PROCESS_VM_OPERATION+PROCESS_VM_READ+PROCESS_VM_WRITE тд тп

Я делал как keng советовал в своих уроках, так что если что не так его ругать надо :DDD

Цитата

K32GetModuleBaseName что там делает? в структуре от Module32Next уже есть имя ProcessEntry.szExeFile

Вот это я немного не понял

Цитата

7 можно заюзать K32EnumProcesses\K32EnumProcessModules\K32GetModuleBaseNameW - они быстрее (вин7+)

Про них почитаю сегодня

Цитата

8 шрифт добавь! Lol

я цвет текста замучался менять, а тут шрифт)

Ссылка на комментарий
Поделиться на другие сайты

Ты наверно про это  GetModuleBaseName 

Скрытый текст

bool ProcessClass::GetModuleByName(char *name, DWORD pid)
{
	bool result = false;
	
	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
	if (snapshot != INVALID_HANDLE_VALUE)
	{
		MODULEENTRY32 module;
		module.dwSize = sizeof(MODULEENTRY32);
		if (Module32First(snapshot, &module))
		{
			do
			{
				if (module.th32ProcessID != pid)
					continue;

				TCHAR szName[MAX_PATH];
				HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
				GetModuleBaseName(hProcess, module.hModule, szName, MAX_PATH);
				if (_stricmp(szName, name) != 0)
				{
					strcpy_s(szName, "");
					continue;
				}
				m_module = module;
				CloseHandle(hProcess);
				
				result = true;
				break;
			} while (Module32Next(snapshot, &module));
		}
		else
		{
			result = false;
		}
	}
	else
	{
		result = false;
	}

	CloseHandle(snapshot);

	return result;
}

 

А почему ты называешь  K32GetModuleBaseName ?

Я так делал потому что имя модуля в MODULEENTRY32 хранится вместе с путем, можно было сроку обработать и получить только имя, но я просто воспользовался этой функцией GetModuleBaseName

Ссылка на комментарий
Поделиться на другие сайты

8 минут назад, keng сказал:

Я хочу посмотреть на твой первый трейнер, нет, серьезно. :D

 

6 минут назад, Garik66 сказал:

gmz, кстати я тоже бы с удовольствием посмотрел на него (если конечно сохранился), причём с твоими теперешними замечаниями. :D;)

он был похож на это только на масм32 +замена линкера +бредооптимиз. весил ~2.7кб (пак) и самый большой косяк - мерцание текста когда вкл/откл

а еще рекордный был на вирьтотал - 47+ детектов :D

 

8 минут назад, helldrg сказал:

А можно по подробней?

L"blabla"

 

9 минут назад, helldrg сказал:

Вот это я немного не понял

https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms684839(v=vs.85).aspx

 

 

  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

Только что, gmz сказал:

он был похож на это только на масм32 +замена линкера +бредооптимиз. весил ~2.7кб (пак) и самый большой косяк - мерцание текста когда вкл/откл

а еще рекордный был на вирьтотал - 47+ детектов :D

Спасибо - за самокритику, хорошо что и себя критикуешь тоже. :D

Ссылка на комментарий
Поделиться на другие сайты

13 минуты назад, helldrg сказал:

Я так делал потому что имя модуля в MODULEENTRY32 хранится вместе с путем, можно было сроку обработать и получить только имя, но я просто воспользовался этой функцией GetModuleBaseName

там есть szModule

Ссылка на комментарий
Поделиться на другие сайты

 

Цитата

Я знаю что структура содержит, я не знаю что такое   K32GetModuleBaseName. Я так понял это другое определение GetModuleBaseName в какой то версии psapi, но почему вы так назвали эту функцию? Запутать хотели ?))

Ссылка на комментарий
Поделиться на другие сайты

Цитата

там есть szModule

Спасибо большое!!! Этот момент я упустил!!!!!!
 

Цитата

unicode билд обязательно (все равно на вин98 не запустится)

Да я понял что L подставляешь и пишешь строку, а почему юникодом надо пользоваться?)

Ссылка на комментарий
Поделиться на другие сайты

gmz

Я смотрю вы шарите в этой теме, вот есть вопросик =) 

Я сделал класс для работы с процессами. Там я вывожу имена адрес потока:
 

Скрытый текст

typedef LONG    NTSTATUS;
typedef NTSTATUS(WINAPI *pNtQIT)(HANDLE, LONG, PVOID, ULONG, PULONG);
#define STATUS_SUCCESS    ((NTSTATUS)0x000 00000L)
#define ThreadQuerySetWin32StartAddress 9


DWORD WINAPI GetThreadStartAddress(HANDLE hThread)
{
	NTSTATUS ntStatus;
	HANDLE hDupHandle;
	DWORD dwStartAddress;

	pNtQIT NtQueryInformationThread = (pNtQIT)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryInformationThread");
	if (NtQueryInformationThread == NULL) 
		return 0;
	HANDLE hCurrentProcess = GetCurrentProcess();
	if (!DuplicateHandle(hCurrentProcess, hThread, hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0))
	{
		SetLastError(ERROR_ACCESS_DENIED);
		return 0;
	}
	ntStatus = NtQueryInformationThread(hDupHandle, ThreadQuerySetWin32StartAddress, &dwStartAddress, sizeof(DWORD), NULL);
	CloseHandle(hDupHandle);
	//if (ntStatus != STATUS_SUCCESS) return 0;

	return dwStartAddress;
}

THREADENTRY32 ProcessClass::GetThreadListByPID(DWORD pid)
{
	THREADENTRY32 result = {};

	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, pid);
	if (snapshot != INVALID_HANDLE_VALUE) //Create snapshot of processes
	{
		THREADENTRY32 thread;// write here about find processes
		thread.dwSize = sizeof(THREADENTRY32);
		if (Thread32First(snapshot, &thread))
		{
			do {
				if (thread.th32OwnerProcessID != pid)
					continue;
				HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, thread.th32ThreadID);
				DWORD dwThreadStartAddress = GetThreadStartAddress(hThread);
				CloseHandle(hThread);
				//printf("Thread list by Pid: %d\n", thread.th32OwnerProcessID);
				//printf("TID: %d, Base Address: %x, Size: %x, Name: %x\n", thread.th32ThreadID, dwThreadStartAddress, thread.dwSize, thread.dwSize);
			} while (Thread32Next(snapshot, &thread));// find it
		}
		else
		{

		}
	}
	else
	{

	}

	CloseHandle(snapshot);

	return result;
}

 

На msdn NtQueryInformationThread пишут, что это функция может быть не доступна в будущих версиях, используйте альтернативу, а какую альтернативу там не написали)

Изменено пользователем helldrg
Ссылка на комментарий
Поделиться на другие сайты

9 minutes ago, helldrg said:

Спасибо большое!!! Этот момент я упустил!!!!!!
 

Да я понял что L подставляешь и пишешь строку, а почему юникодом надо пользоваться?)

ASCII табличка маленькая и в нее не все влезает. Например, какой-нибудь хинди или китайский традиционный - неа. Только латиница, только хардкор! Вопрос в том, так ли это надо. :D

Ссылка на комментарий
Поделиться на другие сайты

 

Цитата

 

ASCII табличка маленькая и в нее не все влезает. Например, какой-нибудь хинди или китайский традиционный - неа. Только латиница, только хардкор! Вопрос в том, так ли это надо. 

 

То есть Use Multi-Byte Character Set  это обозначает, что будет использоваться ASCII код? ASCII символ помещается в байт а UNICODE символ в 2 байта, на вики пишут что вроде уже 2 не достаточно

Ссылка на комментарий
Поделиться на другие сайты

10 минуту назад, helldrg сказал:

Да я понял что L подставляешь и пишешь строку, а почему юникодом надо пользоваться?)

2hWZg.png

+A версии постоянно хип юзают/конвертируют..

 

15 минуту назад, helldrg сказал:

NtQueryInformationThread

наверно имели ввиду GetThreadIOPendingFlag, зачем такое нужно в обычном трейнере :D

 

Ссылка на комментарий
Поделиться на другие сайты

Цитата

+A версии постоянно хип юзают/конвертируют..

Я так понял это плохо
Вот, к примеру раньше я делал так (переменные типа char*)
FindWindow(className, windowName);
Нужно теперь так делать:
FindWindowA(className, windowName);

Но так постоянно хип юзают/конвертируют.

Значит нужно оставить FindWindow(className, windowName); так, но поменять тип переменных?

Цитата

наверно имели ввиду GetThreadIOPendingFlag, зачем такое нужно в обычном трейнере :D

Да это не для трейнера =) Просто класс процесса делал, заодно с модулями и потоками решил поразбираться) GetThreadIOPendingFlag это наверное не то, он просто истину или ложь выводит, для поиска адреса или имени ничем не поможет

Ссылка на комментарий
Поделиться на другие сайты

13 минуты назад, helldrg сказал:

Значит нужно оставить FindWindow(className, windowName); так, но поменять тип переменных?

сначала в настройках компиля надо вкл, потом исправляешь. там PCWSTR наверно или что то похоже

  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

Цитата

сначала в настройках компиля надо вкл

Ну это понятно :DD

я так к char привык, этого хоть стоит?) Или может все таки  A версии оставить?)

 

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.