首页 > 技术文章 > 扫雷分析

P201821440033 2020-02-21 15:24 原文

void C扫雷分析Dlg::OnBnClickedButton1()
{
    HWND hWND = ::FindWindow(NULL, _T("扫雷"));
    if (NULL == hWND)
    {
        ::MessageBox(NULL, _T("扫雷游戏未打开"), _T("错误"), MB_OK);
        return;
    }
    ::SendMessage(hWND, WM_COMMAND, 0x209, 0);
}


void C扫雷分析Dlg::OnBnClickedButton2()
{
    HWND hWND = ::FindWindow(NULL, _T("扫雷"));
    if (NULL == hWND)
    {
        ::MessageBox(NULL, _T("扫雷游戏未打开"), _T("错误"), MB_OK);
        return;
    }
    ::SendMessage(hWND, WM_COMMAND, 0x20a, 0);
}


void C扫雷分析Dlg::OnBnClickedButton3()
{
    HWND hWND = ::FindWindow(NULL, _T("扫雷"));
    if (NULL == hWND)
    {
        ::MessageBox(NULL, _T("扫雷游戏未打开"), _T("错误"), MB_OK);
        return;
    }
    ::SendMessage(hWND, WM_COMMAND, 0x20b, 0);
}


void C扫雷分析Dlg::OnBnClickedButton4()
{
    HWND hWND = ::FindWindow(NULL, _T("扫雷"));
    if (NULL == hWND)
    {
        ::MessageBox(NULL, _T("扫雷游戏未打开"), _T("错误"), MB_OK);
        return;
    }
    ::SendMessage(hWND, WM_COMMAND, 0x20c, 0);
}


void C扫雷分析Dlg::OnBnClickedButton5()
{
    int s = 100;
    while (s--)
    {
        OnBnClickedButton1();
        Sleep(17);
        OnBnClickedButton2();
        Sleep(17);
        OnBnClickedButton3();
        Sleep(17);
    }
}


void C扫雷分析Dlg::OnBnClickedButton6()
{
    DWORD pid;
    HWND hWND = ::FindWindow(NULL, _T("扫雷"));
    if (NULL == hWND)
    {
        ::MessageBox(NULL, _T("扫雷游戏未打开"), _T("错误"), MB_OK);
        return;
    }
    GetWindowThreadProcessId(hWND, &pid);
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (NULL == hProcess)
    {
        ::MessageBox(NULL, _T("打开扫雷游戏失败"), _T("错误"), MB_OK);
        return;
    }
    ReadProcessMemory(hProcess, (LPCVOID)0x1005194, &m_editbase, sizeof(m_editbase), &pid);
    UpdateData(FALSE);
}


void C扫雷分析Dlg::OnBnClickedButton7()
{
    DWORD pid;
    m_strshowdata.Empty();
    int dwhight = 0;
    HWND hWND = ::FindWindow(NULL, _T("扫雷"));
    if (NULL == hWND)
    {
        ::MessageBox(NULL, _T("扫雷游戏未打开"), _T("错误"), MB_OK);
        return;
    }
    GetWindowThreadProcessId(hWND, &pid);
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (NULL == hProcess)
    {
        ::MessageBox(NULL, _T("打开扫雷游戏失败"), _T("错误"), MB_OK);
        return;
    }
    unsigned char gamedata[24][32] = { 0 };
    if (!ReadProcessMemory(hProcess, (LPCVOID)0x1005361, &gamedata, 32*24, &pid))
    {
        ::MessageBox(NULL, _T("读取扫雷游戏进程的数据失败"), _T("错误"), MB_OK);
        return;
    }
    if (!ReadProcessMemory(hProcess, (LPCVOID)0x1005338, &dwhight,sizeof(dwhight), &pid))
    {
        ::MessageBox(NULL, _T("读取扫雷游戏进程的数据失败"), _T("错误"), MB_OK);
        return;
    }
    CString strTemp = _T("");
    short gamex = 20,gamey=60;
    unsigned short xypos[2] = { 0 };
    for (int i = 0; i < dwhight;++i)
    {
        xypos[1] = gamey + i * 16;
        for (int j = 0; j < 32; j++)
        {
        if (0x10 == gamedata[i][j])
            break;
        xypos[0] = gamex + j * 16;
        if (0x8F != gamedata[i][j])
        {
            ::PostMessage(hWND, WM_LBUTTONDOWN,MK_LBUTTON,*(int*)xypos);
            ::PostMessage(hWND, WM_LBUTTONUP, 0, *(int*)xypos);
        }
        strTemp.Format(_T("%02X"), gamedata[i][j]);
        m_strshowdata += strTemp;

        }
        m_strshowdata += _T("\r\n");
    }
    UpdateData(FALSE);
}

 


BUTTON1~7分别为初级,中级,高级,自定义,循环,读取雷数,读取数据(同时自动扫雷)。雷数的基地址为0x1005194,雷区一个大小为16*16,

每一格雷占1byte,0x8f表示雷,0x0f表示没有雷,0x10表示一行结束。

在雷区插旗时变化为0x8E,取消后恢复为0x8f;
在非雷区插旗时变化为0x0E,取消后恢复为0x0f.
雷区的高度:0x01005338 和 0x010056A8
雷区的宽度: 0x01005334 和 0x010056AC

第一个的坐标大约是(20,60)

初级到自定义的UPARAM分别为0x209-0x20c。

推荐阅读