首页
社区
课程
招聘
[旧帖] [原创][原创][原创]AA对战平台本地服务器 0.00雪花
发表于: 2011-4-21 22:27 1559

[旧帖] [原创][原创][原创]AA对战平台本地服务器 0.00雪花

2011-4-21 22:27
1559
不知道大家有没有听过AA游戏对战平台(可能只有我这个贪玩的学生知道吧)?我是一个Dota爱好者(虽然玩得不厉害),经常上AA游戏对战平台玩。但是,实习之余,有时间准备和同学开黑店的时候,AA的服务器总是不给力,登不上去。因此,就想有没有什么办法解决。当然,产生这个想法的原因是:AA平台在我们学校的校内服务器常年不可用,我们都是先连宽带,登陆网通服务器,这时AA会根据用户名是否属于某所大学来返回房间,通常是网通房间和校内房间两个。然后断开宽带,网通房间会自动关闭,校内房间仍然还在。显然AA平台是P2P结构(不过一般游戏平台都是P2P结构)或者说AA平台“P2P得更彻底”比较准确。因为它只在登陆时与服务器交互(关键在于:AA不用像VS,浩方那样要切换房间),这一点让我直觉认为有办法解决前面提到的登不上去的问题。
      想法其实很简单:
      1、在能登上服务器时,将从服务器那里收到的数据保存下来。
      2、在连不上服务器时,利用自己写的一个简单的本地服务器,将最近一次保存下来数据发给AA。
      想到就动手实验,我实验的方法是利用WireShark截取一次整个登陆过程与服务器通信的数据包,然后自己模拟服务器端的行为向AA发送数据。
      这时有一个问题了:怎样让AA连接服务器时IP指向本地?还好以前在学校bbs上见过一个添加服务器的方法:AA安装目录下有个XML格式的文件ServerList.xml,里面记录了AA登录时能选的服务器名称及对应地址。于是很开心地添加一个叫”本地“的服务器,IP地址为”127.0.0.1“。
      然后利用WireShark开始截取登陆时的通信过程。可以发现一共有三次收发数据,第一次是发送包含用户名、密码的登陆信息,接受登陆成功信息,后两次是发送包含两个房间ID的房间请求信息,接受两个房间的接入点信息。利用WireShark的“Export Selected Packet Bytes"功能导出数据包应用层数据到文件,自己写一个简单的winsock程序,按顺序进行3次recv,send,结果出乎意料的顺利,竟然成功登陆了!
      这时问题又来了:总不能每次都用WireShark手动来备份收到的数据吧,而且这种方法显然大部分AA用户都不会,我总不能在AA服务器挂掉的时候,一个人登上去,自己跟自己玩吧?!因此,有必要把备份数据包的功能做成程序跟本地服务器双剑合璧:能连服务器的时候,自动备份本次登陆的数据;不能连的时候,启动本地服务器,用“本地”选项登陆。
      想来挺简单,但是实际做起来才发现实现自动备份数据并不容易。首先我考虑用raw socket来截获通信数据,但是显然有很多缺点,最大的缺点是会丢包,其次是怎么分辨出需要的包,果断放弃。于是又考虑用winpcap来截包,避免了丢包,但是分辨出需要的包仍然不容易,虽说可以利用源端口号固定这个特点,但是谁能保证没有其他网络服务程序与AA服务器使用相同的端口号,AA客户端的端口号又不是固定的。而且还要安装winpcap。。。可以想象我的程序最多几十k,居然还要另外安装一个驱动,有点不能接受
      后来突然想到了前不久看到的帖子。在看雪论坛“初学者园地 伴你成长”伟大的“资料导航”版面的第一篇“理解OD的F4,F7,F8,F9”,非常感谢作者better,这个帖子让我了解了API hook技术。对!就是API hook。大神请不要笑我,可能在你们看来早该想到这种方法,可是我确实很不容易才想到。
      思路出来了:hook AA的网络通信函数,如send,recv,connect等,后来在网上一搜才发现,这种思路在写网游外挂时其实是很常用的。。。然后动手调试,把AA载如OD,输入bp send,运行,结果没断下来。看下输入函数参考,发现有WSASend,WSARecv和GetQueuedCompletionStatus!十有八九用了完成端口模型。客户端程序居然不用阻塞式的IO模型,跟想象中不太一样。后来想想,作为P2P结构的程序,后面要跟其他用户通信时要扮演服务器的角色,也就释然了,可能为了统一,前面登陆也用了完成端口。于是需要hook的API就有点多了,首先WSARecv,WSASend,GetQueuedCompletionStatus肯定要,然后为了确定跟服务器通信的是哪个socket,于是就要hook connect函数,接着为了确定那个socket对应哪个完成端口,又得hook CreateIoCompletionPort。主要在GetQueuedCompletionStatus中获取数据,控制这种异步的IO对于我这种API hook的新手来说比较吃力。有错误也不太好调试,我都是在dll中加入很多MessageBox来输出一些关键数据,编译好了放到AA文件夹下运行的。附件中有程序和代码,平台为:Win7+VS2005+C。

      在这里请问路过的朋友们:在开发API hook的dll时,一般怎么调试?哪位不吝赐教的话,万分感激!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
用vs启动宿主进程就可以的。
2011-4-22 18:53
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢oforgiven的关注。
你能说说具体怎么弄吗?我用的就是VS2008,有关宿主进程我上网搜了一下还是没搞清楚。
2011-4-23 14:45
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
vs 项目->属性->配置属性->调试

然后在“命令”中设置为平台的exe,工作目录是exe所在的文件目录,有命令行的话就在命令行中填写。
2011-4-24 10:51
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
很感谢你的帮助!我想我知道了。
2011-4-24 15:53
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
尴尬。。。跟想象的不太一样。
oforgiven老兄,我再详细地问一下:
假设我要注入的程序是A.exe,我写了一个用来注入的B.dll,和一个把B.dll注入到A.exe的程序,就叫C.exe
这时我该怎么调试B.dll?
2011-4-24 16:36
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
vs调试启动A.exe,注入后在B.dll的源码中下断就可以了。如果不行的话尝试把b.dll加入到A.exe的导入表中。
2011-4-25 12:37
0
游客
登录 | 注册 方可回帖
返回
//