Добрый день. Прошлая заметка о принципе создания чита, заинтересовала многих. Руководствуясь этим я предположил, что кому-то может оказаться интересным другой способ создания подобных программ. Перед тем как начать скажу: «Все ниже описанное Вы, если решите применить на деле, используете на свой страх и риск».
Для примера будем использовать стандартную «рыбу» для подобных программ/трейнеров. Весь принцип работы заключается в нахождении нужных нам адресов/смещений в память программы и изменении их значений на свои.
И так, для начала нам понадобятся:
ArtMoney/TSearch — для поиска значений.
ollydbg — дебагер для поиска адресов.
Посмотреть ролик:
Разъясняю:
1) Первоначально находим адрес в памяти игры, по которому хранится флаг отвечающий за условие показывать/скрыть юнита.
2) Далее, в дебагере, находим этот адрес и ставим точку остановки на его вызов. Переходим туда откуда это произошло. Создаем микро сбой. Копируем значения (выделенные красным) — это и есть то, что мы должны записывать в память программы при активации чита — 6F3A1563 66:B9 0F00.
66:B9 0F00 это и есть наши волшебные байты, запишем их как 0x66 0xB9 0x0F 0x00. И запишем в 6F3A1563 со смещением на единицу.
Находим дескриптор окна и устанавливаем привилегии для нашего маркера.
LPSTR gameWindowTitle = "Warcraft III";
HWND hWnd=::FindWindow(NULL, gameWindowTitle);
if (hWnd != NULL)
{
HANDLE currentProccess = GetCurrentProcess();
HANDLE token;
BOOL retValue = OpenProcessToken(currentProccess, 40, &token);
LUID luid;
LPSTR debugPrivilege = "SeDebugPrivilege";
retValue = LookupPrivilegeValue(NULL, debugPrivilege, &luid);
TOKEN_PRIVILEGES newState, preState;
DWORD returnLength;
newState.PrivilegeCount = 1;
newState.Privileges[0].Luid = luid;
newState.Privileges[0].Attributes = 2;
retValue = AdjustTokenPrivileges(token, FALSE, &newState, 28, &preState, &returnLength);
DWORD PID;
DWORD TID = ::GetWindowThreadProcessId(hWnd, &PID);
openedProccess = OpenProcess(
PROCESS_ALL_ACCESS |
PROCESS_TERMINATE |
PROCESS_VM_OPERATION |
PROCESS_VM_READ|
PROCESS_VM_WRITE,
FALSE,
PID);
...
}
Далее можно модифицировать память
DWORD data = 0x66;
WriteProcessMemory(openedProccess, (LPVOID)(6F3A1563), &data, 1, 0);
data = 0xB9;
WriteProcessMemory(openedProccess, (LPVOID)(6F3A1564), &data, 1, 0);
data = 0x0F;
WriteProcessMemory(openedProccess, (LPVOID)(6F3A1565), &data, 1, 0);
data = 0x00;
WriteProcessMemory(openedProccess, (LPVOID)(6F3A1566), &data, 1, 0);
Для удобства можно передать адреса относительно библиотеки Game.dll, что может увеличить срок жизни нашей программы без перезборки — если в игре будут обновлены другие библиотеки. Для этого нужно знать ее адрес
DWORD GetModuleBase(HANDLE hProc, LPSTR sModuleName)
{
HMODULE hMods[8];
DWORD cbNeeded;
unsigned int i;
if(EnumProcessModules(hProc, hMods, sizeof(hMods), &cbNeeded))
{
for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
{
TCHAR szModName[MAX_PATH];
if ( GetModuleBaseName(hProc, hMods[i], szModName,
sizeof(szModName) / sizeof(TCHAR)))
{
if(strstr(szModName, sModuleName))
{
return (DWORD)hMods[i];
}
_tprintf( TEXT("t%s (0x%08X)n"), szModName, hMods[i] );
}
}
}
return 0x00;
}
bool WriteData(DWORD address, DWORD data)
{
return WriteProcessMemory(openedProccess, (LPVOID)(gameOffset + address), &data, 1, 0);
}
...
LPSTR gameLibraryName = "Game.dll";
gameOffset = GetModuleBase(openedProccess, gameLibraryName);
...
Вот в принципе и все.
В качестве бонуса пучок адресов:
Game.dll = 0x6F000000;
Reveal Units on Main Map
Game.dll + 0x3A14F0 = 0x87
Game.dll + 0x3A14F1 = 0xDB
Game.dll + 0x3A159B = 0x87
Game.dll + 0x3A159C = 0xDB
Remove FOG on Main Map
Game.dll + 0x74CA1A = 0x15
Game.dll + 0x74CA1B = 0x50
Reveal Units on Mini Map
Game.dll + 0x36143B = 0x33
Game.dll + 0x36143C = 0xC0
Game.dll + 0x36143D = 0x90
Game.dll + 0x36143E = 0x90
Game.dll + 0x36143F = 0x90
Remove FOG on Mini Map
Game.dll + 0x356525 = 0x87
Game.dll + 0x356526 = 0xDB
Enable Trade
Game.dll + 0x34DDA2 = 0xB8
Game.dll + 0x34DDA3 = 0xC8
Game.dll + 0x34DDA4 = 0x00
Game.dll + 0x34DDA5 = 0x00
Game.dll + 0x34DDA7 = 0x90
Game.dll + 0x34DDAA = 0xB8
Game.dll + 0x34DDAB = 0x64
Game.dll + 0x34DDAC = 0x00
Game.dll + 0x34DDAD = 0x00
Game.dll + 0x34DDAF = 0x90
Make Units Clickable
Game.dll + 0x28519C = 0x87
Game.dll + 0x28519D = 0xDB
Game.dll + 0x93645E = 0x1C
Game.dll + 0x93645F = 0x45
Reveal Illusions
Game.dll + 0x282A5C = 0x90
Game.dll + 0x282A5D = 0x40
Game.dll + 0x282A5E = 0xC3
Reveal Invisibles
Game.dll + 0x399A98 = 0x71
Show Runes
Game.dll + 0x3A14DB = 0x71
Show Skills / Cooldowns
Game.dll + 0x2026DC = 0x87
Game.dll + 0x2026DD = 0xDB
Game.dll + 0x2026DE = 0x87
Game.dll + 0x2026DF = 0xDB
Game.dll + 0x2026E0 = 0x87
Game.dll + 0x2026E1 = 0xDB
Game.dll + 0x28E1DE = 0x71
Game.dll + 0x34F2A8 = 0x87
Game.dll + 0x34F2A9 = 0xDB
Game.dll + 0x34F2E9 = 0x00
Автор: Zanoza