同城头条  >  技术分享  >  经典扫雷游戏破解实现
经典扫雷游戏破解实现
2021年12月14日 08:20   浏览:0   来源:小报道
本帖最后由 Nattevak 于 2021-12-7 08:48 编辑

自己对游戏方面挺感兴趣的,但是毕竟新手入门水平,想搞搞大型游戏还没有那水平,饭还得一口一口吃,先从经典的扫雷小游戏开始尝试
破解扫雷并不是说玩个扫雷都需要去使用作弊手段,只是为了学习思路和方法
扫雷游戏大家应该都玩过吧,我这里就不献丑演示游戏玩法了

 扫雷.zip (2.78 MB, 下载次数: 527)    其中包含 扫雷EXE源文件 以及 VS工程 (DLL文件在MFC -> Debug ->MFCSL.dll)

一、数据分析

1.雷的数量
添加后分别修改,最后发现地址为01005630的数值进行修改操作时游戏中的雷数会发生变化,故这里就确定的雷数的地址。


2.游戏时间
找到时间的地址,之后通过NOP时间可以实现0秒通关的效果。


3.雷区宽度
同样的搜索方法寻找到疑似雷区宽度的数据,之后仍进行修改验证测试。


4.雷区高度
同样的搜索方法寻找到疑似雷区高度的数据,之后仍进行修改验证测试。


5.数据汇总


二、游戏分析
1.遍历雷区
①创建DLL项目
使用Visual Studio创建MFC动态链接库项目,并选定DLL类型为静态链接(我这里使用的是Visual Studio2022


②使用Spy++获取窗口信息(Visual Studio2022菜单栏 工具->Spy++  自带的工具


③查看扫雷窗口信息


2.此处写了一个遍历雷区的测试代码,供大家参考

[C] 纯文本查看 复制代码

?

0102030405060708091011if (Msg == WM_KEYDOWN && wParam == VK_F5){    //一键秒杀    OutputDebugString(L"F5");    int nWidth = *g_pWidth;    int nHeight = *g_pHeight;    int nMineCount = *g_pMineCount;    CString strString;    strString.Format(L"宽度: %d,高度: %d,雷数:%d ", nWidth, nHeight, nMineCount);    OutputDebugString(strString.GetBuffer());}



3.注入DLL
①使用CE 工具->注入DLL


②使用DebugView工具观察注入情况,对比游戏参数验证数值是否正确


4.反汇编代码调试
①将扫雷程序附加到OD中查看其内存情况,可以看出边界为10,雷为8F,标识为41,42…(无数字标识的地方为40)


②分析雷区数组的汇编代码部分


③测试遍历雷区代码,并重新注入进行测试

[C] 纯文本查看 复制代码

?

0102030405060708091011121314151617for (size_t y = 1; y < nHeight + 1; y++){    CString strLine;    for (size_t x = 1; x < nWidth + 1; x++)    {        //数组基地址+(y+1)*32+x+1(y=0到高度)        BYTE byCode = *(PBYTE)((DWORD)g_pBase + x + y * 32);        if (byCode == MINE)        {            nFindCount++;        }        CString strCode;        strCode.Format(L"%02x ", byCode);        strLine += strCode;    }    OutputDebugString(strLine.GetBuffer());}



④再次使用DebugView工具观察注入情况


5.坐标转换
我们希望完成一键扫雷的操作,那我们就应该有模拟点击的操作,但是我现在并不知道雷区的坐标是什么样的,所以我们需要先进行坐标的转换
①获取回调函数
找到窗口回调函数的位置,仍然通过Spy++查看,使用Spy++获取窗口信息再点击确定就会弹出该窗口


6.反汇编代码调试
①在汇编代码中找到窗口回调函数的位置,并设置假定参数,再设置消息断点


②分析鼠标事件坐标转换的汇编代码部分


③获取鼠标位置,反馈窗口信息

[C] 纯文本查看 复制代码

?

0102030405060708091011x = LOWORD(lParam);y = HIWORD(lParam);x = (x + 4) >> 4;y = (y - 0x27) >> 4;BYTE byCode = *(PBYTE)((DWORD)g_pBase + x + y * 32);if (byCode == MINE){    SetWindowText(hWnd, L"此处有雷");}else{    SetWindowText(hWnd, L"扫雷");}



④通过模拟点击事件把所有非雷区域点击,实现一键通关

[C] 纯文本查看 复制代码

?

1234xPos = (x << 4) - 4;yPos = (y << 4) + 0x27;SendMessage(hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(xPos, yPos));SendMessage(hWnd, WM_LBUTTONUP, 0, MAKELPARAM(xPos, yPos));



⑤游戏效果
按下F5后实现一秒钟自动扫雷并通关游戏


7.NOP游戏时间
①获取地址
在CE中找出是什么访问了这个地址,再显示反汇编程序,可以观察到时间的变化


②反汇编代码调试
由CE可以看到01002FF5处的指令代码实现时间的自增,如果想要时间不增加,就需要把这里给NOP掉,即将FF 05 9C570001 这六个字节都填充为NOP


当我们第一次按下时,01003830会自增1,所以导致之前无法实现0秒完成扫雷,故我们应该把01003830的数据也NOP掉


③将时间自增语句使用NOP填充

[C] 纯文本查看 复制代码

?

1234567//获取扫雷进程IDGetWindowThreadProcessId(g_Wnd, &Pid);//获取扫雷进程句柄hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);//将时间自增的语句使用NOP填充result1 = WriteProcessMemory(hProcess, (LPVOID)g_pTime1, &szInc, 6, 0);result2 = WriteProcessMemory(hProcess, (LPVOID)g_pTime2, &szInc, 6, 0);



④游戏效果


三、完整代码

[C] 纯文本查看 复制代码

?

001002003004005006007008009010011012013014015016017018019020021022023024025026027028029030031032033034035036037038039040041042043044045046047048049050051052053054055056057058059060061062063064065066067068069070071072073074075076077078079080081082083084085086087088089090091092093094095096097098099100101102103104105106107108109110111112113114115116117118119// MFCSL.cpp: 定义 DLL 的初始化例程。//#include "pch.h"#include "framework.h"#include "MFCSL.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// 唯一的 CMFCSLApp 对象CMFCSLApp theApp;HWND g_Wnd;//窗口句柄WNDPROC g_OldProc;//老的窗口回调函数PDWORD g_pHeight = (PDWORD)0x01005338;//雷区高度PDWORD g_pWidth = (PDWORD)0x01005334;//雷区宽度PDWORD g_pMineCount = (PDWORD)0x01005330;//雷的数量PBYTE g_pBase = (PBYTE)0x1005340;//雷区基地址#define MINE 0x8F//雷区中的元素标识DWORD Pid = 0;//进程IDHANDLE hProcess = 0;//进程句柄PDWORD g_pTime1 = (PDWORD)0x01002FF5;//时间自增PDWORD g_pTime2 = (PDWORD)0x01003830;//时间首次自增char szInc[6] = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };//保存NOP指令DWORD result1, result2;//保存结果// CMFCSLApp 初始化LRESULT CALLBACK WindowProc(    _In_ HWND hWnd,    _In_ UINT Msg,    _In_ WPARAM wParam,    _In_ LPARAM lParam){    //获取扫雷进程ID    GetWindowThreadProcessId(g_Wnd, &Pid);    //获取扫雷进程句柄    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);    //将时间自增的语句使用NOP填充    result1 = WriteProcessMemory(hProcess, (LPVOID)g_pTime1, &szInc, 6, 0);    result2 = WriteProcessMemory(hProcess, (LPVOID)g_pTime2, &szInc, 6, 0);     if (Msg == WM_KEYDOWN && wParam == VK_F5)    {        //一键秒杀        OutputDebugString(L"F5");        int nWidth = *g_pWidth;        int nHeight = *g_pHeight;        int nMineCount = *g_pMineCount;        CString strString;        strString.Format(L"宽度: %d,高度: %d,雷数:%d ", nWidth, nHeight, nMineCount);        OutputDebugString(strString.GetBuffer());        int nFindCount = 0;        for (size_t y = 1; y < nHeight + 1; y++)        {            CString strLine;            for (size_t x = 1; x < nWidth + 1; x++)            {                //数组基地址+(y+1)*32+x+1(y=0到高度)                BYTE byCode = *(PBYTE)((DWORD)g_pBase + x + y * 32);                if (byCode == MINE)                {                    nFindCount++;                }                else                {                    int xPos, yPos;                    xPos = (x << 4) - 4;                    yPos = (y << 4) + 0x27;                    SendMessage(hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(xPos, yPos));                    SendMessage(hWnd, WM_LBUTTONUP, 0, MAKELPARAM(xPos, yPos));                }                CString strCode;                strCode.Format(L"%02x ", byCode);                strLine += strCode;            }            OutputDebugString(strLine.GetBuffer());        }        CString strCode;        strCode.Format(L"找到的雷数 %d ", nFindCount);        OutputDebugString(strCode.GetBuffer());    }    else if (Msg == WM_MOUSEMOVE)    {        //鼠标移动        int x, y;        x = LOWORD(lParam);        y = HIWORD(lParam);        x = (x + 4) >> 4;        y = (y - 0x27) >> 4;        BYTE byCode = *(PBYTE)((DWORD)g_pBase + x + y * 32);        if (byCode == MINE)        {            SetWindowText(hWnd, L"此处有雷");        }        else        {            SetWindowText(hWnd, L"扫雷");        }    }    return CallWindowProc(g_OldProc, hWnd, Msg, wParam, lParam);} BOOL CMFCSLApp::InitInstance(){        CWinApp::InitInstance();        //1.通过查找窗口,获取窗口句柄        g_Wnd = ::FindWindow(L"扫雷", L"扫雷");//FindWindowW(_In_opt_ LPCWSTR lpClassName,_In_opt_ LPCWSTR lpWindowName);     if (g_Wnd == NULL)    {        OutputDebugString(L"无法找到 扫雷窗口");        return FALSE;    }    //2.设置窗口回调函数    g_OldProc = (WNDPROC)SetWindowLong(g_Wnd, GWL_WNDPROC, (LONG)WindowProc);    if (g_OldProc == NULL)    {        OutputDebugString(L"设置窗口回调函数失败");        return FALSE;    }    return TRUE;}


头条号
小报道
介绍
报道大小信息,宣传正能量!
推荐头条
Keywords" 仪陇网、仪陇生活网、专注仪陇本地信息真实传递_仪陇网d-sj.cn/学法减分好助理答题神器一扫就出答案、学法减分好助理扫一扫知道答案app、学法减分好助理考试题库、学法减分好助理20道题模拟考试、学法减分好助理可以减多少分?、学法减分好助理拍照搜题 秒出答案免费、学法减分好助理拍照搜题、学法减分好助理拍照搜题 秒出答案、学法减分好助理可以申请几次?、学法减分好助理题库最新版、仪陇生活网、仪陇生活网招聘、仪陇招聘驾驶员、仪陇新政有哪些厂还在招工、仪陇人才网、仪陇在线、仪陇新政最新急招聘58同城、仪陇新政哪有做兼职的、仪陇县招聘信息最新招聘仪陇生活网招聘、仪陇招聘网最新招聘信息、仪陇生活网二手房、仪陇生活网最新消息、仪陇生活网门面转让、仪陇生活网住房出租最新消息、仪陇生活网发布了信息如何取消、四川仪陇生活网、仪陇人才招聘信息生活网、仪陇生活网、仪陇生活网招聘、仪陇招聘网最新招聘信息、仪陇生活网最新消息、仪陇生活网门面转让、仪陇生活网二手房、仪陇生活网住房出租最新消息、仪陇生活网最新招聘暑假工、四川仪陇生活网、仪陇手机生活网、仪陇招聘网最新招聘信息、仪陇招聘驾驶员、仪陇县租房信息、仪陇新政招聘网最新招聘、仪陇找工作、仪陇最新招聘、仪陇生活网招聘、仪陇人才网、仪陇招聘信息招聘仪陇招聘信息信息、仪陇招聘c1驾照、仪陇房价、四川仪陇县房价多少钱一平方米、仪陇县房价现在是多少、仪陇房产网、仪陇新政房价多少钱一平米、仪陇新政房价、仪陇房价为什么这么高、仪陇房价多少钱一平方、仪陇房价如何走、仪陇房价为什么这么高2019、仪陇新闻网、仪陇新闻网头条、仪陇新闻最新消息今天、仪陇新闻网今日新闻、仪陇新闻直播、仪陇新闻网丁强、仪陇新闻网直播视频、仪陇新闻视频、仪陇新闻综合频道直播、仪陇广告公司、仪陇广告语、仪陇金山广告、仪陇驾校、仪陇驾校报名费用、仪陇驾校C1多少费用、仪陇驾校88队哪个教练好、仪陇驾校在什么地方、仪陇驾校科目一考试、仪陇驾校学费、仪陇驾校科一早上笫一堂几点、仪陇驾校蒲、仪陇坤安驾校、仪陇工厂招聘、仪陇工厂有拿回家干的活吗?、仪陇新政工厂招聘、仪陇新政招聘信息工厂、仪陇家电维修、仪陇家电回收、仪陇家电清洗、仪陇电脑维修哪家好、仪陇电脑城在哪里、仪陇电脑销售在什么地方、仪陇电脑回收、仪陇电脑培训、仪陇电脑商家、壹家电脑维修、仪陇二手家具市场、仪陇家具城、仪陇家具厂、仪陇家具维修师傅、仪陇家具定制、仪陇家具厂网上程、仪陇家具市场、仪陇家具城在哪里、仪陇二手家具回收、南充仪陇二手家具市场、四川仪陇房产信息网、仪陇马鞍房价、广西桂林房价、仪陇一中录取分数线2021、仪陇翰林锦府、仪陇金城二手房的房价、仪陇房价为什么这么高、仪陇新政租房最新消息、仪陇县金城镇房价下跌、仪陇县招聘信息最新招聘、仪陇房产网、仪陇河西工业区招聘、仪陇门面出租、四川仪陇黑老大周超、仪陇县金城镇二手房最新消息、仪陇新政本地招聘启事、四川仪陇新镇最新招聘、仪陇县找工作生活网、如何自学电脑维修、娄星区关家垴附近电脑维修、恒达行家维修培训怎么样、珠海唐家电脑维修、台式机维修去哪家好、笔记本维修哪家好、仪陇电脑维修哪家好、电脑维修公司哪家好、秀洲区电脑维修哪家好、仪陇新政本地招聘启事、仪陇县金城镇二手房最新消息、仪陇招聘网最新招聘信息、仪陇新政有哪些厂还在招工、仪陇县河西工业区招工、南部人才网、四川仪陇黑老大周超、仪陇新政哪有做兼职的、四川仪陇新镇最新招聘、长津湖电影、长津湖电影时间多长、长津湖电影完整版免费观看、长津湖电影观后感、长津湖电影完整版免费观看HD、长津湖电影完整版免费观看2021、长津湖电影完整版免费观看网站、长津湖电影观后感500字、长津湖电影票多少钱一张、长津湖电影票购买、长津湖成影史历史片票房冠军、长津湖电影完整版免费观看、长津湖3个冰雕连仅2人生还、长津湖战役、长津湖2021免费完整版观看、长津湖票房破30亿、长津湖作文、长津湖观后感、长津湖手抄报、长津湖观后感10篇、刷手机下拉示选上海百首网络、刷手机下拉述约上海百首网络、刷手机下拉安选上海百首网络、刷手机下拉尚选上海百首网络、刷手机下拉安信上海百首网络、苹果手机下拉菜单、华为手机不能下拉、手机下拉功能在哪里设置、手机下拉设置在哪里设置、手机不能下拉通知栏、仪陇天气、仪陇房产网新楼盘、仪陇县楼盘房价最新消息、仪陇县、仪陇天气预报15天、仪陇县房价、仪陇招聘网最新招聘信息、仪陇属于四川哪个市、仪陇县金城镇、仪陇网、仪陇房产网新楼盘、仪陇县招聘网、仪陇网上在逃人员、仪陇网吧多久开业、仪陇网约车平台、仪陇网红地、仪陇网吧、仪陇网吧开门了吗、仪陇网络电视台、仪陇生活网、仪陇生活网招聘、仪陇生活网最新招聘信息、仪陇生活网最新消息、仪陇生活网门面转让、仪陇生活网二手房、仪陇生活网发布了信息如何取消、四川仪陇生活网、仪陇手机生活网、仪陇人才招聘信息生活网、仪陇丁家大院、仪陇森家环保、仪陇县房价、仪陇二手房、仪陇二手房出售信息、仪陇房产查询系统、仪陇房子出售、仪陇房子能不能买、仪陇房子贵、仪陇房子还会拆迁、仪陇房子出租、仪陇首座房子好不好、仪陇房产网新楼盘、仪陇房产网、仪陇房产备案查询、仪陇房产信息网、仪陇房产查询系统、仪陇房产管理局官网、仪陇房产交易网、仪陇房产价格、仪陇房产中介、仪陇房产局、仪陇河西工业区有些什么厂、仪陇县河西工业区招工、仪陇河西工业园2020招聘、仪陇河西电子厂招聘信息、仪陇河西招聘驾驶员、仪陇河西大华宝公学、仪陇河西工业区有哪些制衣厂、仪陇河西工业园、仪陇河西工业区电子厂、仪陇河西工业区灯泡厂、薇仪陇之家、薇仪陇生活网新政房价、仪陇新政房价、仪陇新政二手房出售、仪陇新政楼盘、仪陇在线、仪陇生活网、仪陇生活网是大家了解仪陇的资讯窗口,同时也是仪陇人的网上家园,为大家提供免费查询发布仪陇便民生活信息,是仪陇地区综合信息门户网站!

Copyright ©2021 仪陇家园同城网--版权所有   蜀ICP备2022002889号-1