Minesweeper hacking - Viewing process memory in Windows

I wrote a very simple program to read Minesweeper's memory and display a grid showing where the bombs are. I used OllyDbg for disassembly and reversing and CheatEngine for quickly finding known values in memory.

During this process, I found out that Minesweeper CHEATS, only spawns about half the bombs, and moves bombs mid-game. (Sometimes to where you are clicking, sometimes it will move a bomb that you click on.) Regardless, I consider this project a success.

During this process, I found that Minesweeper will sometimes assist you and move bombs away from where you are clicking on. Originally, I thought that Minesweeper was only "spawning" about half of the bombs, but as it turns out I misunderstood the way minefield was represented in memory and all bombs are generated at the beginning of the game and not first click or any later clicks.

My error was in thinking that minefield was stored in a 2-dimensional array (ie: minefield[x][y] = FLAGS) where max(x) (and max(y)) are the size of the grid (ie: 9x9 on Beginner) but as xumiiz on Reddit pointed out:

His program is buggy. It's not reading the grid in correctly - it's a constant width of 32 bytes, but a window from the top left is taken for the actual size of the playing field.

So, first bugfix to his source:

 for(DWORD grid_loc = 0; grid_loc < grid_height * grid_width; grid_loc++) {

should be:

 for(DWORD grid_loc = 0; grid_loc < grid_height * 32; grid_loc += ((grid_loc%32)==(grid_width-1))?(32-grid_width+1):1) {

And:

   if((grid_loc % grid_width) == (grid_width - 1))

should be changed to:

   if((grid_loc % 32) == (grid_width - 1))

With these fixes, it reads all the bombs properly.

And also this comment from Anonymous:

Sorry but your program is reading the grid incorrectly. Minesweeper uses a grid with a fixed width of 32 bytes and the playing field is takena s a window of that grid from the top left. e.g. beginner mode uses bytes 0 to 8 and skips bytes 9 to 31 per every 32 byte row.* Fixing the program to read based on that patten shows that Minesweeper only moves the mine if it happens to be the first square you click on. Apart from that, all mines are randomly placed at the start of the game.

(* Actually it would use bytes 0 to 10, where bytes 0 and 10 are 0x10 which is to indicate the border of the mine field, and bytes 1 to 9 are the actual squares. but that's not really relevant to the analysis if you're just &ing with 0x80 to find bombs.)

The program is available here: Minehack Source | Minehack Source & Binary (ZIP)

Sample program output:

Minehack - Reverse Engineering and Coding by Sub <sub@room641a.net>
---
Fairly simple program to display already-placed bombs in minesweeper.
---
PID: 2836
Height: 9
Width: 9
---
[B][ ][ ][ ][ ][ ][B][ ][B]
[ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][B][ ]
[ ][ ][B][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ]

And now, probably the most important comment block of my entire program:

/* Did you know?
 * 
 * Minesweeper uses a char-sized (1 byte) multi-dimensional array. Each byte
 * in memory corresponds to a specific location on the grid. It appears to use
 * simple bit masks.
 *
 * 0x10 Start/End of row (border)
 * 0x40 Button has been pressed already
 * 0x80 Bomb is in place. These can move mid-game if clicked on
 * Bit-wise OR with:
 * 0x00 The square is exposed or the right-hand 4 bits are 0x10
 * 0x0X # on square (if exposed)
 * 0x0D Square is marked with question mark
 * 0x0E Square is marked with flag
 * 0x0F Blank square
 *
 * AND THEN THERE'S 0xCC WHICH MEANS YOU CLICKED A DAMN BOMB AND LOST!
 */

Please note: At 12:20AM EST on 7/3 I have edited this post by merging a couple of updates, adding contributions from comments here and on Reddit, and retracting false, invalid, or unfounded statements (these are still available to read, they are just "crossed out") I'm still on the road (writing this from a hotel in Iowa) but will try to reply to comments when I arrive in California.

Another update: At 10:10PM PST on 7/7 I have fixed my program, "Minehack." The source has been updated, I have released a binary, and the software has been placed under the BSD License. Many thanks to the people and sites who linked me, people who posted comments, most definitely the contributors, but most importantly: the readers. I have other projects in the works and I hope you will find them just as interesting!


I believe the bombs are generated on first click. To prove this point. Try creating a custom game and max out the mines. No matter where you click first you NEVER click on a bomb.

i believe this has to be the best explanation of why i didn't think of this first....it's all because of the http://stuffididlastnight.com

That's because there is a bit of code that moves any bomb that you click on if it is the first click of the game. If you examine the memory before any clicks take place, you will see where the bombs are. Once I update my source I will release a binary so you can all see it for yourself, without having to compile any of my code (which will still remain freely available.)

You can also verify that bombs are placed at the start and not after the first click by opening Minesweeper up in a debugger and placing a breakpoint on the rand() routine - I am unsure of its exact name at this time. That breakpoint will fire number_of_bombs*2 for the x and y coordinates. You can take this a step further and find out where in memory these values are returned to and again know where the bombs are before first click.

There is a cheat for minesweeper so you can see where the bombs are to impress your friends.

http://hight3ch.com/post/minesweeper-cheat/
----------------------
All you Minesweeper ”legit” players look away ! The Windows based Minesweeper game has a cheat. Hard to beleive, I always thought that Windows games had no cheats. All you have to do is -> open the game - place the cursor on the game panel and -> type: xyzzy and press SHIFT -> ENTER -> ENTER. After that you should see a ONE white pixel on the top left side of your screen. Everytime you will move the cursor over a mine in the game, the pixel will turn black. Try not to have a white background if you want to see the white pixel.
---------------------

You could actually win a lot of money off easily (or, frankly, not-so-easily) fooled friends by using your 'psychic' powers with this. Sadly, that was my first thought upon trying that. *hangs head*

Joe - www.anewbandaday.com

No it's actually quite decent, he is wrong in the assertion that it's cheating but it was a good attempt to look under the hood of one of the most popular games on Windows.

I wonder if solitaire cheats too....

It doesn't believe it or not but at college my and a friend had 'synced' up our games by chance. It's not as random as you think and we used to race each other since our cards were identical. I don't know why solitaire doesn't have a game number selector then because it's not random.

Did this years ago - so it's true of the XP version, don't know about the Vista version. Can confirm all bombs are generated at the start - and the only time a bomb is moved is if you click it first go - it then shifts that bomb to another spot.

wow, you did that all yesterday morning? good job minesweeper hacker dude - now checkout some http://stuffididlastnight.com

dude, that stuffididlastnight.com site is hilarious!

rand is called twice the number of mines because it needs 2 indices for the 2dimensional array, isn't it?

Yeah, pretty much. It probably looks something like grid[x][y] where x and y are both generated from rand()

Amazing!

Amazing the fact that someone would spend so much time finding out if a rubbish game cheats or not. to be honest i'd rather sit on my own d**k.

Duck?

they could be practicing very useful computer skills instead of spending their time surfing the web looking for random people to insult.

/yes, I see the irony

no silly not duck. . . dock, the poster is/was obviously a Otis Redding Fan lol

There's a pretty well-documented cheat built into minesweeper that allows you to know ahead of time where all of the bombs are. Here's how the cheat works:
1. Open Minesweeper.
2. Type xyzzy, and then hold down the Shift key for a second.
3. When you move your mouse over a cell, the top left pixel of your monitor show the current status. A white pixel means safe (no mine) and a black pixel means that there is a mine under the cell. It takes a little bit of practice, since you're only looking at one single pixel.
4. Profit!
Using this cheat, you could easily confirm if mines are moving by mapping out a game, and then confirming the mine locations after each move.

And it does cheat. I just loaded winmine.exe (which starts a new game), did the cheat, noticed the pixel, went for the first black pixel I saw, clicked on it, and no bomb. I tried it thrice, with the same results. It seems the game wants to guarantee you can start. I don't think it's cheating against you; I think it's cheating for you.

I agree. This is my conclusion as well.

If you click on a mine the first time, it moves it. That's all the cheating it does. You can go through with the xyzzy cheat and mark all of the mines ahead of time to prove that none of the others are moved.

You can easily tell the game cheats on the first move if a mine is hit without using the xyzzy method.

Make a custom game with the max allowable mines (eg 10x10 grid, 81 mines).
In theory you should have a 4/5 chance of hitting a mine on your first click but in practice it's impossible to do so.

The vista version of minesweeper on the other hand does allow a 1 click lose situation.

Sorry but your program is reading the grid incorrectly. Minesweeper uses a grid with a fixed width of 32 bytes and the playing field is takena s a window of that grid from the top left. e.g. beginner mode uses bytes 0 to 8 and skips bytes 9 to 31 per every 32 byte row.* Fixing the program to read based on that patten shows that Minesweeper only moves the mine if it happens to be the first square you click on. Apart from that, all mines are randomly placed at the start of the game.

(* Actually it would use bytes 0 to 10, where bytes 0 and 10 are 0x10 which is to indicate the border of the mine field, and bytes 1 to 9 are the actual squares. but that's not really relevant to the analysis if you're just &ing with 0x80 to find bombs.)

Ahh! I was wondering what 0x10 was signifying! Thank you so much!

Could have avoided entire lengthy process by starting with this. You knew all along it was gonna end here.

TITS OR GTFO!

gb2/b/

It doesn't sound too ridiculous to me. It doesn't move mines you've identified, and it doesn't change the displayed numbers.

The only bombs it can actually move are those with positions you can't yet be sure of, Schrödinger's bombs, if you will.

Minesweeper is not cheating. Subversity is trying to cheat, and Minesweeper is being clever about keeping him from doing so.

If minesweeper said only 1 bomb existed in the surrounding squares when two bombs existed, that would be cheating.

Looks like anti-cheating feature, to prevent people just reading the mine locations from memory?

I didn't know it cheated this much. I know that it is impossible to lose on the first click, which is easy to verify. Just set the game with the max number of mines so there are only about 15 safe squares. You will always be fine on the first click.

Play on easy. Click a corner. Reset. Keep clicking only that corner and resetting. I'll guarantee you'll occasionally hit a bomb on the first click.

Maybe we're using different versions, but I'm guessing you just haven't tried sensibly. Go into custom, and configure it to have a board with the maximum mine density (set everything to 999 and they cap at 24x30, 667 mines). Then, click somewhere to start the game. Repeat this a few times and I think you will be convinced quickly.

By the way: picking the same space doesn't matter. The probably is the same anywhere.

"The random moving of bombs is completely pointless."

Your comment is pointless with out any arguments which prove pointlessness.

I spent way too much time as a teen playing Minesweeper, and I've never ever felt cheated.

All the times I lost (and there were many!), I could plainly see what mistake I did in interpreting the already revealed numbers (which do not change of course).

Of course, there are times (especially in expert mode) where you have a 50/50 chance of dying. And my experience is that I've lost in approximately 50% of these games.

Frankly, there is strictly no reason the program would cheat. And why would there be the xyzzy cheatcode, which allows the player to see the bombs before clicking?

I strongly suspect you misinterpreted what you read from memory, or were tricked by the author of the program. The only true way to know is to disassemble the executable and read the machine code.

Youtube or it doesn't happen.

The random moving of bombs is completely pointless. What were they trying to achieve, foiling clairvoyant players??

OW! MY PERCEPTION OF REALITY.

So how did you find the offsets in memory for where minesweeper keeps its 'map'? Did you snoop using some debugging tool or test with trial and error?

I got the offsets by using CheatEngine. I first scanned for an unknown initial value, right clicked on the top left-most square, and then scanned for changed values. I did this based on the assumption that the memory allocation would start with that square.

Microsoft is evil.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <blockcode> <ul> <ol> <li> <dl> <dt> <dd> <br /> <p> <pre> <blockquote> <s>
  • Lines and paragraphs break automatically.

More information about formatting options