This time we use the win98 minesweeper "advanced" field as an example of the basic code. Later, we will write a common code for all fields
The "advanced" minesweeper field refers to
The following is the download link for OD and win98 Minesweeper
: http://pan.baidu.com/s/1gfA10K7 Password: eiqp
Let’s start the demonstration of this experiment:
1. After opening OD, drag winmine.exe into OD
2. Set a breakpoint on WM_LBUTTONUP
3. Then step through to this location
## Comment as message processing (address is 01001FE1) and follow 4. After following, we are here The chessboard data can be found at The data to extract the current position is as follows: We will know the first two words of the address 010055330 It is 0x63 (99 in decimal), which represents the number of mines. The following double words are width and height respectively. 0x10 represents the side of the chessboard, and 0x8F represents mine. So we only need to retrieve this memory 0x8F and change it to 0x8E (marked as red flag), it is successfulAs shown below The following is the C/C++ code#include <windows.h> #include <stdio.h> int main() { HWND hWinmine = FindWindow(NULL, L"扫雷"); DWORD dwPID = 0; GetWindowThreadProcessId(hWinmine, &dwPID); HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, dwPID); //基础地址、雷数、宽度、高度 DWORD dwBaseAddr = 0x01005330; DWORD dwNum = 0, dwWidth = 0, dwHight = 0, dwSize = 0; //读取内存信息 //读进程的内存空间数据 //参数:第1个参数: HANDLE hProcess进程句柄。 //第2个参数: LPCVOID lpBaseAddress基址指针。 //第3个参数: LPVOID lpBuffer接收数据缓冲区指针。 //第4个参数: DWORD nSize接收数据缓冲区缓冲区大小。 //第5个参数: LPDWORD lpNumberOfBytesRead读入数据量大小指针。 返回值: 成功:TRUE 失败:FALSE ReadProcessMemory(hProcess, (LPVOID)dwBaseAddr, &dwNum, sizeof(DWORD), &dwSize); ReadProcessMemory(hProcess, (LPVOID)(dwBaseAddr +0x4), &dwWidth, sizeof(DWORD), &dwSize); ReadProcessMemory(hProcess, (LPVOID)(dwBaseAddr + 0x8), &dwHight, sizeof(DWORD), &dwSize); //棋盘总大小=棋盘+空白边+4角 DWORD dwReadsize = dwWidth*dwHight + dwHight * 2 + dwWidth * 2 + 4; PBYTE pByte = new BYTE[dwReadsize]; ReadProcessMemory(hProcess, (LPVOID)(dwBaseAddr + 0x16), pByte, dwReadsize, &dwSize); BYTE bClear = 0x8E; for (size_t i = 0; i < dwReadsize; i++) { if (pByte[i] == 0x8F) { WriteProcessMemory(hProcess, (LPVOID)(dwBaseAddr + 0x16 + i), &bClear, sizeof(BYTE), &dwSize); } } //函数功能: 得到窗体客户区的大小。 //第1个参数: HWND hWnd窗体句柄。 //第2个参数: LPRECT lpRect客户区RECT结构的指针。 RECT rt = { 0 }; GetClientRect(hWinmine, &rt); InvalidateRect(hWinmine, &rt, true);//这个函数屏蔽一个窗口客户区的全部或部分区域。这会导致窗口在事件期间部分重画 delete pByte; CloseHandle(hProcess); getchar(); return 0; }