[Tutorial] Gamehacking 101
by Toymaker
To Get Started:
- Download Cheat Engine
- Download OllyDBG ver 10
- Download Game (Attached)
- Download Bloodshev Dev-C++
Step 1.
You should understand what you're looking for by playing the game once. You'll notice you and your opponent fight until someone runs out of health points so a good hack feature would be preventing your health from decreasing. I'll paste the code for the game as well so you can get an idea of how programs break down into ASM in memory.
Code:
#include <iostream>
using namespace std;
int uhp = 100;
int usp = 10;
int mp = 100;
int ms = 10;
int turn = 1;
int atk;
int dmg;
int main() {
system("title TBG");
while ( uhp > 0 ) {
//if findwindow here would own haha =D have
to be hacked etc
if ( turn == 1 ) {
turn--;
cout<<"It is YOUR turn hero.n";
cout<<"Your HP is: "<<uhp<<"n";
cout<<"Your SP is: "<<usp<<"n";
cout<<"Decide Your Next Moven";
cout<<"1. Punch(10 DMG 0 SP)n";
cout<<"2. Psyki(20 DMG 5 SP)n";
cin>>atk;
if ( atk == 1 ) {
dmg = 10;
cout<<"You do: "<<dmg<<" DMGn";
mp = mp - dmg;
cout<<"Monstr Life: "<<mp<<"n";
}
else {
dmg = 20;
cout<<"You do: "<<dmg<<" DMGn";
mp = mp - dmg;
usp = usp - 5;
cout<<"Monstr Life: "<<mp<<"n";
}
if ( turn == 0 ) {
turn++;
cout<<"Computer AIs Turnn";
cout<<"Computer Hits Youn";
cout<<"Suffer: 10 Damagen";
uhp = uhp - 10;
cout<<"New HP: "<<uhp<<"n";
}
if ( mp < 5 ) {
cout<<"You Just Wonn";
system("pause");
exit(0);
}
}
}
cout<<"Thanks For Playinn";
system("pause");
}
Step 2. Now that you've played the game and even got an extra boost by seeing it's C++ encoding. It's time to start hacking.
Load The Game and Cheat Engine.You need to, in cheat engine, select 'Process' option in the file menu and attach the game -TBG.exe. You are now ready to start tracing
memory. In the game you see:
It is YOUR turn hero.
Your HP is: 100
Your SP is: 10
Decide Your Next Move
1. Punch(10 DMG 0 SP)
2. Psyki(20 DMG 5 SP)
You should go ahead and select 1 and press enter. You notice you attack the opponent and his health lowers and he automatically attacks you back and you lose health.
You are at 90 HP now. In cheat engine in the
VALUE: textbox, enter 90 and press enter. On the left of cheat engine you'll notice four addresses appear:
0043F000 90
0043F008 90
77C60094 90
77C626FA 90
You want to go back to the game and take damage two more times so you're sure which of these addresses are specifically holding your health points. If you just keep selecting 1 you'll take equal damage but if you press 2 the enemy loses 20hp and you only lose 10hp still. You'll see your health address is:
Double click it so it appears at the bottom of your Cheat Engine. Right click the adress and select 'find out what writes to this address,' and press
'YES.' A box pops up, go back to the game and hit the enemy again to get hit. Come back and you see:
You've know found the actual offset in game memory that handles your health decreasing. Instead of just the address holding your health's value which in most games will be different everytime you load the game thanks to Dynamic Memory Allocation. You notice SUB means subtract and 0A is hexadecimal for 10 Decimal?
Now, close everything, re-open the game, open OllyDBG, file - attach - TBG.exe.
Step 3. In OllyDBG with the TBG.exe attached. Press the [<<] black button at the top below 'File' that is labeled 'REWIND,' and select 'OK.' You have no rewound the program and logged it's loading memory. You simply need to scroll down a little ways in Olly and you find the C++ Main() function where
it's all coded!
Code:
00401390 /$ 55 PUSH EBP
00401391 |. 89E5 MOV EBP,ESP
00401393 |. 83EC 18 SUB ESP,18
00401396 |. 83E4 F0 AND
ESP,FFFFFFF0
00401399 |. B8 00000000 MOV EAX,0
0040139E |. 83C0 0F ADD EAX,0F
004013A1 |. 83C0 0F ADD EAX,0F
004013A4 |. C1E8 04 SHR EAX,4
004013A7 |. C1E0 04 SHL EAX,4
004013AA |. 8945 FC MOV DWORD PTR
SS:[EBP-4],EAX
004013AD |. 8B45 FC MOV EAX,DWORD
PTR SS:[EBP-4]
004013B0 |. E8 ABBF0000 CALL
TBG.0040D360
004013B5 |. E8 E6BB0000 CALL
TBG.0040CFA0
004013BA |. C70424 00004400 MOV DWORD PTR
SS:[ESP],TBG.00440000 ; |ASCII "title
TBG"
004013C1 |. E8 9AF50000 CALL
<JMP.&msvcrt.system> ;
system
004013C6 |> 833D 00F04300 00 /CMP DWORD PTR
DS:[43F000],0
004013CD |. 0F8E C1020000 |JLE
TBG.00401694
004013D3 |. 833D 10F04300 01 |CMP DWORD PTR
DS:[43F010],1
004013DA |.^75 EA |JNZ SHORT
TBG.004013C6
004013DC |. FF0D 10F04300 |DEC DWORD PTR
DS:[43F010]
004013E2 |. C74424 04 0A004400 |MOV DWORD PTR
SS:[ESP+4],TBG.0044000A ; ASCII "It is
YOUR turn hero.
"
004013EA |. C70424 D0334400 |MOV DWORD PTR
SS:[ESP],TBG.004433D0
004013F1 |. E8 52AF0300 |CALL
TBG.0043C348
004013F6 |. C74424 04 21004400 |MOV DWORD PTR
SS:[ESP+4],TBG.00440021 ; ASCII "Your
HP is: "
004013FE |. C70424 D0334400 |MOV DWORD PTR
SS:[ESP],TBG.004433D0
00401405 |. E8 3EAF0300 |CALL
TBG.0043C348
0040140A |. 89C2 |MOV EDX,EAX
0040140C |. A1 00F04300 |MOV EAX,DWORD
PTR DS:[43F000]
00401411 |. 894424 04 |MOV DWORD PTR
SS:[ESP+4],EAX
00401415 |. 891424 |MOV DWORD PTR
SS:[ESP],EDX
00401418 |. E8 C39C0200 |CALL
TBG.0042B0E0
0040141D |. C74424 04 2E004400 |MOV DWORD PTR
SS:[ESP+4],TBG.0044002E
00401425 |. 890424 |MOV DWORD PTR
SS:[ESP],EAX
00401428 |. E8 1BAF0300 |CALL
TBG.0043C348
0040142D |. C74424 04 30004400 |MOV DWORD PTR
SS:[ESP+4],TBG.00440030 ; ASCII "Your
SP is: "
00401435 |. C70424 D0334400 |MOV DWORD PTR
SS:[ESP],TBG.004433D0
0040143C |. E8 07AF0300 |CALL
TBG.0043C348
00401441 |. 89C2 |MOV EDX,EAX
00401443 |. A1 04F04300 |MOV EAX,DWORD
PTR DS:[43F004]
00401448 |. 894424 04 |MOV DWORD PTR
SS:[ESP+4],EAX
0040144C |. 891424 |MOV DWORD PTR
SS:[ESP],EDX
0040144F |. E8 8C9C0200 |CALL
TBG.0042B0E0
00401454 |. C74424 04 2E004400 |MOV DWORD PTR
SS:[ESP+4],TBG.0044002E
0040145C |. 890424 |MOV DWORD PTR
SS:[ESP],EAX
0040145F |. E8 E4AE0300 |CALL
TBG.0043C348
00401464 |. C74424 04 3D004400 |MOV DWORD PTR
SS:[ESP+4],TBG.0044003D ; ASCII "Decide
Your Next Move
"
0040146C |. C70424 D0334400 |MOV DWORD PTR
SS:[ESP],TBG.004433D0
00401473 |. E8 D0AE0300 |CALL
TBG.0043C348
00401478 |. C74424 04 54004400 |MOV DWORD PTR
SS:[ESP+4],TBG.00440054 ; ASCII "1.
Punch(10 DMG 0 SP)
"
00401480 |. C70424 D0334400 |MOV DWORD PTR
SS:[ESP],TBG.004433D0
00401487 |. E8 BCAE0300 |CALL
TBG.0043C348
0040148C |. C74424 04 6B004400 |MOV DWORD PTR
SS:[ESP+4],TBG.0044006B ; ASCII "2.
Psyki(20 DMG 5 SP)
"
00401494 |. C70424 D0334400 |MOV DWORD PTR
SS:[ESP],TBG.004433D0
0040149B |. E8 A8AE0300 |CALL
TBG.0043C348
004014A0 |. C74424 04 10304400 |MOV DWORD PTR
SS:[ESP+4],TBG.00443010
004014A8 |. C70424 70344400 |MOV DWORD PTR
SS:[ESP],TBG.00443470
004014AF |. E8 5C6F0200 |CALL
TBG.00428410
004014B4 |. 833D 10304400 01 |CMP DWORD PTR
DS:[443010],1
004014BB |. 0F85 88000000 |JNZ
TBG.00401549
004014C1 |. C705 14304400 0A000000 |MOV DWORD PTR
DS:[443014],0A
004014CB |. C74424 04 82004400 |MOV DWORD PTR
SS:[ESP+4],TBG.00440082 ; ASCII "You
do: "
004014D3 |. C70424 D0334400 |MOV DWORD PTR
SS:[ESP],TBG.004433D0
004014DA |. E8 69AE0300 |CALL
TBG.0043C348
004014DF |. 89C2 |MOV EDX,EAX
004014E1 |. A1 14304400 |MOV EAX,DWORD
PTR DS:[443014]
004014E6 |. 894424 04 |MOV DWORD PTR
SS:[ESP+4],EAX
004014EA |. 891424 |MOV DWORD PTR
SS:[ESP],EDX
004014ED |. E8 EE9B0200 |CALL
TBG.0042B0E0
004014F2 |. C74424 04 8B004400 |MOV DWORD PTR
SS:[ESP+4],TBG.0044008B ; ASCII " DMG
"
004014FA |. 890424 |MOV DWORD PTR
SS:[ESP],EAX
004014FD |. E8 46AE0300 |CALL
TBG.0043C348
00401502 |. A1 14304400 |MOV EAX,DWORD
PTR DS:[443014]
00401507 |. 2905 08F04300 |SUB DWORD PTR
DS:[43F008],EAX
0040150D |. C74424 04 91004400 |MOV DWORD PTR
SS:[ESP+4],TBG.00440091 ; ASCII "Monstr
Life: "
00401515 |. C70424 D0334400 |MOV DWORD PTR
SS:[ESP],TBG.004433D0
0040151C |. E8 27AE0300 |CALL
TBG.0043C348
00401521 |. 89C2 |MOV EDX,EAX
00401523 |. A1 08F04300 |MOV EAX,DWORD
PTR DS:[43F008]
00401528 |. 894424 04 |MOV DWORD PTR
SS:[ESP+4],EAX
0040152C |. 891424 |MOV DWORD PTR
SS:[ESP],EDX
0040152F |. E8 AC9B0200 |CALL
TBG.0042B0E0
00401534 |. C74424 04 2E004400 |MOV DWORD PTR
SS:[ESP+4],TBG.0044002E
0040153C |. 890424 |MOV DWORD PTR
SS:[ESP],EAX
0040153F |. E8 04AE0300 |CALL
TBG.0043C348
00401544 |. E9 8A000000 |JMP
TBG.004015D3
00401549 |> C705 14304400 14000000 |MOV DWORD PTR
DS:[443014],14
00401553 |. C74424 04 82004400 |MOV DWORD PTR
SS:[ESP+4],TBG.00440082 ; ASCII "You
do: "
0040155B |. C70424 D0334400 |MOV DWORD PTR
SS:[ESP],TBG.004433D0
00401562 |. E8 E1AD0300 |CALL
TBG.0043C348
00401567 |. 89C2 |MOV EDX,EAX
00401569 |. A1 14304400 |MOV EAX,DWORD
PTR DS:[443014]
0040156E |. 894424 04 |MOV DWORD PTR
SS:[ESP+4],EAX
00401572 |. 891424 |MOV DWORD PTR
SS:[ESP],EDX
00401575 |. E8 669B0200 |CALL
TBG.0042B0E0
0040157A |. C74424 04 8B004400 |MOV DWORD PTR
SS:[ESP+4],TBG.0044008B ; ASCII " DMG
"
00401582 |. 890424 |MOV DWORD PTR
SS:[ESP],EAX
00401585 |. E8 BEAD0300 |CALL
TBG.0043C348
0040158A |. A1 14304400 |MOV EAX,DWORD
PTR DS:[443014]
0040158F |. 2905 08F04300 |SUB DWORD PTR
DS:[43F008],EAX
00401595 |. 832D 04F04300 05 |SUB DWORD PTR
DS:[43F004],5
0040159C |. C74424 04 91004400 |MOV DWORD PTR
SS:[ESP+4],TBG.00440091 ; ASCII "Monstr
Life: "
004015A4 |. C70424 D0334400 |MOV DWORD PTR
SS:[ESP],TBG.004433D0
004015AB |. E8 98AD0300 |CALL
TBG.0043C348
004015B0 |. 89C2 |MOV EDX,EAX
004015B2 |. A1 08F04300 |MOV EAX,DWORD
PTR DS:[43F008]
004015B7 |. 894424 04 |MOV DWORD PTR
SS:[ESP+4],EAX
004015BB |. 891424 |MOV DWORD PTR
SS:[ESP],EDX
004015BE |. E8 1D9B0200 |CALL
TBG.0042B0E0
004015C3 |. C74424 04 2E004400 |MOV DWORD PTR
SS:[ESP+4],TBG.0044002E
004015CB |. 890424 |MOV DWORD PTR
SS:[ESP],EAX
004015CE |. E8 75AD0300 |CALL
TBG.0043C348
004015D3 |> 833D 10F04300 00 |CMP DWORD PTR
DS:[43F010],0
004015DA |. 75 7F |JNZ SHORT
TBG.0040165B
004015DC |. FF05 10F04300 |INC DWORD PTR
DS:[43F010]
004015E2 |. C74424 04 9F004400 |MOV DWORD PTR
SS:[ESP+4],TBG.0044009F ; ASCII
"Computer AIs Turn
"
004015EA |. C70424 D0334400 |MOV DWORD PTR
SS:[ESP],TBG.004433D0
004015F1 |. E8 52AD0300 |CALL
TBG.0043C348
004015F6 |. C74424 04 B2004400 |MOV DWORD PTR
SS:[ESP+4],TBG.004400B2 ; ASCII
"Computer Hits You
"
004015FE |. C70424 D0334400 |MOV DWORD PTR
SS:[ESP],TBG.004433D0
00401605 |. E8 3EAD0300 |CALL
TBG.0043C348
0040160A |. C74424 04 C5004400 |MOV DWORD PTR
SS:[ESP+4],TBG.004400C5 ; ASCII
"Suffer: 10 Damage
"
00401612 |. C70424 D0334400 |MOV DWORD PTR
SS:[ESP],TBG.004433D0
00401619 |. E8 2AAD0300 |CALL
TBG.0043C348
0040161E |. 832D 00F04300 0A |SUB DWORD PTR
DS:[43F000],0A
00401625 |. C74424 04 D8004400 |MOV DWORD PTR
SS:[ESP+4],TBG.004400D8 ; ASCII "New
HP: "
0040162D |. C70424 D0334400 |MOV DWORD PTR
SS:[ESP],TBG.004433D0
00401634 |. E8 0FAD0300 |CALL
TBG.0043C348
00401639 |. 8B15 00F04300 |MOV EDX,DWORD
PTR DS:[43F000]
0040163F |. 895424 04 |MOV DWORD PTR
SS:[ESP+4],EDX
00401643 |. 890424 |MOV DWORD PTR
SS:[ESP],EAX
00401646 |. E8 959A0200 |CALL
TBG.0042B0E0
0040164B |. C74424 04 2E004400 |MOV DWORD PTR
SS:[ESP+4],TBG.0044002E
00401653 |. 890424 |MOV DWORD PTR
SS:[ESP],EAX
00401656 |. E8 EDAC0300 |CALL
TBG.0043C348
0040165B |> 833D 08F04300 04 |CMP DWORD PTR
DS:[43F008],4
00401662 |.^0F8F 5EFDFFFF JG
TBG.004013C6
00401668 |. C74424 04 E1004400 MOV DWORD PTR
SS:[ESP+4],TBG.004400E1 ; ASCII "You
Just Won"
00401670 |. C70424 D0334400 MOV DWORD PTR
SS:[ESP],TBG.004433D0
00401677 |. E8 CCAC0300 CALL
TBG.0043C348
0040167C |. C70424 EF004400 MOV DWORD PTR
SS:[ESP],TBG.004400EF ; ||ASCII
"pause"
00401683 |. E8 D8F20000 CALL
<JMP.&msvcrt.system> ;
|system
00401688 |. C70424 00000000 MOV DWORD PTR
SS:[ESP],0 ; |
0040168F |. E8 BCF20000 CALL
<JMP.&msvcrt.exit> ;
exit
00401694 |> C74424 04 F5004400 MOV DWORD PTR
SS:[ESP+4],TBG.004400F5 ; ASCII
"Thanks For Playin
"
0040169C |. C70424 D0334400 MOV DWORD PTR
SS:[ESP],TBG.004433D0
004016A3 |. E8 A0AC0300 CALL
TBG.0043C348
004016A8 |. C70424 EF004400 MOV DWORD PTR
SS:[ESP],TBG.004400EF ; |ASCII
"pause"
004016AF |. E8 ACF20000 CALL
<JMP.&msvcrt.system> ;
system
004016B4 |. B8 00000000 MOV EAX,0
004016B9 |. C9 LEAVE
004016BA . C3 RETN
Step 4. You are now looking at the assembly version of your C++ coding in memory execution. You notice key parts are labeld with ASCII ; such as 'Monster Life.' I just wanted to show you this rewind trick but really now what you need to do is press CTLR+G so the 'Goto Expression' box pops up. Enter that offset we found and press search:
0040161E |. 832D 00F04300 0A |SUB DWORD PTR
DS:[43F000],0A
You are now at that location and we will be testing a hack method. How about instead of losing (SUBtracing) health your game increases (ADDing) your health each time you're attacked? Simply press the space bar, with this line highlighted, and you see the memory as is. JUST CHANGE 'SUB' to 'ADD. Now press F9 in olly so the game is running again. Go to the game. Attack a few times. Notice your HP continues to increase. You hacked it.
Now looking back in Olly you see only 1 byte of memory actually turned RED right? It's the one in the line that represents ADD. The offset 40161E starts with 83 and beings 0% is teh next byte you're actual hack code is:
Step 5. You can now open your Bloodshev Dev-C++ compiler and paste in the injection code
notice you change the offset and byte and window name to match correctly.
Code:
#include <windows.h>
#include <iostream>
using namespace std;
HWND hHack=FindWindow(NULL,"TBG");
void write(LPVOID addy, DWORD mydata);
void adddebugtokens();
void calltohack();
int main() {
if(!hHack)
{
cout << "Window not found" << endl;
system("pause");
exit(0);
}
cout << "Loading Hack" << endl;
enableDebugPrivileges();
calltohack();
system("pause");
}
void write(LPVOID addy, DWORD mydata)
{
DWORD PID, TID;
TID = ::GetWindowThreadProcessId (hHack, &PID);
HANDLE hopen=OpenProcess(
PROCESS_ALL_ACCESS|PROCESS_TERMINATE|PROCESS_VM_OPE
RATION|PROCESS_VM_READ|
PROCESS_VM_WRITE,FALSE,PID);
WriteProcessMemory(hopen,addy,&mydata,1,0);
CloseHandle(hopen);
}
void adddebugtokens()
{
HANDLE hcurrent=GetCurrentProcess();
HANDLE hToken;
BOOL
bret=OpenProcessToken(hcurrent,40,&hToken);
LUID luid;
bret=LookupPrivilegeValue(NULL,"SeDebugPrivilege",&
luid);
TOKEN_PRIVILEGES NewState,PreviousState;
DWORD ReturnLength;
NewState.PrivilegeCount =1;
NewState.Privileges[0].Luid =luid;
NewState.Privileges[0].Attributes=2;
AdjustTokenPrivileges(hToken,FALSE,&NewState,28,&Pr
eviousState,&ReturnLength);
}
void calltohack()
{
write((LPVOID)0x0040161F, 0x05);
}
Step 6. You can now enjoy your working hack.exe and if you load the game and then the hack you will start gaining health points instead of losing them forever. Hope I helped.
If you want to learn more, Like I add to all of my Tutorials, you should study how the C++ in Main() converterd to ASM in OllyDBG. Good luck.
Step 7.
Additional Feature Ideas:
00401668 |. C74424 04 E1004400 MOV DWORD PTR
SS:[ESP+4],TBG.004400E1 ; ASCII "You
Just Won"
You see this line? Notice the message "You Just Won" is pointed to by 004400E1. You could use a hex/ascii converter and get the hex coding for another phrase like "You have no life" and then write it to the offset 004400E1 and when playing the game the string "You Just Won" would be successfully replaced by that.