12558网页游戏私服论坛

 找回密码
 立即注册
游戏开服表 申请开服
游戏名称 游戏描述 开服状态 游戏福利 运营商 游戏链接
攻城掠地-仿官 全新玩法,觉醒武将,觉醒技能 每周新区 经典复古版本,长久稳定 进入游戏
巅峰新版攻 攻城掠地公益服 攻城掠地SF 新兵种、新武将(兵种) 进入游戏
攻城掠地公 散人玩家的天堂 新开 进入游戏
改版攻城掠 上线即可国战PK 稳定新区 全新改版,功能强大 进入游戏
少年江山 高福利高爆率 刚开一秒 江湖水落潜蛟龙 进入游戏
太古封魔录 开服送10亿钻石 福利多多 不用充钱也可升级 进入游戏
神魔之道 签到送元宝 稳定开新区 送豪华签到奖励 进入游戏
神奇三国 统帅三军,招揽名将 免费玩新区 激情国战,征战四方 进入游戏
龙符 三日豪礼领到爽 天天开新区 助你征战无双 进入游戏
王者之师 免费领豪华奖励 免费玩新区 6元送6888元宝 进入游戏
查看: 262|回复: 0

逆向在线游戏加密通信协议

[复制链接]

505

主题

505

帖子

1020

积分

实习版主

Rank: 7Rank: 7Rank: 7

积分
1020
发表于 2020-2-28 10:44:18 | 显示全部楼层 |阅读模式
看到有朋友在问工具名称,说一下用到的工具
API monitor + IDA + VS2017
在下菜逼,偶然得到一款韩国游戏的客户端和服务端,因为个人兴趣想开个sf,然而架设部署过程中发现缺少一个关键组件:游戏负载均衡网关,这个组件负责在客户端连上之后给客户端提供环境变量信息,以及分配游戏服务器IP,这本应该是服务端的一部分,然而却缺失了。
本来想找人逆向,身边朋友问了一圈,淘宝找了一圈,一万都没人干,我去,只好硬着头皮自己撸起袖子干。
搞了一个礼拜终于完工,分享一下中间的过程。
一步一步来:
1.修改客户端IP指向。
客户端下载回来,要想仿制服务端,首先要把客户端连接IP改成我自己服务器的IP,这样客户端连上我的服务端,这个应该不难。

我分析IP要不然写死在exe文件里,要不然卸载配置文件里。exe文件搜了一遍字符串,并没有搜到IP字符串,ascII和unicode都没有,那么看看有没有写着IP的配置文件:

New.dat和Version.dat都是音量大小,版本号之类无关紧要的配置信息,这个New.rst里面是不可识别字符串(俗称乱码)

长度正好是16的倍数,我怀疑是AES之类的block加密算法,因为要对齐block,所以长度是0x10的整数倍(时候发现block不是16是2,唉,算是蒙对了),为了验证我的想法,跑一遍游戏,监视系统API调用和自带的dll调用,大致看一下游戏外部调用的流程:



选上Networking相关和加密相关(系统自带的加密API都是从ADVAPI32.dll里导出的),以及自带dll,然后游戏跑起来走一遍。
跑完成了两万多个call

exclude掉几个出现太频繁的,先找connect:

找到connect,那么如何获取到这个IP,一定在connect之前,既然我怀疑IP是从被加密的配置文件里来的,那么就重点看加密API
顺着connect网上找,果然,找到了

根据api call看参数,密钥、交换算法、hash算法、block size都写在里面,照葫芦画瓢写个加解密程序,最终成功解密New.rst:

明文IP和端口号都在里面,不过显然,这个文件是有数据结构的,不管怎样,IP指向算是搞定了,继续下一个环节。

2.分析通信协议,研究他如何加密的,如何封包的,包内结构如何。
这部分是耗时最多的,首先抓包看一下,

这两个包都是分两次抓取、通信开始时的第一个包(目测握手包,或者say hello 之类的),这里可以看出来,相同类型的的包,包头和包尾一样,中间不一样的部分应该就是经过加密的包体,因为每次不同,可以判断明文中加入了时间之类的随机字符串,这个情况想重放是不可能了,只能老老实实逆向他协议了。
下面就是要找到他数据包的结构,和加密方法,来看一下主程序的导入表:

这几个函数从字面意义来看跟加解密关联很大,这个时候不急着分析dll,先回到捕获的API调用,看看调用顺序

这写信息非常关键,我们可以根据外部接口调用顺序看出来,包是经过如下流程解密的
tryDeserializeIncomingPacket ->tryDeframeIncomingPacket ->Decrypt ->crc16 ->Decode
中间经过crc16这个步骤,可以说明数据包中某个部分有校验码,这个等会儿再说,下面该IDA出场了,一个函数一个函数分析
1.tryDeserializeIncomingPacket:

函数内容比较简单,直接把参数传给另一个函数,目测就是进了tryDeframeIncomingPacket ,具体怎么样开debuger跟踪就知道
在call下断,跑起来停在这个call,step in跟进去,果然是进了tryDeframeIncomingPacket

不过这边也没什么实际作用,继续进下一个call


这边虽然点了analysis module,然而不知什么原因IDA的分析没有起作用,猜测有可能是因为从静态分析的dll换到了另一个内存中加载的dll的领空,那么重新加载tryDeframeIncomingPacket所在的dll
现在IDA顺利分析出来了函数结构,经过反反复复的调试,tryDeframeIncomingPacket前半段代码如下

根据分析真个数据包的格式如下:
923E(包头标识) + ServiceID(用来判断数据包的作用,然后进行相应回调) + 包长度 + 02 00(作用不明,不过是固定的) + CRC16(用来校验包体) + 包体 + EC3E(包尾标识)
继续往下看,包体如何解密


解密包体使用的是一个叫CRijndael::Decrypt的函数,Rijndael是AES的别称,CRijndael我猜测是用C写的Rijndael,这应该是一个第三方组件,到google查查看

哈哈,这不就有了,经过一番寻找,找到了CRijndael的代码,还是老办法,照葫芦画瓢,先看看主程序的API调用,把key找到

生成密钥的函数MakeKey在主程序初始化阶段就调用了,可见这个key是全局使用的,后面不会发生改变,所以一开始就Makekey,现在可以开始画瓢了
把代码下载回来一番修改编译, 跑一遍

解密的结果跟游戏程序自己解密的结果完全一样,这下加解密包体就算是ok了。
协议逆向部分最后还剩一个问题,CRC16校验码,这个问题刚入手感觉很简单,CRC16校验码的算法github上要多少有多少,没想到代码下回来跑了一遍发现个大问题
传入参数一模一样,但是生成的校验码跟他完全不同,这个地方花了很多时间研究,最后发现问题在这:


这个crc16是个查表算法,原来网上下到的crc16的表跟他的表不一样,继续IDA跑起来把

左边是汇编,右边是github上的crc16,一目了然,顺利找到256字节的table,替换进源代码,这次返回的CRC16校验码总算是对了
到此为止,加密协议分析就算是完成90%,剩下10%是明文包体的数据结构,这部分主要跟程序的业务相关,就不在这多说了。
最后根据协议的结构和加密算法,我写了一个游戏网关服务端,一万块都没人干的工作自己干了,爽。。。

感谢各位看官,欢迎大牛指点交流

来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
楼主热帖
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|12558网页游戏私服论坛 |网站地图

GMT+8, 2024-4-29 10:17 , Processed in 0.109375 second(s), 31 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表