游戏网络架构逆向分析--1

测试需求和拆解

网络游戏客户端与服务端协同形式:

一般分为两种情况:

  1. UI操作->吃药-> 生命值增加-> 发送服务器   (发送结果型)
  2. UI操作->吃药->发送请求吃药->服务器验证->服务器完成吃药->客户端同步显示

发送结果型:
首先在界面里按了吃药的操作,按下吃药的操作以后,生命值增加,客户端会看有没有药水,有没有cd 能不能吃,生命值就增加了,然后把这个血量发送给服务器,但发送给服务器前的这个是可以改的比如直接改成999999,这不就无敌了吗,所以用这种操作往往会有一系列加密的技术防止去修改,但再怎么修改本质上就是能改,这不是技术高低决定的,是这种结构就决定了能改,大部分都不会采用这种结构

另外一种比较完善的:
UI操作,首先检测有没有药水,在不在cd,能不能吃,然后告诉服务器要吃药了,服务器收到这个要吃药的请求也要看服务器上的数据:有没有药水,在不在cd,能不能吃,然后服务器就把吃药操作完了,接下来服务器把血量写到数据库里,再给客户端发送个消息 吃药完成了,这个过程是不是就严谨了很多,从整个流程看,可攻击的地方很小,在客户端和服务端都检测了一次,客户端的检测排除掉了以后,服务端的压力就会变小,这个主要是为了保护服务器,有的游戏就会把第二步取消掉了,都由服务器完成,这样服务器的压力就会大,服务器就有可能变卡

实际上,不是所有游戏都采用第二种,其实大部分的游戏都是第一种和第二种相结合(安全本质就是经济的对决),用第二种方式行,但成本比较高,这是一个吃药的操作,但有的操作非常频繁,比如走路,这种操作在服务器上验证是比较困难的,在服务器验证困难就会消耗大量的时间,客户端是一个面对服务器,服务器是一个面对N个玩家,所以同一时间要处理大量的消息,虽然现在硬件水平变好了,但依然还是很有压力的,有的时候服务器不得不放弃一些验证的操作,改用第一种结果式的发给服务器,从而就造成了漏洞,有的时候用了第二种,但是连续性的,比如需要三个第二种操作才能完成整个操作,如果其中某一个被我们人为忽略掉了,修改掉了,也会造成漏洞,只要都是在网络通信这块

        网路通信是一个网络游戏的核心命脉,可以说大多数的游戏漏洞都是利用网络通信设计的不合理来实现的,比如绝地求生游戏中早期出现的一击必杀,瞬移等漏洞

        逆向分析游戏宏发送数据和接收数据的过程,寻找游戏数据包明文发送与接受的关键函数,并且尝试利用该函数发送和接收数据

        对于网络游戏中数据包漏洞利用的特点,给出检测和修复建议

网络游戏通信操作模型

UI操作   -》组织数据-》加密数据-》发送数据
接收数据-》解密数据-》分发数据-》使用数据

比较小型的会用单线程通信

一般大多是多线程通信

  1. 线程A:UI操作-》组织数据-》加密数据-》写入数据至发送区
    线程B:读取发送区数据-》发送数据
  2. 线程A:接收数据-》解密数据-》写入数据至分发区
    线程B:读取分发区数据-》分发数据-》使用数据

常见函数:
send recv 一般用于tcp通信,默认为阻塞型(可以改成非阻塞)
sendto recvfrom  一般用于udp
WSASend  WSARecv  一般配合完成端口使用

通过逆向分析确定游戏明文数据包发送数据过程

数据包有关的关键信息:

char* buffer 数据包
unsigned len 数据包长度

我们要找的是明文数据发送的那个函数,要实现这个过程,至少要提供明文的数据包和数据长度
这个数据包跳过去一定有可辨识的,比如说话123,那里面就是123,里面就有,这就是明文,使用技能就有技能的ID或者编号,使用物品就有物品的代码,光有数据包不行,本身来说就是一段数据,就是一个指针,那数据包到底多长必须得给出来,长度不可能太长,总不可能发个这么长的片把?长度一般就是几百几十的样子,也可能数据包和包长混在一起的,数据包前面就是包长,后面就是内容,这样就只能看到一个东西,不管是哪一种,这个都是很敏感的东西。发送数据是这样的,那么接收数据也是一样的道理,也是这两个关键的信息,不然不好解析。

首先connect和WSAConnect下断
登录
游戏网络架构逆向分析--1_第1张图片

可以直接看到IP地址 
游戏网络架构逆向分析--1_第2张图片

翻一下栈 ,这就是ip和 端口 

随便看看调用过程
游戏网络架构逆向分析--1_第3张图片

 返回值等于-1就执行WSAGetLastError

 这个地方大概就是它建立连接的地方,没什么太多可以注意的
但有一个地方还是要注意,如果连接成功,能拿到它的套接字,这个套接字肯定会保存起来
这个connect往上跳

游戏网络架构逆向分析--1_第4张图片

发现是个虚函数 

传入的两个参数是IP地址和端口 
这个地方应该就是连接,连接完了要发送账号密码的操作
这个ecx也先保存一下

然后send和WSASend都断下
发现send被调用

游戏网络架构逆向分析--1_第5张图片

上面这四个传递参数就比较奇怪  他可能是编译器的问题esi代替了 ecx,第二种可能是编译器的优化策略,但这种优化策略很少见

这个地方直接暴露了这发送失败了 ,相当于给别人提供武器了

 这个函数没啥,也就是个发送的封装,也没什么值得一提的东西,还得看看上级
游戏网络架构逆向分析--1_第6张图片
游戏网络架构逆向分析--1_第7张图片

 就比较明显了,这是数据的发送过程

这参数一看就是数据包和数据包长度
这就要测试是不是,看看数据包内容,内容看不懂,因为不知道是啥样的数据包

 那我们就自己发送一个可以分辨的数据包

 

 直接是明文了,直接改一个
  所以这个地方恰恰就是我们想要的
这个 地方又是个虚函数,和connect很像

 

 ecx = 3CDAF4A8

发送数据的时候要建立网络连接,指针一定是和跟网络有关系的值
这是个虚函数 就是thiscall 用 ecx传递参数

改一下参数,eax ebx改成0看看崩不崩:
结果也只是断线了,但没崩溃什么的问题,所以这个函数用法就是得到ecx就可以,而ecx可以通过网络连接获取,所以只要在这个地方做个小小的HOOK就能知道这个函数是什么样的情况了,有哪些地方调用了它,发送的是什么内容看看这个函数:

游戏网络架构逆向分析--1_第8张图片

这就是我们发送数据的过程 

游戏网络架构逆向分析--1_第9张图片

往下翻就看到了刚刚那个发送数据函数 esi这个东西应该就是加密好的数据放进来了
上面那个函数应该就是加密数据的函数

在发送数据这截取
游戏网络架构逆向分析--1_第10张图片

发现这貌似是个明文..... 
一开始:

 调用完那个加密函数:

 数据包本身数据是没有变化的 就只加了个EE 加EE主要是为了防止粘包,服务器好处理,但里面没有个长度有关联的数据 万一也出现了EE 就寄了,如果数据包里没有长度光靠结尾加个EE是解决不了问题的,而且,居然没有加密的过程?可能是因为这是比较早期的客户端,没有加这个,当然,对于我们逆向来讲,加不加密不重要。目前来看 这个是只加了个EE

我们使用发送数据肯定是使用那个过程的发,在这也可以用那个send的发,但其他游戏加密肯定很复杂,那肯定是要调用本身的加密过程来完成加密的
问:
游戏网络架构逆向分析--1_第11张图片

这段函数干了什么 ,EE咋加上去的,这个循环用C++还原出来

通过逆向分析确定游戏明文接收数据过程

基本上用的send,反过来就是recv
游戏网络架构逆向分析--1_第12张图片

 

 eax是长度   eax 309说明这里有过个数据包
游戏网络架构逆向分析--1_第13张图片

这里又出现EE  而数据包里也有EE..不就解析么 
这个esp+edi+37C edi现在是0 表明这个可以变化,这是个典型的数组
一般数组是 esp+edi*4+x  
esp+37C 就是 char* buffer[0x800]
游戏网络架构逆向分析--1_第14张图片
因为这前面传了个0x800内容,所以大小应该就是0x800,所以前面压栈压了个b78这么大

0x800-0x37C+4刚好是0x800 esp+37C是局部变量的buf的指针

edi后面肯定会处理让edi+
这地方操作就相当于 cl = buf[0]
if(buf[0]==0xEE)

 然后一顿操作
游戏网络架构逆向分析--1_第15张图片

edi++   这肯定也是个循环 读取数据包,肯定就读取到EE结束
2个EE结尾了就不跳了

 游戏网络架构逆向分析--1_第16张图片

很明显是用的结构体传参

 游戏网络架构逆向分析--1_第17张图片

 这个函数就是 ebx相当于指针,esi,edi相当于里面两个内容
游戏网络架构逆向分析--1_第18张图片

这个应该是thiscall 但是用 eax来代替了ecx
传了esi edi 肯定就是数据包的内容了

直接肉眼可见了 

刚好EE前 
自己发消息接收试试
游戏网络架构逆向分析--1_第19张图片

 

 这个时候改一下:接受到的数据也变了

这地方就是接收数据
发现类都是一样的
首先在网络连接建立的时候会创建一个类,它的指针在我们网络连接的时候就能截取到了,截取到了以后,我们发送数据,接收数据都能够用。发送数据刚刚看了是标准的虚函数,但这个接收数据,因为代码优化的情况下,不是虚函数,用起来就比较麻烦。
首先

 

这个函数里就是用了eax来代替了ecx,这个函数要调用起来,不写汇编代码还比较麻烦。。但用起来肯定没啥太大问题,所以我们关键就是这个点。接下来要做的就是大量数据包分析了,接下来要把所有数据包打印出来,然后看是什么情况,这次核心目的就是尽量少去逆向,尽量用封包看看能不能把游戏构建起来,尽量尝试性的往脱机走走

你可能感兴趣的:(C++测试角度,c++,windows,网络)