内容参考于:易道云信息技术研究院VIP课
上一个内容:窗口化助手与游戏窗口同步移动
项目需求:
为游戏的聊天功能做一个增强,能够使用户脱离游戏界面的情况下使用窗口化助手进行聊天,能够设置自动回复,记录关键聊天记录,自动说话等
需求由来,很多使用玩游戏是为了社交,社交很重要的方式就是聊天,窗口化助手提供隐藏游戏窗口功能,后期会全自动所以不用盯着游戏窗口,这时可以玩会游戏
实现这个东西,要找到怎样说话,找到消息来了以后,显示的接口,这个实现起来很麻烦,所以要找一个简单的方式。
需求拆解:
方式就是从网络封包通信的地方去解决,所以接下来是重点解读封包,解读网络游戏或者说应用程序网络通信的它的一个架构一个系统,最后落到实处就是,当前分析的游戏中的封包是什么样子的,当把这个解读出来以后,就可以利用网络封包去做,这个功能,不用累死累活的区找call,还原函数了,现在代码里就已经记录了很多地址了,如图1,然后游戏里所有的操作都是通过网络封包来实现的,也就是说不管是游戏也好还是其它的应用程序也好,它的通信系统其实就是它的核心命脉,只要握住了这个命脉其实就找到了一把钥匙,去解决所有的问题
对于应用程序来讲网络通信经典流程:
组织数据 =》加密数据 =》发送数据
接收数据 =》解密数据 =》处理数据
组织数据:
比如说话,这个说话要说给谁?比如要说给张三,然后就是张三然后一个分隔符(比如张三;)因为服务器要读取的,服务器要怎样确定哪个是名字呢?所以它总要有一个方法,然后说话的内容XXX,然后就是张三;XXXX;,然后在给一个时间戳,代表什么时候说的,然后就变成了 张三;XXXX;时间戳;,这就是一个最简单的组织数据,这三个内容通过分号就连接了起来。
加密数据:
数据组织好往往都会进行加密,比如base64加密或其它自己写的算法进行加密,目前来讲加密算法就那几种,专业设计加密的很少,密码学是跟军工是同样级别的东西,我们写的算法都是现有算法的改良或者是一种变种,在一般的应用程序尤其是在游戏里,这种加密算法它基本上都是恺撒密码的变种,恺撒密码的特定是替换或者往后加偏移,一看这个数据是不是恺撒密码就看最根本的就是数据加密前,比如加密前20个字节,加密后还是20个字节,有的数据加密前20个字节加密后16个字节,这个不叫加密叫压缩,面对大型数据会遇到压缩这个情况存在的,然后加密必定会有效率的损耗,它就是为了防止,就是在网络发送的时候会有中间人攻击,这个数据会被拦截,这样的话是不安全的,但有了加密算法加密以后,中间人没有加密算法,就算知道是恺撒密码只要稍微变点变种,想破解难度还是比较大的,攻击成本就会变高,所以加密主要解决这个问题
发送数据:
没什么特殊的就是发送数据
解密数据:
服务器处理完数据也会对数据进行加密,所以要解密数据
处理数据:
比如数据头是0表示说话成功了,也就是根据这个头进行处理。
所以基本上所有网络应用程序都是这样的流程,万变不离其宗
应用程序网络通信的两种架构:发送数据的时候存在阻塞的问题,比如发送一个数据特别大,这时还有用异步通信(完成端口映射或WSA系列函数,虽然是单线程的逻辑,但实际上还是异步的),单线程处理就是先发送完数据再去处理其它的,这时如果是游戏的话它就会卡
1.单线程通信
组织数据 =》加密数据 =》发送数据
接收数据 =》解密数据 =》处理数据
单线程处理所有操作都在一个线条上,发送慢的话就会影响后续的操作
2.多线程通信:如果遇到这种情况,通过发送数据去回溯,只能找到线程二的读取队列的操作,找不到线程一的操作,这时该怎么办?那就是通过监视队列的读取或写入,就能从线程二切换到线程一投递数据进入队列的操作上了
发送数据:
线程一:组织数据 =》加密数据 =》投递数据进入发送队列
线程二:读取发送队列 =》发送数据
接收数据:
线程一:接收数据 =》解密数据 =》投递数据进入处理队列
线程二:读取处理队列 =》处理数据
应用程序网络通信的常用函数:(IOCP完成端口映射例子及说明)
recv、send、sendto、recvfrom、WSARecv、WSASend
recv、send 它俩是老式函数容易造成阻塞,也就是说没有发送完以前什么事都做不了,所以它俩通常会出现在多线程的架构中,不然就卡死了
WSARecv、WSASend 它俩支持完成端口,所以本质上是异步的,然后它俩出现了就没必要使用多线程了,因为完成端口本身就是多线程的,它俩发送的时候只是告诉操作系统要发送,然后就完了,然后由操作系统完成数据发送,操作系统发送完会通知它发送完了,所以看到WSA的函数是一个好消息,因为它采用单线程的架构,然后配合完成端口的函数完成。
图1:现在没有地址变化的问题,如果有就要修改所有的地址,需要写自动更新的算法,这个也是一个不小的工作量,总体来讲还是麻烦