Intro
On a cold winter evening, after reading articles about researching various software and watching various kinds of videos about hacking games and stuff, I suddenly had a desire to tinker with something interesting under debager. I have been doing crackling for a relatively long time, so there is practical experience. At first, like many, I simply searched various CrackMEs on the network and cracked them for the purpose of training, then switched to hacking paid applications (searching / selecting keys) and writing various kinds of KeyGens. At the moment, I am “filling my hand” and trying to hone the skills of hacking.
Well, okay, this is a lyrical digression from the point. Now we will define some details.
In this article, the main object of attention for us will be the
computer game "Minesweeper" .
The study and subsequent debugging of the application occur under Windows 7 x64 (the implementation of the game “Minesweeper” differs in different versions of Windows OS).
As a disassembler, we will use the
built-in debugger CheatEngine . I like it with its simplicity and elegance, some things in it are made much easier than, for example, in OllyDBG.
Okay, with the details figured out, let's get down to business!')
Surely, almost everyone who uses Windows has ever dealt with the game Minesweeper.
In the "seven" the game looks like this :

This is a standard field (in this case 16x16 cells). We will break the game on the average difficulty level, that is, on the “Amateur” level. In general, for the “Novice” and “Professional” difficulty levels this article will also be relevant, nothing but time, the number of mines and the size of the field will not change.
Stage 1So, open our CheatEngine (the CE abbreviation will be used in the future) and attach to the game process:

OK, joined. The search for the values ​​we need will be based on the search for currently open cells. Therefore, we are looking for the desired value of the current number of open cells. In CE, this is done quite simply:
1) Enter the initial number of open cells in the “Value” field, that is, zero, click on “First Scan”
2) Go to the game and click on a random cell, then go to CE and in the "Scan Type" field select "Increased Value" (value increased), click "Next Scan"
We do similar actions until we find the very, cherished value:

We found an address in which another address is stored, which in turn stores a static value.
Add a value to the “AddressList”. Now, if you play a little game, you will notice that the value is changing.
Now we are looking for an asm instruction that somehow interacts with the given value (changes, reads):

Open the game and play a little more, then we see this picture:

Yeah, very interesting :) Of particular interest are the 1 and 3 instructions, as they are firstly written in memory, and secondly they are similar and, in general, are executed as many as 3 times! So we go to the debugger, selecting 1 or 3 instructions and clicking on the "Show Disassembler" button.
So, so, so, everything becomes more interesting and more interesting! Of particular interest is this chain with a final comparison (cmp):

If we hang "break" on the comparison "cmp edx, eax", then when you return to the game and try to click on the cell, the breakpoint will work. With that, as when clicking on a cell with a mine, and when clicking on a regular cell. What does it mean? This means that somewhere here there is a “recognition” of what is under in a closed cell: emptiness, mine or figure. We try to change this value to any meaningless comparison, for example, on this:

Here, as some have understood, the main task is the activation of the “Z” processor flag, which occurs in case both operands are CMP equivalent.
We return to the game and click on a closed cell. Eventually:

Hah, cool! It turns out that it was a “winning game” test, which occurs with every click on the field cage, which is quite logical. Not bad, but we want to play exactly, bypassing all the mines, and not stupidly win the game when opening the first square of the field, right? So, we continue our research.
Stage 2In the second stage of hacking, we will try to find out what is the “turning point” in recognizing the “inside” of the cell that clicked. Ok, we go to CE again and do the same operations as in the first stage, except that debugging code is not required. We see the already familiar sequence of instructions:

Let us try to find the boundaries of the function (block of instructions) in which we are at the moment (where the instruction is located):

Yeah, and what we see:

We are visually thrown at the beginning of the current function. This doesn’t mean anything to us yet, but if we think about it, think about it, all we have, we can come to the conclusion that this function can be somehow connected with the graphics of the game, for example. This conclusion can be reached on the basis of stage 1, where we found the test of the game “to win”, which most likely affects the drawing of the field. Okay, let's test this theory. We get down from the beginning of the function a little bit down, where we will soon find a very interesting instruction:

This is the first comparison in this function ... Hmm, we will try to break the instructions, then go into the game:

We can not go into the game. Why? Yes, because our theory was confirmed! This feature is really related to the graphics of the game. Each time the window is activated and other interactions with the game interface are called, this function is set BreakPoint on the comparison => we cannot activate the window and “Sapit” until we remove the bryak. Remove it. There is a possibility that this comparison plays a key role in the subsequent behavior of the entire function. Let's try to change this comparison to a meaningless comparison so that the processor flag “Z” is activated, as it was done in the first stage:

The size of the new instruction (2 bytes) is 2 times smaller than the one that was originally (4 bytes), therefore, the “nop” instructions were added to 1 byte, so that the remaining space of 2 bytes “burst”. Go to the game and try to play. We poke in the cells, stumble on a mine, and ... nothing happened! Hmm, no wonder. Okay, let's try not to turn on, but turn off the flag of the processor "Z". For this it is necessary to replace the comparison with such that the two compared elements were never equal. To do this, restore the original instructions:
cmp dword ptr [rax + 38], 01
and change the comparison of the contents of the pointer, for example, to compare with a negative number (s -1):

Now we return to the game and start saping. When you click on some areas, they are drawn with some delay, or their “inside” is drawn only from the second time. It is true, because we brazenly got into the graphical function and mercilessly otdebazhili it :). But when you click on "dangerous areas" with mines nothing happens at all!
Result:

Profit :) We hacked the game "Minesweeper" from the standard set of games from Microsoft.
In the next article I will talk about how you can use buffer overflow to hack the game, about other equally interesting features.