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”