本文分析一款經典的 Windows 掃雷外掛原理,其核心思路是通過 Windows API 讀寫掃雷進程內存,將未點擊的格子強制標記為「旗幟」狀態,從而實現作弊效果。
#include
DWORD x = 0; // 進程 ID
DWORD m = 0, n = 0; // 循環計數器
DWORD addr_a = 0x1005361; // 起始掃描地址
DWORD addr_b = 0x1005361 + 29; // 結束掃描地址(單行 30 格)
BYTE buffer = 0; // 讀取緩衝
BYTE mark = 142; // 旗幟標記值(0x8E)
int main() {
// 1. 尋找掃雷窗口並獲取進程 ID
HWND hWnd = ::FindWindow("掃雷", NULL);
::GetWindowThreadProcessId(hWnd, &x);
// 2. 打開進程獲取完全訪問權限
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, x);
if (hProcess == NULL) return 0;
// 3. 遍歷 16 行 × 30 列的棋盤內存區域
for (n = 0; n < 16; n++) {
for (m = addr_a; m <= addr_b; m++) {
// 讀取 1 字節
::ReadProcessMemory(hProcess, (LPCVOID)m, (LPVOID)&buffer, 1, NULL);
// 若為未點擊格子 (143 = 0x8F),寫入旗幟值 (142 = 0x8E)
if (buffer == 143) ::WriteProcessMemory(hProcess, (LPVOID)m, &mark, 1, NULL);
}
addr_a += 32; // 行跨度(含填充)
addr_b += 32;
}
// 4. 清理並刷新窗口
::CloseHandle(hProcess);
::ShowWindow(hWnd, SW_MINIMIZE);
::ShowWindow(hWnd, SW_SHOWNORMAL);
return 0;
}
0x1005361 開始,每行 30 格,行跨度 32 字節(含 2 字節填充),共 16 行。這在特定版本(如 WinXP 內建掃雷)下成立,但現代系統因 ASLR、版本差異已失效。143 (0x8F):未點擊的空白格142 (0x8E):旗幟標記格FindWindow → GetWindowThreadProcessId → OpenProcess → ReadProcessMemory/WriteProcessMemory → CloseHandle,標準的進程間內存操作流程。SW_MINIMIZE/SW_SHOWNORMAL) 強制 UI 重繪,使修改即時生效。遊戲開發者可採用:
① 關鍵數據加密存儲 ② 完整性校驗(CRC/Hash) ③ 反調試檢測 ④ 服務端權威邏輯(網絡遊戲)。