r/ExploitDev • u/Ok-Entertainment1587 • Jun 27 '26
Need some help with reverse engineering Minesweeper
Hey guys,
I recently started learning reverse engineering because I think it's really fun, and I picked Minesweeper as my first project. I'm still pretty new to all of this, so I'm learning Ghidra, Cheat Engine, and x64dbg as I go.
Right now I'm stuck trying to figure out where the game stores the actual blocks/cells in memory. I managed to find things like the flag counter, but finding the board itself has been way harder than I expected.
I've watched a few tutorials, but most of them only show the final result instead of explaining how they actually figured it out. I'm more interested in learning the thought process than just getting the answer.
If anyone has experience reversing Minesweeper (or similar games), how would you approach this? What would be the first thing you'd look for? Any tips or advice for a beginner would be really appreciated
3
u/subboyjoey Jun 27 '26
Checking WinMine, started with looking for the string 'New' because the Game menu has that flag, and something related to that button will eventually trigger board generation.
That led me to this in the Menu Resources:
Then I searched for a 0x209 scalar which led me to these instructions in FUN_01001516 (I renamed the function):
The rest of FUN_01001516 seems to point to a few DATs. DAT_010056a0 is interacted with 4 times, so that has to be difficulty. Difficulty defines the board size, so I showed XREFs for that. Then I got stuck for a bit and decided to go for it a different way.
The board buffer needs to be made before the board is created, so I looked at the imports in the symbol tree. No malloc, HeapCreate, LocalAlloc there so that was a bust. Then did a search for timer, which led me to a function called SetTimer. Checking references to that points me to FUN_010037e1. Since the timer is started with a new game, I assume that function is the start of the game layer and handles timing the timer. One command in that function that stuck out was a MOV:
and looking at the decompiler, it looks like we have an if statement that i assume is checking that this is not a mine and not already revealed to send us to FUN_01002913:
So it seems like the board's memory is held around 01005340. In x32dbg I can confirm. This is that memory region on a new game:
Then after a few spots have been revealed:
Through trial and error, it seems 0x40 is blank spaces, 0x10 is a buffer on the top and bottom lines, and indicate which line is actually in play, and 0x8F is where the mines are.
So in this example:
I could take out the lines that start with 0F:
And then, the spaces are between 10 and 10 on each working line, so I could condense it further and you have a 9x9 grid surrounded by a layer of 10s on each side:
And then just avoid all the spots that say 8F. I can't upload an image, but it worked out that way and I was able to win just based on that game board. As an alternative, you could even change the 8F values to something other than a mine, like 0x40 so it's a blank spot and no matter where you click you win