吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 11795|回复: 41
收起左侧

[游戏安全] 连连看辅助开发——第二篇【编程实现找出相同的棋子】

  [复制链接]
YiZheng 发表于 2020-2-18 20:00
本帖最后由 YiZheng 于 2020-2-19 20:46 编辑

今天来讲讲怎么用程序算法找出相同的棋子,首先咱们今天的目标就是读取内存数据,然后分析内存,利用算法找出相同的棋子

简单说如果想消除一对棋子,咱们得先找出相同的棋子;

昨天的那张棋盘的内存截图可能会有人看不懂,我先解读解读;

先上两张图片;


第二天界面截图.PNG 第二天内存截图.PNG

可以发现整个棋盘的布局是有点反人类的;

我为了方便你们看,做了手脚;

观察游戏界面第一排和最后一排,再观察内存区域红线部分;

发现游戏中的一排在内存中是以一列存储的,也就是【游戏】一排==【内存】一列,【游戏】一列==【内存】一排;


第一步:读取数据到数组

//棋盘数据
char chessData[9][14];
void GetChessData()
{
        ///棋盘基地址
        DWORD baseAddress = 0x0019FA04;
        //取得窗口句柄
        HWND gameHWND = FindWindowA(NULL, "连连看");
        //通过窗口句柄-》取得窗口进程ID
        DWORD processID; ::GetWindowThreadProcessId(gameHWND, &processID);
        //通过进程ID-》获得进程句柄
        HANDLE processOpen = OpenProcess(PROCESS_ALL_ACCESS, false, processID);
        //临时变量,存放棋子
        char tmp[1];
        //定义缓冲区
        LPVOID pBuffer = (LPVOID)&tmp;
        for (int i = 1; i < 13; i++)//读取列
        {
                for (int j = 1; j < 8; j++)//读取行
                {
                        //定义棋盘基地址指针
                        LPCVOID pBase = (LPCVOID)baseAddress;
                        //读取棋盘数据
                        ReadProcessMemory(processOpen, pBase, pBuffer, 1, NULL);
                        //写入数据到数组
                        chessData[j][i] = *tmp;
                        //绕过两个数据之间的3个00
                        baseAddress += 0x4;
                }
                //绕过一行数据后的00和FF
                baseAddress += 0x1C;
        }
}

最后读取出来的数据是这个样子;

0  0   0   0   0   0  0  0  0  0  0  0  0  0 
0  8   8   8   8   8  8  8  8  8  8  8  8  0 
0  8   b  13   a   c  11 b  d  13  d e 11  0 
0  f   10  9   14  e  2  15 12 12   4 3  3  0 
0  7   a   6   8   15 4  b  9 9  1  11  c  0 
0  e   3   7   f   6  a  10 7 13  f 2  2    0 
0  12  d   4   15  e  f  1  10  1  5  14  11 0 
0  11  11  11  11  11 11  11 11 11 11 11 11 0 
0  0   0   0   0   0  0  0  0  0 0 0 0 0 


完美!一个一个空格敲的我眼睛酸,后面没敲了,所以比较乱,别介意;

为什么我写数据到数组的时候要从一开始,就是为了周围有一圈零,这个后面会用到;

还有就是每次写入一个数据,地址都要加上一个4,以正确的读取后面的数据,每读取一行也要加一个1C,十进制就是28,如果你不这样做,你就等着叫爸爸:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 8 8 8 8 8 8 8 8 8 8 8 8 0 
0 8 8 8 8 8 8 8 8 8 8 8 8 0 
0 8 8 8 8 8 8 8 8 8 8 8 8 0 
0 8 8 8 8 8 8 8 8 8 8 8 8 0 
0 8 8 8 8 8 8 8 8 8 8 8 8 0 
0 8 8 8 8 8 8 8 8 8 8 8 8 0 
0 8 8 8 8 8 8 8 8 8 8 8 8 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 

不加就是读出一群8来

第二步:实现找出相同一对的算法;

bool FindPair()
{
        int firstPiece_x; int firstPiece_y;//第一颗棋子
        int cecondPiece_x; int cecondPiece_y;//第二颗棋子
        for (firstPiece_x = 1; firstPiece_x < 13; firstPiece_x++)
        {
                for (firstPiece_y = 1; firstPiece_y < 8; firstPiece_y++)//外面两层,是第一颗棋子的XY坐标
                {
                        for (cecondPiece_x = firstPiece_x; cecondPiece_x < 13; cecondPiece_x++)
                        {
                                for (cecondPiece_y = firstPiece_y; cecondPiece_y < 8; cecondPiece_y++)//里面两层,是第二颗棋子的XY坐标
                                {
                                        //如果两个棋子的值相等,并且两个棋子值不等于零(未被消除),并且第一颗棋子与第二颗棋子不在同一个位置(自己不等于自己)
                                        if ((chessData[firstPiece_y][firstPiece_x] == chessData[cecondPiece_y][cecondPiece_x])
                                                && (chessData[firstPiece_y][firstPiece_x] != 0 || chessData[cecondPiece_y][cecondPiece_x] != 0)
                                                && !(firstPiece_x == cecondPiece_x && firstPiece_y == cecondPiece_y))
                                        {
                                                //找到了返回真,这里会写一个算法判断两个棋子是否能消除。。。。。
                                                return true;
                                        }
                                }
                        }
                }
        }
}

找棋子的话也是从数组的1下标开始,周围的零没必要也去找一遍;

好了结束!大家有建议欢迎提出来;

第一篇传送门 :分析游戏

第三篇传送门:算法设计

免费评分

参与人数 15吾爱币 +19 热心值 +14 收起 理由
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
mosar_zh + 1 + 1 我很赞同!
netCheney + 1 + 1 用心讨论,共获提升!
刘必文 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
飞tian狐li + 1 我很赞同!
黑龍 + 1 + 1 谢谢@Thanks!
mchankun + 1 + 1 用心讨论,共获提升!
fiona82 + 1 + 1 谢谢@Thanks!
caizexin299 + 1 用心讨论,共获提升!
short + 1 一起学习
150button + 1 + 1 我很赞同!
独行风云 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
WarWolf + 1 + 1 我很赞同!
黑色魔方 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
sniper9527 + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| YiZheng 发表于 2020-2-19 12:50
YenKoc 发表于 2020-2-19 10:23
老哥这种直接从内存中写脚本的是什么操作,菜鸟的提问,哈哈哈,希望楼主解答

HooK中文意思是叫钩子,假如你找到一段代码,它的功能是挡子弹没了的时候我就换子弹,我就可以Hook这段代码,修改一下,就可以实现秒换弹,不过现在大部分网游的代码都是运行在服务端的,这里就要别的技术了,有点难度
相信 发表于 2020-2-18 20:26
csp0227 发表于 2020-2-18 20:34
a245656350 发表于 2020-2-18 20:36
是个狠人。。
sqhop 发表于 2020-2-18 20:40
楼主厉害,希望以后楼主能多发点这类的文章!
liuwt14 发表于 2020-2-18 21:00
楼主是个狼人啊,很有用的帖子,顶一下
黑色魔方 发表于 2020-2-18 21:08
不错,学习了
天空の幻像 发表于 2020-2-18 21:29
大佬,真厉害,来学习学习
mmattic 发表于 2020-2-18 21:43
过来膜拜
forgetbaidu 发表于 2020-2-18 21:46
大佬牛逼啊
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-3-29 13:08

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表