原理
单机与联机的不同:释放一个技能
单机:
捕捉用户键盘消息——》技能相关的几个函数——》直接释放了某某技能
联机:
捕捉用户键盘消息——》技能相关的几个函数——》告诉服务器我要释放某某技能
或许不够立体,来写一些伪代码。
按键监听函数{
。。。。。
技能相关函数();
。。。。
}
技能相关函数{
。。。。。
系统发包函数(); // 告诉服务器我要释放某某技能
。。。。。
}
在网络游戏中必须要和服务端通讯,服务器才能把人物的行为动作,同步到其他玩家的客户Duan上。
而要与服务器通讯,必须要使用到系统的几个发包函数,分别是WSASend send sendto。(向服务端发送一个装有shuj的包裹)
根据上面的一些例子我们知道,大家都感兴趣的释放技能函数内部会调用系统发包函数。
那么我们找到游戏使用的发包函数,在函数头部利用工具下一个执行断点(程序走到断点处会停下),那么是不是就可以利用堆栈中函数调用留下的信息,寻找到调用发包函数的技能函数?
PS:堆栈中有调用函数保存的返回地址
实例
首先,需要找到游戏使用那个系统发包函数,非常简单——需要使用工具OD,使用OD附加上游戏。
按快捷键Ctrl+G,输入发包函数的名字 要注意大小写
点击OK,即可跳转到响应的函数代码头部。(如果跳转不过来,试试加上 ws2_32. 的前缀)
点击函数头部代码,按F2下一个执行断点。如果程序执行到断点处,程序就会停下来。
三个可能使用的发包函数,我们都这么操作一下。然后在游戏里面操控角色,喊喊话,走走路,做一些肯定会发送请求的动作。
观察一下程序在那个发包函数断下了,那么就说明游戏使用的是那个发包函数。这个游戏使用的是send 函数。如果刚下断还没有做动作就断下,不用感到奇怪。这是客户Duan向服务端发送的心跳包,证明游戏还活着,你还在线。
准备工作到这里全部结束了,现在我们就可以通过send来定位游戏功能函数了,就来找个吃药Call把。
同样的,在send头部下F2断点,右键药品使用。我们发现程序断下了,注意务必吃药使游戏断下,你要找什么函数就做什么动作让游戏断下。
按快捷键,Ctrl+F9 执行到返回,OD会返回到上一层调用处。
很明显上面的Call 就是send函数。不用管它,这不是我们要找到的。再次Ctrl+F9
来到这里,我们把上面的函数标记一下(双击右边的部分,添加注释)这个函数就有可能是我们要找的,继续Ctrl+F9 重复上面的操作。
然后在注释为7这个函数上下F2断点,在游戏里面跑一跑,跳一跳,打打怪,喊喊话,做一些不是吃药的动作。
然后发现程序断下了,如果这个函数是吃药函数的话,那不吃药是不是不应该执行?说明7这个函数不是吃药函数,按键盘上的减号返回上一步。
重复刚才的操作,下断点 做一些其他的事情。发现游戏都不断下,然后我们打开背包吃药。发现游戏立刻断下,而且按F9恢复运行,游戏没有再断下,那说明只调用了一次。思考一下,我们只吃了一次药,这个函数只在吃药的时候断下,而且只断一次。是不是正好和我们的行为相对应?那么它多半是吃药函数了。
具体是不是我们需要使用代码注入器,自己调用一下试一试。想要调用一个函数,首先需要知道它有没有参数,一般参数以push的形式传递,但是这个函数有点奇怪。
咋一看,好像它并没有参数。但是我们想一想,如果你来写一个吃药函数,会没有参数吗?单击回车进Call看一看。
一直翻到函数尾部发现了ret 8,那说明这个函数其实有2个参数。
这么看来上面这2个push,其实是吃药函数的参数。通过反汇编代码我们可以看见,第二push,也就是函数的第一个参数是常量0。我们不用管它,下个断点吃药使游戏断下看看 push edx 是什么。
我们发现edx是1,1代表的是什么?观察一下背包。
发现血药在背包的第2格,有过编程基础的小伙伴应该知道,编程的世界都是从0开始的,那么背包第一个格子实技上是第0格,那么第二格实际上是第1格。已经很明了,唯一变化的参数是药品在背包中的第几个格子。在准备测试函数之前,我们还需要获取一下ecx的值,通常它传递类成员函数的this指针,接下来就可以使用代码注入器测试函数了。
远程注入代码后,可以看到使用了红药,这说明确实是找到吃药Call了。同理其他的任何功能函数几乎都可以轻松的通过在send函数上下断点,无脑Ctrl+F9找到。大家可以自己试试,找找其他的功能函数。
当然这个技巧我们知道,游戏厂商也非常清楚。一个破绽暴露所有的功能,怎么可能不处理?一般通过两种方式处理:
1.重写系统发包函数。(你不是要在系统函数上下断吗?3个函数都不断,看你怎么办)
2.线程发包。
道高一尺魔高一丈,突破上面2种干扰的方法 由于篇幅有限,咱们下回见分晓!
|