helldrg Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 (изменено) Всем привет! До пилил наконец то кое как свой трейнер для игры 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, "Ошибка!"); Так как я понимаю, что все таки не правильно что то делаю. Хороший, качественный и чистый код не должен так выглядеть, поэтому я немного расстроился =) и решил подождать новых уроков от вашего сообщества, так как я люблю программирование, но вот такое программирование меня утомляет. Может кто то играет в эту игру ему пригодится этот трейнер. Его возможности можно увидеть на скрине: Далее я попробую этот чит сделать в стиле metro, так как стандартными средствами winapi очень трудно добиться такого результата. Ну и если трейнер соберет больше 10 лайков, то я добавлю, то, что в последний момент урезал (по разным причинам: не доделал, доделал, но выглядит код ужасно как выше приведенный код и просто поленился) следующие функции: - активацию опции по нажатию клавиш; - описание трейнера в пункте об трейнере, который должен быть на серой полоске; - опцию map hack - опцию режим Бога - ползунок для изменения положения камеры по оси Z (в настоящее время она отдаляется на 600 условных едениц, по стандарту стоит приблизительно 300) - и на последок завезу оптимизацию, то есть проц будет нагружиться приблизительно в 15 раз меньше, во всяком случае на моем компьютере, то есть сделаю чтобы основной цикл программы проходил 30 раз за секунду, а не как сейчас несколько тысяч раз PS:Последний абзац написан в лучших традициях байта на лайки :DDDDDD Ох да, чуть не забыл скинуть программу =) Трейнер будет доступен 90 дней с момента публикацииhttp://rgho.st/89Jw7rhCm Особые благодарности: kenq - за отличные видеоуроки и Dino - за невероятно доступное, понятное объяснение непонятных мне аспектов Изменено 9 октября, 2016 пользователем helldrg 5 Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 4 часа назад, helldrg сказал: Ну и если трейнер соберет больше 10 лайков Добавлю свою долю лайков. 4 часа назад, helldrg сказал: то я добавлю, то, что в последний момент урезал Конечно пилите дальше. Тем более, что Вам нравиться программировать: 4 часа назад, helldrg сказал: так как я люблю программирование ЗЫ: 4 часа назад, helldrg сказал: До пилил наконец то кое как свой трейнер для игры C&C:Generals v1.8 С почином!!! 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 Предлагаю @helldrg переводить потихоньку в разработчики. PS: Никогда бы не подумал, что в моем нике можно ошибиться. 2 Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 28 минуты назад, keng сказал: Никогда бы не подумал, что в моем нике можно ошибиться. 29 минуты назад, keng сказал: Предлагаю @helldrg переводить потихоньку в разработчики. Я - за. 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
LIRW Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 Человек старался и я поставлю! Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 9 октября, 2016 Автор Поделиться Опубликовано 9 октября, 2016 Цитата PS: Никогда бы не подумал, что в моем нике можно ошибиться. аахахах извиняюсь, уже поздно было, спать хотелось Спасибо всем, приятное сообщество здесь =) Ссылка на комментарий Поделиться на другие сайты Поделиться
gmz Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 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 Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 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 Я хочу посмотреть на твой первый трейнер, нет, серьезно. Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 Только что, keng сказал: Я хочу посмотреть на твой первый трейнер, нет, серьезно. gmz, кстати я тоже бы с удовольствием посмотрел на него (если конечно сохранился), причём с твоими теперешними замечаниями. Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 9 октября, 2016 Автор Поделиться Опубликовано 9 октября, 2016 Цитата в 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 я цвет текста замучался менять, а тут шрифт) Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 9 октября, 2016 Автор Поделиться Опубликовано 9 октября, 2016 Ты наверно про это 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 Ссылка на комментарий Поделиться на другие сайты Поделиться
gmz Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 8 минут назад, keng сказал: Я хочу посмотреть на твой первый трейнер, нет, серьезно. 6 минут назад, Garik66 сказал: gmz, кстати я тоже бы с удовольствием посмотрел на него (если конечно сохранился), причём с твоими теперешними замечаниями. он был похож на это только на масм32 +замена линкера +бредооптимиз. весил ~2.7кб (пак) и самый большой косяк - мерцание текста когда вкл/откл а еще рекордный был на вирьтотал - 47+ детектов 8 минут назад, helldrg сказал: А можно по подробней? L"blabla" 9 минут назад, helldrg сказал: Вот это я немного не понял https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms684839(v=vs.85).aspx 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 Только что, gmz сказал: он был похож на это только на масм32 +замена линкера +бредооптимиз. весил ~2.7кб (пак) и самый большой косяк - мерцание текста когда вкл/откл а еще рекордный был на вирьтотал - 47+ детектов Спасибо - за самокритику, хорошо что и себя критикуешь тоже. Ссылка на комментарий Поделиться на другие сайты Поделиться
gmz Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 13 минуты назад, helldrg сказал: Я так делал потому что имя модуля в MODULEENTRY32 хранится вместе с путем, можно было сроку обработать и получить только имя, но я просто воспользовался этой функцией GetModuleBaseName там есть szModule Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 9 октября, 2016 Автор Поделиться Опубликовано 9 октября, 2016 Цитата https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms684839(v=vs.85).aspx Я знаю что структура содержит, я не знаю что такое K32GetModuleBaseName. Я так понял это другое определение GetModuleBaseName в какой то версии psapi, но почему вы так назвали эту функцию? Запутать хотели ?)) Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 9 октября, 2016 Автор Поделиться Опубликовано 9 октября, 2016 Цитата там есть szModule Спасибо большое!!! Этот момент я упустил!!!!!! Цитата unicode билд обязательно (все равно на вин98 не запустится) Да я понял что L подставляешь и пишешь строку, а почему юникодом надо пользоваться?) Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 9 октября, 2016 Автор Поделиться Опубликовано 9 октября, 2016 (изменено) 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 пишут, что это функция может быть не доступна в будущих версиях, используйте альтернативу, а какую альтернативу там не написали) Изменено 9 октября, 2016 пользователем helldrg Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 9 октября, 2016 Автор Поделиться Опубликовано 9 октября, 2016 А так же я не вывел имена потоков, оставил до лучших времен, так как THREADENTRY32, я так понял не содержит имени Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 9 minutes ago, helldrg said: Спасибо большое!!! Этот момент я упустил!!!!!! Да я понял что L подставляешь и пишешь строку, а почему юникодом надо пользоваться?) ASCII табличка маленькая и в нее не все влезает. Например, какой-нибудь хинди или китайский традиционный - неа. Только латиница, только хардкор! Вопрос в том, так ли это надо. Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 9 октября, 2016 Автор Поделиться Опубликовано 9 октября, 2016 Цитата ASCII табличка маленькая и в нее не все влезает. Например, какой-нибудь хинди или китайский традиционный - неа. Только латиница, только хардкор! Вопрос в том, так ли это надо. То есть Use Multi-Byte Character Set это обозначает, что будет использоваться ASCII код? ASCII символ помещается в байт а UNICODE символ в 2 байта, на вики пишут что вроде уже 2 не достаточно Ссылка на комментарий Поделиться на другие сайты Поделиться
gmz Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 10 минуту назад, helldrg сказал: Да я понял что L подставляешь и пишешь строку, а почему юникодом надо пользоваться?) +A версии постоянно хип юзают/конвертируют.. 15 минуту назад, helldrg сказал: NtQueryInformationThread наверно имели ввиду GetThreadIOPendingFlag, зачем такое нужно в обычном трейнере Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 9 октября, 2016 Автор Поделиться Опубликовано 9 октября, 2016 Цитата +A версии постоянно хип юзают/конвертируют.. Я так понял это плохо Вот, к примеру раньше я делал так (переменные типа char*) FindWindow(className, windowName); Нужно теперь так делать: FindWindowA(className, windowName); Но так постоянно хип юзают/конвертируют. Значит нужно оставить FindWindow(className, windowName); так, но поменять тип переменных? Цитата наверно имели ввиду GetThreadIOPendingFlag, зачем такое нужно в обычном трейнере Да это не для трейнера =) Просто класс процесса делал, заодно с модулями и потоками решил поразбираться) GetThreadIOPendingFlag это наверное не то, он просто истину или ложь выводит, для поиска адреса или имени ничем не поможет Ссылка на комментарий Поделиться на другие сайты Поделиться
gmz Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 13 минуты назад, helldrg сказал: Значит нужно оставить FindWindow(className, windowName); так, но поменять тип переменных? сначала в настройках компиля надо вкл, потом исправляешь. там PCWSTR наверно или что то похоже 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 9 октября, 2016 Автор Поделиться Опубликовано 9 октября, 2016 Цитата сначала в настройках компиля надо вкл Ну это понятно :DD я так к char привык, этого хоть стоит?) Или может все таки A версии оставить?) Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 9 октября, 2016 Поделиться Опубликовано 9 октября, 2016 12 часа назад, keng сказал: Предлагаю @helldrg переводить потихоньку в разработчики. Done. helldrg, велкам в группу Разработчики Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения