700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 「 硬核教学」 ❤️ C语言编写扫雷游戏外挂❤️「 完整源码」

「 硬核教学」 ❤️ C语言编写扫雷游戏外挂❤️「 完整源码」

时间:2021-04-23 03:18:23

相关推荐

「 硬核教学」 ❤️ C语言编写扫雷游戏外挂❤️「 完整源码」

目录

第一步:使用CE找出棋盘的基址

第二步:使用CE/OD查看该地址的数据

第三步:对比棋盘分析数据的含义

第四步:验证猜想

第五步:编写功能

有没有羡慕学霸们在机房里 潇洒如意地玩着扫雷无限通关,而你连初级都通关不了?

有没有想过你为什么那么蠢?

....

但你别慌,其实我也是。

于是乎今天给大家来个扫雷外挂的详细教学,避免以后出现像我这样的扫雷菜鸡(bi mian xue ba zhuang bei)。

效果大概这样:

打开扫雷游戏

开启外挂:啪,就过关了。

下面详细说明开发过程:

第一步:使用CE找出棋盘的基址

分析:棋盘是x*y的矩形,第一格的地址很可能是矩形的基址。打开游戏通过不断地变化第一格的数据,分析出其地址。 我这里地址是 01005361 (16进制,以下数据都以16进制来表示)

第二步:使用CE/OD查看该地址的数据

如图:

第三步:对比棋盘分析数据的含义

分析:观察棋盘和数据,可以明显得出结论:8F代表雷 0F则为空 10代表行结束 32字节存储棋盘的一行 一共有24行

(通过扫雷游戏的操作可知 棋盘的大小最大为 24 *30,少的字节用来存储判断行结束的标志)

比如上述地址,第一行第一列数据为8F,第一行第三列为8F,对应棋盘第一个和第三个就是雷

第四步:验证猜想

分析:可以编写程序读出该地址数据存放在 byte[24][32]的数组中,然后将数组内容按 24行 × 32列 的格式 输出

如图:

上述我加了判断,如果值为8F就输出: 雷,否则输出: 安全,这样看的更清晰些

查看对应棋盘

还真是!

第五步:编写功能

分析:在四步的时候你已经可以看着你读取出的数据手动过关。但是这样显然不是一个程序员想要的,如何编写自动过关成了最后一步。

思路: 通过模拟鼠标点击,点击除了“雷”之外的格子, 即完成过关功能

步骤 1:通过截图工具或spy++获取窗口消息(推荐),得出或者测量出一个格子的中心点相对于游戏窗口的坐标 我这里是(18, 61)

步骤 2: 再测量出 一个格子的大小 本游戏是 16×16。那么分析就可以知道 第一行二个格子的中心点就是 (18+16,61),依次类推则可以得到所有格子中心点的坐标

步骤 3: 编程通过 mouse_event或 SendMessage 来模拟鼠标点击

上述就是扫雷外挂的全部开发过程,为了庆祝你成为扫雷大神。请务必给我点赞!!

下面附C语言完整源码,如果需要本游戏程序和MFC的完整源码请+扣扣3492625357

#include"stdio.h"#include<windows.h>//author:See QQ3492625357HWND hWnd = NULL;DWORD pId = -1;HANDLE hProc = NULL;byte chessData[24][32] = { 0 };bool ReadChessData() //读数据函数{BOOL bRet = FALSE;do{hWnd = ::FindWindow(NULL, TEXT("扫雷"));if (NULL == hWnd){printf("未检测到游戏,请先打开扫雷游戏!");break;}::GetWindowThreadProcessId(hWnd, &pId);hProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId);if (NULL == hProc){printf("右键以管理员运行,重新打开本程序!");break;}if (0 == ::ReadProcessMemory(hProc, (PBYTE)0x01005361, chessData, 24 * 32, 0))break;bRet = TRUE;} while (FALSE);return bRet;}void click(int x, int y) //鼠标左键点击{::SendMessage(hWnd, WM_LBUTTONDOWN, 0, (y << 16) + x);::SendMessage(hWnd, WM_LBUTTONUP, 0, (y << 16) + x);}void ShowChessData() //读取数据{click(18, 61);if (!ReadChessData()){return;}for (int i = 0; i < 24; i++){printf(" %d行 : ", i + 1);for (int j = 0; j < 32; j++){if (chessData[i][j] == 0x10)//如果读取的值是10代表行结束 break;if (chessData[i][j] == 0x8F)// 8F是雷 输出1 代表雷printf("1 ");elseprintf("0 ");// 安全则输出0}printf("\n");}}void StartGame() {click(18, 61);if (!ReadChessData()){return;}for (int i = 0; i < 24; i++)for (int j = 0; j < 32; j++){if (chessData[i][j] != 0x8F){click(18 + j * 16, 61 + i * 16);}}}void ShowMenu(){printf("******功能菜单******\n");printf("\n请输入数字 1 或 2 来选择功能\n");printf("****1:读取数据****\n");printf("****2:开始游戏****\n");}int main(){int chioce = -1;while (1){system("cls");ShowMenu();scanf("%d", &chioce);switch (chioce){case 1:ShowChessData();system("pause");break;case 2:StartGame();printf("扫雷结束...");system("pause");break;default:printf("输入错误请重新输入\n");system("pause");break;}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。