Ĺadny brzuch
- lSpotkałem się z kodem trainera (pod konsole, w C) do gry Enter The Matrix. Kod: (lub ze strony z kolorowaniem: http://rafb.net/past...s/O3J3TT38.html)#include <windows.h>
#include <tlhelp32.h>
#include <string.h>
#include <conio.h>
#include <stdio.h>
enum CHEAT_MASK{
MASK_INF_AMMO = 0x00000001,
MASK_ALL_WEAPONS = 0x00000002,
MASK_INVISIBILITY = 0x00000008,
MASK_INF_FOCUS = 0x00000020,
MASK_INF_HEALTH = 0x00000800,
MASK_FASTER_LOGOS = 0x00001000,
MASK_BONUS_LEVEL = 0x00002000
};
const DWORD dwAddress = 0x00972DC0;
DWORD GetMatrixPID1()
{
HANDLE hProcessSnap = NULL;
PROCESSENTRY32 pe32 = {0};
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
return 0;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap, &pe32))
{
BOOL bGotModule = FALSE;
PROCESSENTRY32 pe32 = {0};
pe32.dwSize = sizeof(PROCESSENTRY32);
if ( !Process32First(hProcessSnap, &pe32) )
return 0;
do
{
if ( !stricmp(pe32.szExeFile, "matrix.exe") )
return pe32.th32ProcessID;
}
while (Process32Next(hProcessSnap, &pe32));
}
else
return 0;
CloseHandle (hProcessSnap);
return 0;
}
DWORD GetMatrixPID2()
{
DWORD dwPID = 0;
HWND hWnd = FindWindow("ETM", NULL);
if ( hWnd )
GetWindowThreadProcessId(hWnd, &dwPID);
return dwPID;
}
void UpdateMenu(DWORD dwCheatMask)
{
char n=' ', y='Ĺą';
printf("[%c] - [1] Infinite Health\n", dwCheatMask & MASK_INF_HEALTH ? y : n);
printf("[%c] - [2] Infinite Focus\n", dwCheatMask & MASK_INF_FOCUS ? y : n);
printf("[%c] - [3] Infinite Ammo\n", dwCheatMask & MASK_INF_AMMO ? y : n);
printf("[%c] - [4] Get Enemy Weapons\n", dwCheatMask & MASK_ALL_WEAPONS ? y : n);
printf("[%c] - [5] Invisibility\n", dwCheatMask & MASK_INVISIBILITY ? y : n);
printf("[%c] - [6] Faster/Stronger Logos\n", dwCheatMask & MASK_FASTER_LOGOS ? y : n);
printf("\nCheat bit mask value is 0x%08X", dwCheatMask);
printf("\nPress 'Q' to exit the program...");
}
void main()
{
DWORD dwPid, dwCheat, dwOldCheat, dwAddr=0;
SetConsoleTitle("Enter The Matrix v1.52 Cheat Manager");
printf("Enter The Matrix v1.52 Cheat Manager - © 2003 CoDe RiPPeR\n\n");
if ( (dwPid = GetMatrixPID1())==0 )
dwPid = GetMatrixPID2();
HANDLE hProcess = OpenProcess(PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_VM_OPERATION, false, dwPid);
if ( !hProcess )
{
printf("Error opening game process...\n");
getchar();
return;
}
printf("Ĺą Opened process 'matrix.exe'...\n");
ReadProcessMemory(hProcess, (void *)dwAddress, &dwAddr, sizeof(DWORD), NULL);
if ( !dwAddr )
{
printf("Error reading game process...\n");
getchar();
return;
}
printf("Ĺą Successfully read memory at 0x%08X...\n", dwAddress);
dwAddr += 0x01E4;
printf("Ĺą Adding offset 0x000001E4...\n");
printf("Ĺą Reading memory at 0x%08X...\n", dwAddr);
ReadProcessMemory(hProcess, (void *)dwAddr, &dwCheat, sizeof(DWORD), NULL);
printf("Ĺą Successfully retreived cheat bit mask value 0x%08X...\n", dwCheat);
fflush(stdin);
printf("\n");
COORD pos;
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
pos.X = info.dwCursorPosition.X;
pos.Y = info.dwCursorPosition.Y;
UpdateMenu(dwCheat);
while ( true )
{
bool bQuit = false;
dwOldCheat = dwCheat;
while ( !_kbhit() )
{
if ( !ReadProcessMemory(hProcess, (void *)dwAddr, &dwCheat, sizeof(DWORD), NULL) )
{
printf("\n\nError reading process memory! Terminating...\n");
return;
}
if ( dwOldCheat != dwCheat )
{
dwOldCheat = dwCheat;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
UpdateMenu(dwCheat);
}
}
char ch=_getch();
fflush(stdin);
switch (ch)
{
case '1':
dwCheat ^= MASK_INF_HEALTH;
break;
case '2':
dwCheat ^= MASK_INF_FOCUS;
break;
case '3':
dwCheat ^= MASK_INF_AMMO;
break;
case '4':
dwCheat ^= MASK_ALL_WEAPONS;
break;
case '5':
dwCheat ^= MASK_INVISIBILITY;
break;
case '6':
dwCheat ^= MASK_FASTER_LOGOS;
break;
case 'Q':
case 'q':
dwCheat = 0;
bQuit = true;
}
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
UpdateMenu(dwCheat);
if ( dwCheat != dwOldCheat )
WriteProcessMemory(hProcess, (void *)dwAddr, &dwCheat, sizeof(DWORD), NULL);
if ( bQuit )
break;
}
CloseHandle(hProcess);
}Chciałem się dowiedzieć czy ktoś miał z tym styczność, pisał trainery, a może zna ktoś stronę z kursem/tutorialem/artukułem o pisaniu trainerów?
Czy ktoś umiałby tak uprościć ten kod, żeby się dało zrozumieć początkującemu programiście? I jakoś go przystępnie opisał co robi.
llCzy jeżeli znam adres komórki pamięci np. do ilości pieniędzy w jakiejś grze (to co mi znajdzie jakiś program do trainerów np. Cheat Engine, Last Hope, Magic Trainer Creator), to jak ją zmienić, żeby nie było naruszenia pamięci?
llPrzypuśćmy że pisze program, który przechowuje jakąś zmienną i chce zmienić tą wartość innym programem, czy to na tym samym polega co trainerowanie? Czy to już by był cracking?l
Ugh, nie znam się na tym za bardzo, ale się domyśłam, jak program działa. Na szczęście nie jest aż tak skomplikowany.
1) Najpierw odszukuje numer PID1, jeśli tego nie znajdzie, to PID2.
2)Następnie otwiera proces pod tym numerem, uzyskując tym samym dostęp do Matrixa ;)
3) Następnie odczytuje dane z pewnego miejsca w pamięci (dwAddress) do dwAddr,
4) po czym zwiększa jej wartość
6) i tak uzyskaniej wartości używa jeko miejsca w pamięci, z którego odczytuje następną wartość.
7) Następnie w tej wartości zmienia odpowiednie bity (operacją XOR), w zależności od tego, którego cheata wybrał user.
8) Na koniec podmienia tą wartość w pamięci gry. I voila!
Czyli, że ta liniijka const DWORD dwAddress = 0x00972DC0; to jest ten adres w pamięci który odpowiada za ten kod? I jeżeli podmienie zupełnie niektóre wartości to moge przerobić ten kod na trainera do innej gry? Czy ten kod jest "uniwersalny"? ;)
A PID1 i PID2 to jest tak jakby id otwartego procesu?
1) Nie ufaj teraz za bardzo temu, co mówię, bo mogę się mylić. Ale ten adres zdaje się wskazywać na wskaźnik, który wskazuje na coś, co można potraktować jako punkt odniesienia do znalezienia miejsca, w którym można wprowadzać cheaty. Tak więc ten adres może być uniwersalny, a pod nim znajdować się wskaźnik do zmiennych procesu. Ale to tylko moje domysły.
2) Tak
Rozumiem o co Ci chodzi. Czyli jeżeli to prawda to spróbuje napisać jakiegoś trainera, jak mi się uda to napiszę jak to zrobiłem. A jak ktoś by wiedział coś więcej to może tu napisać. Może to mi troche pomoże.
W każdej grze te dane są umieszczone w innych miejscach i zapewne podaje się im inne wartości, twórcy trainerów używają debuggerów, żeby te miejsca znaleźć ;)
Chcesz koniecznie napisać swój własny program? Bo jeśli nie, to np Cheat Engine ma taką opcje która pozwala na stworzenie oddzielnego exeka do konkretnej gry, wystarczy kliknąć na "advanced options" na dole okienka...
W każdej grze te dane są umieszczone w innych miejscach i zapewne podaje się im inne wartości, twórcy trainerów używają debuggerów, żeby te miejsca znaleźć ;) Wiem, że tak można, ale to nie dla mnie. (30 minut siedziałem z zadaniem z tdhack.com (z softu) i nic nie znalazłem ;) Dopiero Notatnik mi pomógł)
Przykładowo dla GTA SA adres dla pieniędzy to 0x0B7CE50, ale coś mi się nie kompiluje program. Gdyby działał to by wystarczyło podmienić wartość pod tym adresem i by był git.
Chcesz koniecznie napisać swój własny program? Bo jeśli nie, to np Cheat Engine ma taką opcje która pozwala na stworzenie oddzielnego exeka do konkretnej gry, wystarczy kliknąć na "advanced options" na dole okienka... Tak, chce swój program, bo jest wtedy większa satysfakcja. Ale Cheat Engine znam i używam go do takich celów. Ale postanowiłem napisać swój własny :D.
Ale twoja wskazówka też mi pomoże.