Recently I tweeted a screenshot where I won the Minesweeper game by looking at the mine field from the memory. I posted this for no reason, just for fun since I was happy that I finally won this game. I used to play this game back in 2002 in Windows XP and I never won this game, I never even understood how this game works until today when I read how it really works š
[tweet https://twitter.com/OsandaMalith/status/975488775815094273]
In few minutes my notifications were flooded, I didnāt expect to get this much of likes. Some people asked me a tutorial on this. I thought of writing a very quick blog post on this. Pardon me if I missed anything.
After tweeting that screenshot I saw this blog post by @DidierStevens where he shows a video on hacking Minesweeper with Mimikatz from @gentilkiwi. Itās awesome to include such a functionality inside Mimkatz. Letās try to code a simple dirty hack for Minesweeper in XP.
In Windows XP you can find the binary from %systemroot%\system32\winmine.exe
If you donāt have Windows XP you can still download the original binary from here.
Static Analysis
First, letās have a look if the binary has ASLR enabled. The DLL Characteristics got a value of 0x8000 which is āIMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWAREā. Itās confirmed that this PE was compiled with no ASLR protection. We can easily hardcode the addresses if we are coding a hack for this.
Looking at the IAT we can determine the program uses the Microsoft Windows graphics device interface (GDI) by looking at the functions imported from the āgdi32.dllā. This is obvious since this is a game? We can also see Registry APIs used from the āadvapi32.dllā which means we can suspect the application accesses the registry.
Hacking the Scores
The scores are stored in the registry and the values are read from the registry. If you check all the imports and find references to āRegQueryValueExWā API and hit a break point you can find the location of the registry. Another easy way would be hooking the API ?
After the breakpoint is hit you can see the parameters on the stack and you can open the location in the registry.
HKEY_CURRENT_USER\software\Microsoft\winmine
You can modify the names, scores and other options such as colour, difficulty, height, width, etc. The value of āName1ā corresponds with the score value of āTime1ā in hex.
Hacking the Mine Field
Letās hit a breakpoint at the āBeginPaintā API.

Letās step inside the function
01001C4C |. E8 720E0000 CALL Winmine_.01002AC3
Then again step inside the function.
01002AE6 |. 56 PUSH ESI ; /Arg1
01002AE7 |. E8 BBFBFFFF CALL Winmine_.010026A7 ; \Winmine_.010026A7
You will see the āBitBltā api is used to draw the blocks one by one.
If we check the registers, the EBX contains the mine field 0x010056360 and the ESI register is used to increment each byte.
If we dump the EBX register we can determine starting point from 0x01005340.
It adds 0x20 to EBX which we can determine the end of each field.
0100271D |. 83C3 20 |ADD EBX,20
Coding a Dirty Hack
First, we have to open the process of the game. For this, we will use FindWindow and get the handle of the window and then pass it to āGetWindowThreadProcessIdā and once we get the ādwProcessIdā we can pass that value to āOpenProcessā API. You can also use ‘CreateToolhelp32Snapshot’ technique discussed here.
|
1 2 3 4 5 6 |
HWND window = FindWindow(NULL, L"Minesweeper"); if (window == NULL) return wprintf(L"[-] Failed to find Minesweeper process"); GetWindowThreadProcessId(window, &dwProcessId); HANDLE process = OpenProcess(PROCESS_VM_READ, FALSE, dwProcessId); |
Next, we will allocate our buffer to store our mine field data.
|
1 2 3 |
LPBYTE buffer = (LPBYTE)malloc(size); if (buffer == NULL) return wprintf(L"[-] Failed to allocated memory"); |
Finally, we will write an infinite loop to read memory from the starting address of the memory using the āReadProcessMemoryā API, so that each time we click a field the fields get updated. We can use 0x20 as the end of each line in the field.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
while (true) { BOOL ret = ReadProcessMemory(process, (LPVOID)start, buffer, size,&dwRead); if (ret == NULL) return wprintf(L"[-] Failed to read memory"); for (size_t i = 0, j = 0; i < size; i++, j++) { if (j == 0x20) { puts(""); j = 0; } printf("%c", buffer[i]); } Sleep(1500); system("cls"); } |
We just dumped the mind field from memory using āReadProcessMemoryā API ?
Here’s the full source code.
https://github.com/OsandaMalith/GameHacking/blob/master/Minesweeper/Hack.c
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#include "stdafx.h" #include <stdio.h> #include <tchar.h> #include <windows.h> #define start 0x1005340 #define end 0x10056A0 int _tmain(int argc, _TCHAR* argv[]) { DWORD dwProcessId = 0; DWORD dwRead = 0; HWND window = FindWindow(NULL, L"Minesweeper"); if (window == NULL) return wprintf(L"[-] Failed to find Minesweeper process"); GetWindowThreadProcessId(window, &dwProcessId); HANDLE process = OpenProcess(PROCESS_VM_READ, FALSE, dwProcessId); DWORD size = end - start; LPBYTE buffer = (LPBYTE)malloc(size); if (buffer == NULL) return wprintf(L"[-] Failed to allocated memory"); while (true) { wprintf(L"[+] Minesweeper Dirty hack\n"); wprintf(L"[+] Author: @OsandaMalith\n"); wprintf(L"[+] Website: https://osandamalith.com\n\n"); BOOL ret = ReadProcessMemory(process, (LPVOID)start, buffer, size, &dwRead); if (ret == NULL) return wprintf(L"[-] Failed to read memory"); BYTE field = NULL; for (size_t i = 0, j = 0; i < size; i++, j++) { if (j == 0x20) { puts(""); j = 0; } printf("%c", buffer[i]); } Sleep(1500); system("cls"); } return 0; } |
You can modify the byte values and print something like this, Iāll leave that to you ?
You can check my friend Ophir Harpaz has nicely patched the program where she has made, if the al == 0x8f which is a mine, change it to a flag which is 0x0E inside the code cave.
https://github.com/ophirharpaz/Patched-Minesweeper
I hope this post will be useful to you get started with hacking simple games ?
Translations
?????? Minesweeper – https://howtorecover.me/khaking-minesweeper
[tweet https://twitter.com/FennelAurora/status/986967915110064129]














5 thoughts on “Haxing Minesweeper”