Tumgik
Text
Reverse Engineering - Minesweeper Game
Hello Everyone,
This is my first experience Reverse Engineering a game. I had so much fun analyzing the code and it took five days to figure out the logic and design.
Tools Used:
Ollydbg, IDA Pro, MSDN, Procdump and Hex Calculator
My Goal:
- Find the GAME logic
- Simulate the game board WITHOUT PLAYING THE GAME
- Find the secret code (revealed when we win the game) of all three levels without playing the game
Find the GAME logic
I first used IDA Pro to review the Imports and strings that are being used in the executable (minesam.exe). The string tab did not have any useful strings that might give us a clue to understand the functionality of the code. The Import table has LoadStringsW and gives me a clue that a string is being loaded using this function.
After using IDA Pro, I used Ollydbg to debug the game. I tried to run the program and reviewed the memory dump for clues.
I got to see the minesweeper board with mines. The board starts at 0x01005340. The board’s border is designed using the hex value ‘10′ and the mines are represented by ‘8F’. The memory dump of the game board looks like the picture below.
Tumblr media
Next I used IDA pro to find the cross reference calls to this memory address (to find out the functions that referenced to the 0x01005340 memory address). IDA pro showed the following list of cross references.
Tumblr media
I carefully reviewed every function using the combination of both disassembler and debugger. I found the following code segment that adds ‘0F’ to the memory dump. This is the first step that is being iterated to create game board in the memory dump. It starts at (0x01005340 + 360) and replaces ‘00‘ with ‘0F‘. The game board gets filled with ‘0F‘ .
Tumblr media
And then the next part of the code draws the vertical and horizontal borders to the memory dump.
Tumblr media
The board in the memory dump looks like the image below  and the mines are yet to be placed on the board.
Tumblr media
Mine Calculation:
Lets look at how the mines are calculated and placed in the memory dump. First a number is generated using Rand Function(msvcrt). The random number is stored in both EAX and ECX. EAX is divided and the remainder is stored in EDX. EDX value is moved to EAX.
010036DB       CALL minesam.01003940
01003940        CALL DWORD PTR DS:[<&msvcrt.rand>]      
The function returns the EAX value and the value is moved to ESI. ESI  will represent the column in the game board. For example if ESI = 2, the mine will be placed at second (2nd) column. The function CALL minesam.01003940  is called the second time to set the EAX value and  the following offset [EAX+ESI+1005340] will help us to determine the location of the next mine.
010036F3        LEA EAX,DWORD PTR DS:[EAX+ESI+1005340]
 After finding the location offset of the next mine, the code tries to change the value in that offset. The following screenshot shows the part the code that does the calculation.
Tumblr media
An OR bitwise operation is applied between EAX value and 80.  If EAX is equal to 0F , the result of OR logic will be ‘8F’. ‘8F’ is the value of a mine in the memory dump of the game. At the end of this function, the memory dump looks like the below image.
010036FA         OR BYTE PTR DS:[EAX],80     
Tumblr media
We figured out the mine location of the board. Next I am going to cheat the game using the memory dump above.
Tumblr media
After winning the game, I reviewed the memory dump again, and found that the values have been replaced with different numbers. The board now looks exactly like the actual GUI game board(image above).
Tumblr media
By comparing the two images above, we make the following inferences:
A Mine new value is 8E.  Old Value was 8F.
Tumblr media
Now we will work on finding the logic in the code using Ollydbg.
After reviewing the code using breakpoints, I was able to nail down the logic.  The cell that does not have a mine will either be blank or have a number.
The value of each cell is calculated using the following rule.
Tumblr media
The number of mines (# of 8E) around the cell will determine the value of that cell.
Number of 8E:
Tumblr media
The logic is available in the following code fragment/section.
Tumblr media
The OR logic is used to calculate the cell value.
01003044          OR AL,40                               
Tumblr media
The value is moved to that particular cell using the following command
01003047    MOV BYTE PTR DS:[ESI+1005340],AL  
Finally we figured out how the hex values are changed in the memory dump while playing the game. Next we are going to simulate the board  in command line without playing the game.
Simulate the game board WITHOUT PLAYING THE GAME    
We will be using python and Procdump. And yes, We can cheat the game without playing the game. The following image shows the memory dump of the intermediate level challenge.
Tumblr media
I wrote a python program, that reads the memory dump created by procdump. Then I apply the code logic to figure out the value of each cell and the output of the command line looks like this:
Tumblr media
I was able to simulate the board in the command line without playing the game. In the above image,
~ represents Blank cell
1,2,3,4,5 represent the number of mines around that cell
* represents a mine
Tumblr media
Find the secret code (revealed when we win the game) of all three levels (Beginner, Intermediate, Expert) without playing the game
There is a secret code that will be displayed when we win the game. There is a secret code for each level (3 levels available). We are going to apply reverse engineering techniques to figure out the location of the secret code. We are going to print the secret code without winning/playing the game.
Tumblr media
The secret code (Smartie) is underlined in the above image.
To find out the code that stores the secret string, I used ollydbg and IDA pro in combination to figure out the offset and logic.
When I reviewed the imports of this executable in IDA pro, the following entry gave me a clue that strings are loaded using the LoadStringW :
00000000010010D0     LoadStringW     USER32
I added a breakpoint at this location in ollydbg and started to debug the executable. The code stopped at breakpoint multiple times to load User name,  game statistics (seconds, top score etc) and the message that had the secret code.
Tumblr media
Lets take a look at the stack when LoadStringW  is loaded with the message and secret code
Tumblr media
I tried to step in to the function minesam.010039E7, one instruction at a time to track the strings in the stack. The following entries in the stack looked interesting.
000DF598  |0101E88C  UNICODE "You have the fastest time for beginner level.
000DF5B0   000DF5F0  UNICODE "You have the fastest time for beginner level.
The secret word is Smartie!"
Let us have a look at the stack at this stage
Tumblr media
When I reviewed the stack, the memory offset 0101E88C looked new and was out of range in the current memory dump. So I decided to right click and select “follow in dump”. Aha! look what I discovered at that offset:
Tumblr media
So I want to find out the memory layout at the offset 0101E88C.  I clicked the View -> Memory to view the current memory layout.
Tumblr media
The offset  0101E88C is available in the below entry. The offset is part of the .rsrc folder as part of the Minesam.exe. I am going to double click on the entry to have a look at the resources folder dump.
Tumblr media
After reviewing the  resource folder dump, I was able to locate the secret code at the offset  0101E88C.
Hence the buffer in LoadStringsW function loads the secret code from the resource folder. But the code is loaded only after winning the game.
Tumblr media
So now I have to print the secret code without playing the minesweeper game. I am going to use Python and Hex calculator, to access the memory and calculate the offset. The following sample code shows how the offset for expert level is calculated.
b= pe.sections[2].get_data()[100880:100935]
Please find below the output of python program.
Tumblr media
Credit: Sam Bowne
0 notes