Requirements:
- Knowledge of C/C++
- x86 Assembler
- Debugger of your choice (I used IDA PRO)
- Memory Scanner (I used CheatEngine)
- Minesweeper (XP Version)
Summary of Learning:
- Simple Bot
- Simple function hooking
So let's make "CleanBot"
Open CE (CheatEngine) attach -> WinMine.exe
Step 1.)
- Game -> Custom -> Height -> a random number
- Value: Search for the number you inputted
- Scan Type: Exact Value
- Value Type: 4Bytes
Step 2.)
- Repeat Step 1.) Until you have got Height.
- Do same for width.
Step 3.)
There are 4 addresses i could of choosen of the 2 pairs.
I've decided to choose:
0x1005334
0x1005338
Extra Notes:
Notice the 4byte difference.
Let's check what sort of variable it could be: http://www.cplusplus.com/doc/tutorial/variables/
So since it doesn't have a decimal point its going to be an "int"
Step 4.)
So the code for mines and boxs must be close!
So i made smallest board game - 9 by 9
So i did 9*9 = 81 just to make sure i catch it i added 100
so 181 converted to hex is 0xB5
0x1005334 + 0xB5 = 0x10053E9
Step 5.)
- Setup range from 0x1005334-0x10053E9
- Unknown Value
- Then click smiley on MineSweeper
- then scan for changed value
Step 6.)
Pretty much every value changed on from 0x1005342 from my results!
(After coding bot up i found out address of start is 0x1005340)
So it seems like it's a board array!
Having a look at dissambler i seen that playing with boards with very few mines has
loads of 0x0F so i belive it 0x0F is no mines.
Step 7.)
Load up IDA PRO and look at functions.
I set breakpoints on every function until i found out:
0x1003512 is CheckBox also know that it's taking 2 variable arguements to the function
which is 4bytes each!
Extra Note people wanting to make more complexed hacks:
There loads other nice functions in there to play with !
E.g. 0x0100374F - Make a guess (Flags) etc etc
Ok we have gather enough information for making a bot now
Bot DLL Code
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// Click Function from IDA PRO
typedef int ( __stdcall *D_ClickBox )(unsigned int, unsigned int);
// This also could be done using deferenced pointer too
class MinesweeperWH
{
public:
unsigned int width; // 0x1005334 (4byte)
unsigned int height; // 0x1005338 (4byte)
};
bool CheckMine( unsigned int x, unsigned int y )
{
y = (y << 5);
unsigned int* UnderBox = (unsigned int*)( 0x1005340 + y + x );
if( (BYTE)*UnderBox == 0x0F )
return false; // No Mines Detected
return true; // Mine Detected
}
bool APIENTRY DllMain( HMODULE hDll, DWORD dwReason, LPVOID pvReserved )
{
switch( dwReason )
{
case DLL_PROCESS_ATTACH:
{
DisableThreadLibraryCalls(hDll);
MessageBoxA( NULL, "Minesweeper Cleanbot by PoZHx\nClick OK to run!.", "Cleanbot", MB_OK );
MinesweeperWH* MinesweeperTable = (MinesweeperWH*)0x1005334; // Table Size we found in CheatEngine
D_ClickBox ClickBox = (D_ClickBox)0x1003512; // Click Function we found in IDA PRO
for( unsigned int w = 1; w <= MinesweeperTable->width; w++ )
{
for( unsigned int h = 1; h <= MinesweeperTable->height; h++ )
{
if( CheckMine(w, h) == false )
ClickBox(w, h);
}
}
return true;
}
default:
{
return false;
}
}
}
by PoZHx