Basics of game hacking by UgLy-NeRd. Article is provided with video and C source code. Will be suitable for beginners.
The game I'll be using is Minesweeper and making it so it shows where the mines are (automatically flagging them).
Ok. First you need to start Minesweeper and MHS (Memory Hacking Software).
Open Minesweeper's process (winmine.exe) with MHS.
Now, we need to search for 10 (number of mines left).
You will be left with a bunch of results. We need to narrow these down, so, flag a mine (any mine, it does not matter), and make it so you only have 9 mines left.
Now, sub search for value 9 (number of mines left).
You should now be left with 1 result. This is the offset where minesweeper stores the number of mines left.
Go ahead and copy the address down.
And opon OllyDbg. Attach Minesweeper's process (winmine.exe) to OllyDbg.
Your screen should now look like this. This is just minesweeper's code. Don't worry, you don't really need to understand any of this.
Un-pause Minesweeper by clicking the Play button.
Now, go to the offset that you found in MHS.
Change the text formatting of the dump area to ASCII (32 chars).
When you're looking at the dump, what do you see? You should see something like this. The box that is shown in the dump area would be the minesweeper boxes. It shows which are mines and which aren't.
We need to find what code changes the boxes to be mines and not mines. We do this by breakpointing on write. Go ahead and do this (as shown below).
Click the smiley on minesweeper, this will re-draw all the boxes with different mines.
Wait.. It just paused. Why? Because when you breakpointed on write, and you go to minesweeper and click the smiley, it re-draws the boxes with mines. So, we breakpointed on write, meaning it changed that value. It will take us to the bit of code that does so.
Continue by pressing F7 (or step into button) to find which piece of code actually writes where the is. Just hold F7 until you notice a mine is drawn (it will look like an A with a squiggly line in the dump area). You might have to draw a few mines until you find which line of code draws the mine.
If your having trouble, go slow, once you see the A pop up in the dump area, it will be the line of code that was just called.
I found it. It is at offset 010036FA. The code that draws the mines is
OR BYTE PTR DS:[EAX],80
OR BYTE PTR DS:[EAX],80
So, we know this function draws a a blank box where the mine is, we need that blank box to be a mine. 80 would be the overlay for the blank box.
OR - Logical inclusive OR of the two operands returning the result in the destination. Any bit set in either operand will be set in the destination.
MOV - Loads the current task register with the value specified in "src".
Lets change that OR to a MOV.
To find what the hex code for the flag is, just click play in OllyDbg, go to Minesweeper, make a flag in a box, go back to OllyDbg, change the dump area view to Hex Ascii 16 Chars. Find the flag in the dump. Once you find it, it should be 0E.
So, change
OR BYTE PTR DS:[EAX],80
to
MOV BYTE PTR DS:[EAX],0E
by double clicking that piece of code. The assemble box should come up, just put the changed code in there, and click assemble.
Remove the breakpoint we made so it doesn't always pause when drawing the boxes.
Click the smiley on minesweeper, and it should draw the flags as shown below.
Ok. Now we need to put ALL of this into programming language (C++). Which can be done very easily with a function called WriteProcessMemory().
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
/* Offset that we changed the code in OllyDbg */
LONG address = 0x010036FA;
/* The new bytes that we write */
/*010036FA C600 0E MOV BYTE PTR DS:[EAX],0E*/
BYTE newvalue[] = {0xC6,0x00,0x0E};
HWND hwnd;
HANDLE phandle;
DWORD pid;
/* Get Minesweeper's window */
hwnd = FindWindow(NULL, "Minesweeper");
if (hwnd != 0) {
GetWindowThreadProcessId(hwnd, &pid);
phandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
} else {
cout << "Minesweeper is not running.";
cin.get();
return 0;
}
/* If we can open Minesweeper's process, it will change the code, else, it will return "Couldn't get a handle" */
if (phandle != 0) {
WriteProcessMemory(phandle, (LPVOID)address, (LPVOID) &newvalue, 3, 0);
cout << "Mines revealed!";
cin.get();
} else {
cout << "Couldn't get a handle";
cin.get();
}
}
Please register or login to download attachments.