没有ggplot这个函数_利用系统发包函数,无脑定位游戏功能函数

本文围绕网络游戏逆向展开,指出拿到非FPS网游,首先要确定其与服务器沟通的发包函数。以释放技能流程为例说明联机游戏需与服务端通讯。通过工具OD找到发包函数并下断点,以口袋西游为例介绍定位吃药Call等功能函数的方法,还提及游戏厂商的应对方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

玩游戏逆向,拿到一款非FPS类型的网络游戏,第一件事情要干什么?

我想应该是确定它使用那个系统发包函数与服务器沟通。

ad48935404cb7af83c114a3c4202dcf7.png

为什么?不想讲太多花里胡哨的道理。举一个单机游戏和网络游戏,释放技能流程的例子。

e400f73b54574447a8ae210d303a1445.png

单机:

捕捉用户键盘消息——》技能相关的几个函数——》直接释放了某某技能

联机:

捕捉用户键盘消息——》技能相关的几个函数——》告诉服务器我要释放某某技能

有没有看出什么?

b1542fa8fb9ad3c260b78cd2821666f5.png

或许不够立体,来写一些伪代码。

按键监听函数{

。。。。。

技能相关函数();

。。。。

}

技能相关函数{

。。。。。

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

。。。。。

}

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

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

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

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

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

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

6e70ec4fefb459b885b07a5916a05d98.png

首先,需要找到游戏使用那个系统发包函数,非常简单——需要使用工具OD,使用OD附加上游戏。

按快捷键Ctrl+G,输入发包函数的名字 要注意大小写,

26f8f775cf36961828a1332569935257.png

点击OK,即可跳转到响应的函数代码头部。(如果跳转不过来,试试加上 ws2_32. 的前缀)

026371ca74367b40419fb1e62eba2e8b.png

点击函数头部代码,按F2下一个执行断点。如果程序执行到断点处,程序就会停下来。

f0d3b87cd190094a9ea226bae024cdc6.png

3个可能使用的发包函数,我们都这么操作一下。然后在游戏里面操控角色,喊喊话,走走路,做一些肯定会发送封包的动作。

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

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

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

7dab115f98eb218037004e0d3e2895ff.png

按快捷键,Ctrl+F9 执行到返回,OD会返回到上一层调用处。

a008b845eec6c094331474b180a5ee36.png

很明显上面的Call 就是send函数。不用管它,这不是我们要找到的。再次Ctrl+F9

92caf2c3476b4fd26568b3009f8e4631.png

来到这里,我们把上面的函数标记一下(双击右边的部分,添加注释)这个函数就有可能是我们要找的,继续Ctrl+F9 重复上面的操作。

594c9ea8364597b338167ef131992de7.png

重复操作个7到8次。

0197e6a1d29a3329e8502ad8e6ae5455.png

然后在注释为7这个函数上下F2断点,在游戏里面跑一跑,跳一跳,打打怪,喊喊话,做一些不是吃药的动作。

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

528adcd935d09878883aae4144618f34.png

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

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

d47840e5251e164247f7a35913643963.png

咋一看,好像它并没有参数。但是我们想一想,如果你来写一个吃药函数,会没有参数吗?单击回车进Call看一看。

c2d0e52796842ce29fb448f5344c9fdd.png

一直翻到函数尾部发现了ret 8,那说明这个函数其实有2个参数。

d13392b7ef095489f2afda8aa6f5b139.png

这么看来上面这2个push,其实是吃药函数的参数。通过反汇编代码我们可以看见,第二push,也就是函数的第一个参数是常量0。我们不用管它,下个断点吃药使游戏断下看看 push edx 是什么。

fe120a1686a504d8ef6f23e4e5cc04cc.png

我们发现edx是1,1代表的是什么?观察一下背包。

862c9e4861eea2c9295d8e2b10c3ad07.png

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

2c97069afe842ac85f374b28c251e30a.png

远程注入代码后,可以看到使用了红药,这说明确实是找到吃药Call了。同理其他的任何功能函数几乎都可以轻松的通过在send函数上下断点,无脑Ctrl+F9找到。大家可以自己试试,找找其他的功能函数。

当然这个技巧我们知道,游戏厂商也非常清楚。一个破绽暴露所有的功能,怎么可能不处理?一般通过两种方式处理:

1.重写系统发包函数。(你不是要在系统函数上下断吗?3个函数都不断,看你怎么办)

2.线程发包。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值