揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)

这个技巧严格来说和封包外G,关系不是很大,但是可以利用它无脑定位游戏功能Call,可谓是作者找Call最常用的技巧之一了。那不得不说啊,正好帮助大家了解封包。

玩游戏逆向,拿到一款非FPS类型的网络游戏,第一件事情要干什么?我想应该是确定它使用那个系统发包函数与服务器沟通。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
为什么?不想讲太多花里胡哨的道理。举一个单机游戏和网络游戏,释放技能流程的例子。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
单机:捕捉用户键盘消息——》技能相关的几个函数——》直接释放了某某技能
联机:捕捉用户键盘消息——》技能相关的几个函数——》告诉服务器我要释放某某技能

有没有看出什么?
揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
或许不够立体,来写一些伪代码。
按键监听函数{
。。。。。
技能相关函数();
。。。。
}

技能相关函数{
。。。。。
系统发包函数(); // 告诉服务器我要释放某某技能
。。。。。
}

在网络游戏中必须要和服务端通讯,服务器才能把人物的行为动作,同步到其他玩家的客户端上。

而要与服务器通讯,必须要使用到系统的几个发包函数,分别是WSASend send sendto。(向服务端发送一个装有数据的包裹)

根据上面的一些例子我们知道,大家都感兴趣的释放技能函数内部会调用系统发包函数。

那么我们找到游戏使用的发包函数,在函数头部利用工具下一个执行断点(程序走到断点处会停下),那么是不是就可以利用堆栈中函数调用留下的信息,寻找到调用发包函数的技能函数?

PS:堆栈中有调用函数保存的返回地址

原理我们知道了,来看一个小实例。PS:实例中使用的游戏为口袋西游。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
首先,需要找到游戏使用那个系统发包函数,非常简单——需要使用工具OD,使用OD附加上游戏。

按快捷键Ctrl+G,输入发包函数的名字 要注意大小写,
揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
点击OK,即可跳转到响应的函数代码头部。(如果跳转不过来,试试加上 ws2_32. 的前缀)

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
点击函数头部代码,按F2下一个执行断点。如果程序执行到断点处,程序就会停下来。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
3个可能使用的发包函数,我们都这么操作一下。然后在游戏里面操控角色,喊喊话,走走路,做一些肯定会发送封包的动作。

观察一下程序在那个发包函数断下了,那么就说明游戏使用的是那个发包函数。这个游戏使用的是send 函数。如果刚下断还没有做动作就断下,不用感到奇怪。这是客户端向服务端发送的心跳包,证明游戏还活着,你还在线。

准备工作到这里全部结束了,现在我们就可以通过send来定位游戏功能函数了,就来找个吃药Call把。

同样的,在send头部下F2断点,右键药品使用。我们发现程序断下了,注意务必吃药使游戏断下,你要找什么函数就做什么动作让游戏断下。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
按快捷键,Ctrl+F9 执行到返回,OD会返回到上一层调用处。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
很明显上面的Call 就是send函数。不用管它,这不是我们要找到的。再次Ctrl+F9

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
来到这里,我们把上面的函数标记一下(双击右边的部分,添加注释)这个函数就有可能是我们要找的,继续Ctrl+F9 重复上面的操作。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
重复操作个7到8次。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
然后在注释为7这个函数上下F2断点,在游戏里面跑一跑,跳一跳,打打怪,喊喊话,做一些不是吃药的动作。

然后发现程序断下了,如果这个函数是吃药函数的话,那不吃药是不是不应该执行?说明7这个函数不是吃药函数,按键盘上的减号返回上一步。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
重复刚才的操作,下断点 做一些其他的事情。发现游戏都不断下,然后我们打开背包吃药。发现游戏立刻断下,而且按F9恢复运行,游戏没有再断下,那说明只调用了一次。思考一下,我们只吃了一次药,这个函数只在吃药的时候断下,而且只断一次。是不是正好和我们的行为相对应?那么它多半是吃药函数了。

具体是不是我们需要使用代码注入器,自己调用一下试一试。想要调用一个函数,首先需要知道它有没有参数,一般参数以push的形式传递,但是这个函数有点奇怪。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
咋一看,好像它并没有参数。但是我们想一想,如果你来写一个吃药函数,会没有参数吗?单击回车进Call看一看。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
一直翻到函数尾部发现了ret 8,那说明这个函数其实有2个参数。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
这么看来上面这2个push,其实是吃药函数的参数。通过反汇编代码我们可以看见,第二push,也就是函数的第一个参数是常量0。我们不用管它,下个断点吃药使游戏断下看看 push edx 是什么。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
我们发现edx是1,1代表的是什么?观察一下背包。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
发现血药在背包的第2格,有过编程基础的小伙伴应该知道,编程的世界都是从0开始的,那么背包第一个格子实技上是第0格,那么第二格实际上是第1格。已经很明了,唯一变化的参数是药品在背包中的第几个格子。在准备测试函数之前,我们还需要获取一下ecx的值,通常它传递类成员函数的this指针,接下来就可以使用代码注入器测试函数了。

揭秘封包辅助外G:利用系统封包函数,定位游戏功能Call(一)
远程注入代码后,可以看到使用了红药,这说明确实是找到吃药Call了。同理其他的任何功能函数几乎都可以轻松的通过在send函数上下断点,无脑Ctrl+F9找到。大家可以自己试试,找找其他的功能函数。

当然这个技巧我们知道,游戏厂商也非常清楚。一个破绽暴露所有的功能,怎么可能不处理?一般通过两种方式处理:
1.重写系统发包函数。(你不是要在系统函数上下断吗?3个函数都不断,看你怎么办)
2.线程发包。

道高一尺魔高一丈,突破上面2种干扰的方法 由于篇幅有限,咱们下回见分晓!

为方便学习以上游戏使用的都为老版客户端或私服。附上我的Github地址,里面有游戏下载链接和各种文章中使用到的工具,需要请自取:https://github.com/Li-lab-dev/-