猛牛哥
记录网络点滴生活

集结号抢座挂的制作分析过程(一):座位内存的分析

因为集结号棋牌大厅更新的比较频繁,每次更新都需要重新找内存基址,功能call,而本人的脑子不好使,做过的东西一般过几天就会忘,重新做一遍还是要费不少脑筋。经过几番折腾,最后决定把相关的过程记录下来,以便以后游戏再更新时可以少一些工作量。所以,这篇文章不是教程,只是本人的工作笔记,其他人(老手)可以借鉴,但是不适合新手用来学习。

第一步,先用CE搜索到座位的内存地址。一个座位上有人时,其内存值是指向该玩家内存数据的地址;座位上没人时,其内存值是0。根据这个规律可以搜索到某个座位的内存地址,然后查看什么指令写入了该内存,本次得到的结果是:

0044237A – 89 44 8A 54  – mov [edx+ecx*4+54],eax

第二步,关掉CE,打开OD,附加游戏进程,定位到0044237A:

集结号抢座分析-第一次下断

集结号抢座分析-第一次下断

可以看到,基址是来自EDX,EDX又来自该call外部的传参。一般EBP+8是第一个参数,EBP+0xC是第二个参数,EBP+0x10是第三个参数。根据0044237A – 89 44 8A 54  – mov [edx+ecx*4+54],eax这条指令判断,EDX是基址,ecx是座位号,eax是玩家内存地址。在此处下断,然后随便坐个座位,断下后返回到这个call外部看看:

集结号抢座分析-第2次下断

集结号抢座分析-第2次下断

可以看到,这个call前面的3个push就是他的3个参数,根据之前的分析,第一个push是玩家内存地址,第二个push是座位号(一个桌子有N个座位),因为之前看到座位号是取的WORD,所以只看低位的2个字节,高位的2个字节可以忽略。第三个push是基址。在这个call的地方下断,断下后观察堆栈数据,基本符合判断。

第三步:查找基址来源。在第二部中的结果中看到,edx来自local1(其实真实代码是[ebp-0x4]),然后向上找找local1是来自什么地方。可以看到上面不远处有个:mov [local1],eax。而eax上面有个call,可以确定这个eax应该就上上面这个call的返回值(一般的call都是把返回值存在eax中)。所以要想知道edx是怎么来的,就要看看上面这个call(call dword ptr ds:[eax+0x18])里面做了什么。在这个call上下断,然后F7跟进;看到下面代码:

集结号抢座分析-EDX来源

集结号抢座分析-EDX来源

经过仔细分析,这个call的返回值eax的来源是最下面的:add eax,dword ptr ds:[ecx+0x172C],是个加法。第2个加数[ecx+0x172C]中的ecx是外部第一个参数,比较简单。第1个加数eax来自上面的:imul eax,eax,0x1EC,也就是:eax=eax*0x1EC=[EBP+0xC]*0x1EC,所以edx的实际来源是:[参数2]*0x1EC+[参数1+0x172C],这里根据经验可以猜测,参数2应该是桌号,参数1是上一级基址。然后返回到该call外部,并下断查看:

集结号抢座分析-EDX来源call

集结号抢座分析-EDX来源call

第4步,进一步查找基址,第2级基址

通过第三步的结果,看到基址ecx来自于arg1,也就是本call的外部参数1。然后下断,CTRL+F9返回,看到如下代码:

集结号抢座分析-查找基址2

集结号抢座分析-查找基址2

可以看到,基址是eax,来自上面的local.165,然后做了个+0xF18运算。然后在add eax,0xF18处下断,断下后F7单步一次,看到eax的值:0x132E64E0,然后打开CE尝试搜索这个值。为什么要到这个时候用CE搜索?因为这个过程我以前做过,这是经验。第一次分析时不是这样的。CE搜索结果:

CE搜索基址的结果

CE搜索基址的结果

搜索结果有绿色的,说明这是可靠基址。

第5步,整理基址

第二级基址是[0x4d07d8]+0xF18,这就是第三步中的代码:add eax,dword ptr ds:[ecx+0x172C]中的ecx的值。第三步中的代码其实就是计算桌子的地址,算法是:桌号*0x1EC+[ecx+0x172C],即:桌号*0x1EC+[[0x4d07d8]+0xF18+0x172C],该桌子上的每个座位的内存地址是:桌子基址+座位号*4+0x54,即:[[0x4d07d8]+0xF18+0x172C]+桌号*0x1EC+座位号*4+0x54,这样有了桌号和座位号,就能得到这个座位的内存地址,进而可以通过内存判断这个座位上有没有人,然后决定要不要抢这个座位。

至此,抢座工作基本做好了1/3,剩下的工作就是如何实现抢座,然后再把相关逻辑用程序写出来。我更倾向于找到坐下call,然后调用这个call去实现抢座。其实也可以用鼠标模拟点击的方法,简单,找不到call时这是备用的解决方案。但是因为崇拜call的稳定、准确、快速,即使找call的过程会比较繁琐,我也是优先考虑用调用call来实现。具体找call的过程以后有时间了再写。

赞(0) 打赏
猛牛哥原创:猛牛哥的博客 » 集结号抢座挂的制作分析过程(一):座位内存的分析

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏