Crack the puzzle game "Minesweeper"
On a cold winter evening, after reading articles on researching various software and watching various kinds of videos about hacking games and stuff, I suddenly also had the desire to tinker with something interesting under the debugger. I’ve been engaged in cracking for a relatively long time, so there is practical experience. At first, like many, I just searched for various CrackMEs on the network and hacked them for training, then I switched to hacking paid applications (search / key selection) and writing various kinds of KeyGens. At the moment I am “stuffing my hand” and trying to hone my hacking skills.
Well, okay, this is a lyrical digression from the essence. Now we will decide on some details.
In this article, the main object of attention for us will be the computer game "Minesweeper" .
Research and subsequent debugging of the application takes place under Windows 7 x64 (the implementation of the Sapper game differs in different versions of Windows OS).
As a disassembler, we will use the CheatEngine built-in debugger . I like it for its simplicity and elegance, some things are done in it much easier than, for example, in OllyDBG.
Okay, we figured out the details, let's get down to business!
Surely, almost everyone who uses Windows has ever dealt with the Minesweeper game. In the "seven" the game looks like this :
This is a standard field (in this case 16x16 cells). We will break the game at an average difficulty level, that is, at 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.
So, we open our CheatEngine (in the future we will use the abbreviation CE) and attach ourselves to the game process:
Ok, joined. The search for the values we need will be based on the search for the cells that are currently open. Therefore, we are looking for the value we need for the current number of open cells. In CE, this is done quite simply:
1) Enter the initial number of open cells, ie zero, in the “Value” field, click on “First Scan”
2) We go into the game and click on a random cell, after we go to CE and select “Increased Value” in the “Scan Type” field, click “Next Scan”.
We do similar actions until we find the very cherished value:
We found the address where 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 this value (changes, reads):
We open the game and play a little more, then we see the following picture:
Yeah, very interesting :) Of particular interest are the 1 and 3 instructions, since they are first written in memory, and secondly they are similar and, in general, are executed as much as 3 times! So we go into the debugger, highlighting 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 complete comparison (cmp):
If we hang a “crack” on the comparison of “cmp edx, eax”, then when you return to the game and try to click on the cell, the break will work. Moreover, when you click on a cell with a mine, and when you click on a regular cell. What does it mean? And this means that somewhere here there is a “recognition” of what is underneath in a closed cell: a void, a mine or a number. We are trying to change this value to a meaningless comparison, for example, to this:
Here, as some people understand, the main task is to activate the processor flag “Z”, which occurs if both operands of the CMP instruction are equivalent.
We return to the game and click on any closed cell. Eventually:
Hah, cool! It turns out that it was a “win the game” test, which occurs with every click on the cell in the field, which is generally logical. Already not bad, but we really want to play, bypassing all mines, and not stupidly win the game when opening the first cell of the field, right? So, we continue our research.
In the second stage of hacking, we will try to find out what is the “turning point” in recognizing the “inside” of the cell that was clicked on. Ok, again we go to CE and do the same operations as in the first stage, except that we don’t need to debug the code. We see an already familiar sequence of instructions:
Let's try to find the boundaries of the function (block of instructions) that we are currently in (where the instruction is):
Yeah, and what do we see:
We were visually thrown to the beginning of the current function. This still doesn’t mean anything important to us, but if you think about it, think over everything we have, we can conclude 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 a check of the game “to win”, which, most likely, affects the rendering of the field. Okay, let's check this theory. We get down from the beginning of the function a little down, where we will soon find a very interesting instruction:
This is the first comparison in this function ... Hmm, let's try to put a break on the instruction, then go to the game:
We cannot 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, this function is called, and BreakPoint is installed in it by comparison => we cannot activate the window and “Sap” until we remove the crack. We remove it. It is likely 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 size that it was originally (4 bytes), therefore, nop instructions of 1 byte were added so that the remaining space of 2 bytes would be “snooped”. We go into the game and try to play. We poke the cells, stumble upon a mine, and ... nothing happened! Hmm, no wonder. Okay, let's try not to turn on, but turn off the processor flag “Z”. To do this, replace the comparison with one so that the two elements being compared are never equal. To do this, restore the original instruction:
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 begin to “sapper”. When you click on some areas, they are drawn with some delay, or their "inside" is drawn only the second time. It is true, because we impudently got into a graphic function and mercilessly deprived it :). But when you click on "dangerous areas" with mines, nothing happens at all!
Profit :) We hacked the Sapper game from the standard set of games from Microsoft.
In the next article I will talk about how you can use buffer overflows to hack the game, and about other equally interesting features.