📜 ⬆️ ⬇️

WarCraft III / Dota in brief about creating a cheat

Good day. The last article about the principle of creating a cheat interested many. Guided by this, I suggested that someone might be interested in another way to create such programs. Before you begin, I will say: “Everything described below is you, if you decide to apply it in practice, use it at your own peril and risk. Everything described here is given exclusively for general development. ”
For example, we will use the standard "fish" for such programs / trainers. The whole principle of operation is to find the addresses / offsets we need in the program memory and change their values ​​to their own.

And so, for a start we will need:
ArtMoney / TSearch - to search for values.
ollydbg - debager for address search.
Watch the video:



I explain:
1) Initially, we find the address in the memory of the game, which stores the flag that is responsible for the condition to show / hide the unit.
2) Next, in debugger, we find this address and put a stopping point on its call. Go to where it happened. Create a micro crash. Copy the values ​​(highlighted in red) - this is what we have to write to the program's memory when a cheat is activated - 6F3A1563 66: B9 0F00.
66: B9 0F00 this is our magic bytes, we write them as 0x66 0xB9 0x0F 0x00 . And we write in 6F3A1563 with an offset of one.
')
Find the window handle and set privileges for our marker.

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); ... } 


You can then modify the memory

 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); 


For convenience, you can transfer addresses relative to the Game.dll library, which can increase the lifespan of our program without rebuilding - if other libraries are updated in the game. For this you need to know her address.

 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); ... 


That's basically it.

Source: https://habr.com/ru/post/144453/


All Articles