首先qqllk创建了游戏的进程,那么一定会打开一个进程
在od中下一个createprocess断点,运行程序,果然在断点处断了下来。
在创建进程的参数中这个位置是挂起线程。那么应该就是在挂起线程后对内存进行了修改,修改内存会用到WriteProcessMemory。下个WriteProcessMemory断点接着运行
程序断在了这个位置,对参数分析
43817A是写入的位置,也就是游戏进程的位置,那么一会要去游戏进程看一下
484E70是写入的数据的缓冲区位置,数据窗口跟随查看数据,发现写入了00
想到之前在loadpe中查看的文件对齐大小是1000.会不会是方便修改
再打开一个od附加进程kyodai
CTRL+G去到刚刚找到的地址43817A,现在的数据是01
将启动器接着运行,然后再回来游戏进程,发现之前的01已经被修改成了00
游戏程序就可以运行了
那么把内存中43817A这个位置改变就可以正常的启动游戏本体。那么之前的文件对齐大小是1000,和内存对齐一致,那么对应文件的位置也是43817A,当然这个地址是一个VA地址,RVA地址就是3817A。
在010editor打开游戏文件,跳转到3817A的位置,将01修改为00
另存为一个新文件,改个名字。打开发现游戏可以正常运行了
通过Cheat Engine 搜索道具个数。定位到道具数量地址是12AC5C
时间条的地址是12A748(在调试的时候锁定方便分析)
把数值修改,发现道具的数量也改变了
在0D中跳转到12AC5C这个位置发现了一些数据
刚验证了这个位置就是道具的数量位置,从上边的F0 09 F1 03推断F加一个数字是道具类型。根据推断改变下面的数据
果然道具的类型和数量发生了变化。
通过Cheat engine 搜索棋盘第一个位置,不断刷新棋盘,对比第一个位置的数据进行搜索,对比是否发生变化
最后得到很多数据,但是只有第一个和之前的道具位置比较接近,合格应该是棋盘的位置,再次刷新棋盘,这里的数据发生变化。
在od中跳转到这个地方,对棋盘进行刷新,这里色数据都发生了变化,
棋盘最后面以00000结尾,多次刷新数据发现并没有固定的结束标记,所以从游戏入手,算出方块的数量是19*11=209个16进制是D1个
##
首先用CE修改道具的数量,并锁定。方便后面的调试
在地图的一个位置下一内存访问断点,当我们点击了指南针或者炸弹道具的话,肯定会来访问地图的数据寻找可以消除的两个位置
点击道具触发了断点,打开调用堆栈窗口,寻找是哪一个函数调用的
在这几个函数打上断点,在向上就是mfc库函数,只需要在本程序的函数上分析就可以了。
再次运行程序,使用指南针道具,断点在一个地方断了下来,分析一下栈内的参数,其中有一个F0,根据上面的分析,F0是指南针道具的标志
那我就换一个道具看看这里会不会变化。这次点击炸弹道具,这次F0变成F4,正好是炸弹的标志,那这个Call就可能是调用道具的CAll
在IDA中打开这个程序进行分析,来到我们刚刚看到的这个CALL的位置,并进入这个CAll的内部
分析一下这个CAll的流程图,发现这里有个switch选择,一共是8个分支,很可能是道具的种类选择,但是道具槽的位置只有7个,所以我就错过了这个位置,后来浪费了好多时间,等分析完一遍之后,再回到这个位置,感觉它在无情的嘲讽我,道具的位置有七个,但是也可能有八种
查看这个地址,去到OD中跳转到这里。
根据EAX的值来找到跳转的地址,在数据窗口跟随。
发现了八个地址,这八个地址其实就是switch的case,根据道具不同运行不同的代码。其实OD也有给提示caseF0到F7
接着,重新运行,点击指南针,触发断点,将程序运行到这个位置。跳到case F0也就是指南针的case里面,遇到第一个CALL
这里传进去了两个参数,这两个参数是两个局部变量的地址。在数据窗口跟随一下,现在应该是还没初始化。步过这个call
里面的数据已经变成了几个数字,棋盘式一个二维数组,这几个数字很可能是数组的下标,根据数值找到游戏的棋盘这两个位置
发现正好是两个可以消除的,那么这个call就是来获得两个可以消除的位置的call
重新运行,选择点击一个炸弹道具。断在case处
发现又是一个和之前的找两个位置一样的结构。验证确实是寻找了两个能消除的方块位置。
同样利用内存写入断点,使用炸弹道具,通过堆栈调用在call处打断点,分析call的参数,找到一个把可以消除的位置当参数传进去的地方
尝试了下手动点击两个可以消除的方块,发现也会经过这个地方。通过栈回溯找到上一层。并下断点
再次运行到这发现了这几个参数,到数据窗口跟随,确实是两个地址。还有地图的首地址。那这就是消除两个方块所所调用的call了
单步消除:在道具中,有指南针还有炸弹,可以通过找到 指南针的call,分析指南针的算法,的道具给提示的时候肯定会算出哪两个方块可以消除,然后在屏幕点击对应的位置或者直接调用炸弹的call,来实现消除
一键消除:找到对应的剩余方块数量,除以2就是需要消除的次数,就调用几次单步消除就可以了
道具数量:我们已经有的道具的数量的地址,那么直接修改这个值就可以了
消除的功能的话。直接调用炸弹道具会比较方便,当然也可以用指南针的call获取到两个坐标,然后调用消除的call也可以实现,相对来说麻烦了一点。在实际情况中当然怎么简单怎么来。既然是学习,还是用复杂点的方法来让自己理解的透彻一点比较好。
上面的代码是直接使用道具进行消除。因为游戏对消息机制有过滤,所以使用的是自定义消息。通过远程线程注入dll,在dll初始化时创建另一个线程打开一个窗口。点击按钮来向主窗口发送消息,通过消息来调用不同的功能
成功的背后是无数次的失败。尽管最后成功了,里面的原理还是有很多搞不清楚的。路还有很长。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2021-12-2 22:06
被wx_Van_Zovy编辑
,原因: