扫雷外挂

  • 涉及相关API函数

    SendMessage
    PostMessage
    FindWindow
    GetWindowThreadProcessId
    OpenProcess
    ReadProcessMemory
  • 涉及相关工具

    CE
    Spy++
    VC++ 6.0
  • 步骤

    1.用CE分析棋盘基址及其宽、高;
    ①基址: 通过CE以字节数值类型反复“未知初始化数值”、“更改过的数值”和“未更改过的数值”扫描内存,对扫描结果逐一进行过滤,查看滤后结果的内存与实际游戏界面显示情况是否对应,由此进行判定基址;
    ②宽、高:通过CE直接搜索对应宽度、高度,然后调整扫雷级别(即雷面的大小),再次用CE,通过“大于...”、“小于...”对宽高进行扫描,从而判定宽、高在内存中的地址;
  • 附:CE扫描结果
    2.用CE查看棋盘对应内存中数据的意义;
  • 状态:查看非雷、未翻开的雷(标记、未标记的雷)、翻开的雷(失败后游戏自动翻开)等几种状态对应内存中的十六进制数值;
状态十六进制数值
未翻开的雷0x8F
翻开的雷0x8A
结束标识0x10
  • 棋盘坐标:通过Spy++ 监控winmine.exe的鼠标左键按下、松开消息,查看对应棋盘左上角坐标及每格的长、宽;
棋盘坐标十进制数值
横坐标X10
纵坐标Y53

PS:对于棋盘的左上角坐标大致即可,使用时,需要在此基础上加上一个偏移,以使鼠标模拟时能点击到小格内区域;

每小格十进制数值
16
16
3.编制扫雷游戏辅助;

1.辅助源码
2.主要部分SweeperDlg.cpp

unsigned char gameData[24][32]; //ReadProcessMemory

#define gamex 10 + 8
#define gamey 53 + 8
27114710_MaMY.png
程序界面及对应成员
void CSweeperDlg::OnButtonReaddata() 
{
    // TODO: Add your control notification handler code here
    // TODO: Add your control notification handler code here
    HWND hwnd = ::FindWindow(NULL,"扫雷");
    if (hwnd == 0)
    {
        ::MessageBox(0,"游戏未打开",0,MB_OK);
        return;
    }
    //1005194
    DWORD pid;
    GetWindowThreadProcessId(hwnd,&pid);
    //GetWindowThreadProcessId
    //OpenProcss
    HANDLE hp=OpenProcess(PROCESS_ALL_ACCESS,false,pid);
    //
    if (hp==NULL)
    {
        ::MessageBox(0,"打开进程出错",0,MB_OK);
        return;
    }
    ReadProcessMemory(hp,(LPCVOID)0x1005361,gameData,32*24,&pid);
    int high = 0;
    ReadProcessMemory(hp,(LPCVOID)0x1005338,&high,4,&pid);//字节大小可为1,2等,若不为int大小,应对high进行初始化置0;
    m_gameData.Empty();
    CString strGameData;
    WORD yx[2] = {0,0};
    for (int y = 0 ; y < high ; y++)
    {
        for (int x = 0 ; x <32 ; x++)
        {
            //对于后续无意义的字节直接略掉;
            if (gameData[y][x] == 0x10)
                break;
            //格式化
            strGameData.Format("%x,",gameData[y][x]);
            //统一占两位显示
            if (strlen(strGameData) == 2)
                strGameData = "0" + strGameData;
            m_gameData += strGameData;
        }
        //一排结束换行
        m_gameData += "\r\n";
    }
    UpdateData(false);
}
void CSweeperDlg::OnButtonSweeper() 
{
    // TODO: Add your control notification handler code here
    HWND hwnd = ::FindWindow(NULL,"扫雷");
    if (hwnd == 0)
    {
        ::MessageBox(0,"游戏未打开",0,MB_OK);
        return;
    }
    //1005194
    DWORD pid;
    GetWindowThreadProcessId(hwnd,&pid);
    //GetWindowThreadProcessId
    //OpenProcss
    HANDLE hp=OpenProcess(PROCESS_ALL_ACCESS,false,pid);
    //
    if (hp==NULL)
    {
        ::MessageBox(0,"打开进程出错",0,MB_OK);
        return;
    }
    ReadProcessMemory(hp,(LPCVOID)0x1005361,gameData,32*24,&pid);
    int high = 0;
    ReadProcessMemory(hp,(LPCVOID)0x1005338,&high,4,&pid);//字节大小可为1,2等,若不为int大小,应对high进行初始化置0;
    CString strGameData;
    for (int y = 0 ; y < high ; y++)
    {
        for (int x = 0 ; x <32 ; x++)
        {
            //对于后续无意义的字节直接略掉;
            if (gameData[y][x] == 0x10)
                break;
            //不是雷就挖开
            /*
            point[0] = 14+6;
            point[1] = 56+6;
            */
            if (gameData[y][x] != 0x8f)
            {
                WORD yx[2];
                yx[0] = gamex + x*16;
                yx[1] = gamey + y*16;
                ::PostMessage(hwnd,WM_LBUTTONDOWN,1,*(int*)yx);
                ::PostMessage(hwnd,WM_LBUTTONUP,0,*(int*)yx);
            }
        }
    }
}
void CSweeperDlg::OnButtonClick() 
{
    // TODO: Add your control notification handler code here
    WORD point[2];
    HWND hwnd = ::FindWindowA("扫雷",NULL);
    if (hwnd == 0)
    {
        return ;
    }
    point[0] = 14+6;
    point[1] = 56+6;

    ::SendMessage(hwnd,WM_LBUTTONDOWN,1,*(int*)point);
    ::SendMessage(hwnd,WM_LBUTTONUP  ,0,*(int*)point);
}

转载于:https://my.oschina.net/cbnail/blog/910142

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值