开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 784|回复: 2
收起左侧

[图文资料] 请求FZ"初体验"(一)

[复制链接]
发表于 2020-6-4 22:13:25 | 显示全部楼层 |阅读模式   湖南省长沙市

奥术跃迁

利用发包定位功能函数
处理游戏重写发包函数
处理游戏线程发送封包

封包FZ"初体验"

嘿!大家好啊~ 又是一个被床封印的早晨,被闹钟吵醒的时候才8:35,闭上眼睛睁开眼睛 我就到了 11:07 有没有谁拥有和我一样的能力?





前些日子的几篇笔记,分享了如何快乐Ctrl+F9定位游戏功能Call,和处理游戏在这方面设置的障碍,有没有学会了呢?





假设...啊 我们假设 张三学废了,然后....





然后....
张三就开始快乐的测试功能Call了,嗯 正当张三同学最快乐的时候,客户端弹出了一个小窗口...第三方jc了..张三同学被fh了。
(PS:初次了解封包,最好先看完之前的三篇笔记)





上面的故事真是闻者伤心听者落泪啊,不管是重写发包函数还是线程发包,虽然技法巧妙 但是只要清楚原理 细细分析,总会有漏W之鱼。

所以龙门前不会只有这些困难,后面也是困难甚多.. 比如,功能Call的j测有什么变量j测 堆栈j测,恐怕是层层套娃 MV众多,解决起来更是烦躁无比啊!(欲扬先抑,先夸张一下)





那我们学废之前的技巧有啥子用罗?和上面那些花里胡哨的东西 中路对线?

当然不是,所谓黄河之水宜疏不宜堵,之前的三篇笔记都是铺垫 我们一开始的根本目的完全不是为了快乐的Ctrl+F9。





在揭晓谜底之前我们来观察一个珍贵无比的示例:

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

一款网络游戏角色释放一个技能,大概就是上面这种流程。那比如我们找到了游戏的技能Call 调用它释放技能,会是什么样子?

会变成这样:

技能相关的几个函数——》告诉服务器我要释放某某技能

同学们,有没有看出来什么?哦,张三同学看出来了,同时它还有一个大胆的想法。

其实归根结底就是告诉服务器我干了啥,那我们能不能中间切一下 直接告诉服务我要释放啥啥技能,然后达到释放技能的目的?

当然可以,游戏实际上就是这样释放技能嘛,我们自然也可以这样做,以至于80%的功能 我们基本都能直接自己发送封包实现它。

哇哦!那这样做有什么具体的好处?

通过自己发包,试探变T功能这里就不讲了,我想FZ通常大家有一个很关心的点(小声:嘿~~兄弟稳吗?)





如果把游戏j测比作di雷,那么游戏代码游戏领空就是雷qv,想调用游戏功能call免不了遇到有埋雷的情况,而就算是pai雷老手也免不了会踩上几颗。所谓究极的pai雷方法,就是不走雷qv到目的地,你那有雷我绕着走不就是了么。

这里也是同样的道理,我们走自己的代码通过send()系统发包函数发送封包实现功能,这样就避开了游戏领空的di雷,所以只要是完美的封包FZ90%稳稳的很安心。

既然说到了“完美”二字,当然就有不那么完美的。毕竟自己发包实习功能,可不是说说就完成了。

让我们来观察一个珍贵无比的示例:
组包--》加密--》发包

游戏要发送一个封包,通常都要走这么一个流程。组包:把你做的事打包成小报告;加密:这是你和服务器的小秘密不能让别人知道;发包:把小报告邮寄给服务器。

明显的我们要想完美的达到目的主要有三大难点:
1.分析封包
2.寻找明文封包
3.寻找加密函数

分析封包:客户端告诉服务端我释放了某某技能,总不可能写得汉字吧,所以我们需要分析封包,知道释放技能应该以什么形式描述。

找明文包:系统发包函数上下断确实可以获得封包内容,但是多半是加密的,而且加密的密钥可能随时会发生变化,加密后的内容基本就是一团乱码无从下手没法分析,所以我们得找到内容还未被加密的地方。

加密函数:我们找到明文包了,也分析了放什么技能该发什么包。但是服务器可是要被加密后的封包啊,直接发送一个明文过去 服务器不认事小,第三方就不好了。我们要学客户端,把明文包加密一下,当然 得按游戏的加密方式,那么我们就得找到游戏的加密函数。





找明文包:

(一)理论

明文包的寻找是我们的首要任务,以此为跳板才能分析封包 和 定位 加密函数,如何寻找?不如再来欣赏一下这个珍贵无比的示例:
组包--》加密--》发包

我们可以观察到,从组包完成到加密的这段过程,封包内容是明文的未加密的。通过面对对象的编程原则,我们可以猜测这几个步骤在代码中的表现形式,就是几个对应的函数。

或者说组包完成后,封包数据会通过函数一层一层传递,函数怎么传递数据到另外一个函数?没错,当然是通过参数。那么我们是不是能够在发包处下断,使用传统手艺Ctrl+F9逐层返回所有经过的Call(函数),通过分析他们的参数内容,来找到明文的封包内容?





正确!不过在准备撸起袖子加油干之前,我们还有一个问题需要解决,我们怎么分辨出明文封包内容?要知道这些东西可不会写着I is 明文包,它们在内存之中的形式就是一串数字,而堆栈中所有函数的任何参数也都是一堆数字,怎么办?

想象一下你在茫茫人海中,光凭一个模糊的照片去寻找一个人,这该有多么困难~但是如果那个人的长相特立独行...比如头上长个角?再顶两只猫耳朵..是不是就简单多了?我相信眼尖的你肯定一眼就认出他了。





道理是一样的,那封包里面会不会有这种引起围观的奇怪物种?

我想大多数游戏都是有的,也就是喊话功能 或者 说聊天功能,你想想看在游戏中你和队友聊天,客户端是不是一定需要发送一个装有聊天内容的封包给服务器,这样服务器才能更新到其他玩家的客户端上。

我想大家应该都知道吧,实际上电脑只能储存数字...而字符是通过一张表把一些数字定义为字符,如图:





通过表图我们可以看到,字符 1 的对应数字是49,以十六进制表示 0x31。那么我们喊话一串“11111111111111”断下,它在封包内容里面就是一串 31 31 31 31 31 31....

Nice~ 纸上谈兵不如 真 刀真 枪 的干一架,请出我们的老伙计私服版的幻想神域2 带来一段珍贵无比的简单实例。





(二)实战

先在上面笔记说到的跳出线程发包代码段下断,可以当发包下断可以断到功能函数,当然我们并是要Ctrl+F9去找Call,而是返回上一层寻找未加密的封包内容。

喊话“1111111111”断下.







Ctrl+F9返回上一层调用。





这个call看起来好像只有一个参数,具体还是需要观察堆栈变化才能确定。Call指令下断,断下后F8单步步过 观察堆栈esp增加了多少。





增加了0x4 看来确实只有一个参数,Call指令下断 喊话“11111”断下,分析一下这个参数。





好大的值,像这种值一般是一个地址,这说明这个参数实际上是一个结构体之类的东西,我们数据窗口中查看分析一下。







这个结构体里面的成员也像是地址,我们挨个进去看一下,第一个:





这...显然是虚表函数之类的,反正没有31 31 31  不管他...再看看第二个:





哇,哦~ 一串的31 31 31 31看来我们运气不错只返回了一层我们就找到了明文的封包,如果要确认的话也简单。我们再次再次喊话断下,把这个明文内容修改一下会怎样呢?





放开断点。





我们输入的是 “1111111111111111”,居然喊出了 “1111155555111111”这就是n向的魅力,这也就说明我们确实找到了明文封包的位置了。

我们不如发散一下思维,如果我们调用这个Call是不是就可以直接发送明文内容实现功能了,而不必再费力寻找和分析加密函数了?

的确,从实现功能的角度讲,只要分析透了这个函数是能够实现所有的功能,但是这样还是过了游戏代码 并非“完美”的,我们从学习角度出发接着分析。





找加密Call:

(一)理论
加密call在哪?想想我们跳出线程发包代码段那,封包内容应该已经被加密了,因为下面的代码再走就是把封包内容复制到全局变量里面,然后被发包线程发送出去了。游戏不可能让发包线程里面有明文内容,不然我们是不是就不用幸苦跳出发包线程了,直接分析明文的封包内容 岂不美哉?

然后我们返回一层,在传入参数里面发现了明文包,哪说明加密函数就应该在 上层之下,跳出线程发包代码段之上。哪我们的范围就小太多了,我们可以在函数头部跟踪明文内容,加密call必然会需要这个参数!

(二)实战
我们来到函数头部追踪一下明文内容。





在头部发现一个堆栈的值,直接赋值给寄存器。一般来说这种[esp+0xXX]要么是局部变量,要么是函数调用者传入的参数。而这里是函数头部,上面没有对[esp+0x14]初始化的代码,这说明它不是一个局部变量而是一个被传入的参数。

原因很简单,因为局部变量的空间都是在堆栈划分的,而堆栈被反复使用里面有非常多的垃圾数据,所有如果局部变量不初始化谁也不知道它的值是啥。

当然如果看见[esp+0xXX]而自己没有啥把握的话,最好去堆栈中观察确认一下,这是最稳妥的。

那么现在edi是参数首地址了,我们再往下看。[edi+0x4]赋值给了ebp,还记得我们上面寻找明文封包的分析么,这个参数是一个结构体,他的第二个成员就是封包内容首地址。
[edi]是第一个成员,[edi+0x4]是第二个成员,那么现在ebp是明文封包内容首地址了。

再往下看,ebp和[edi+0x8]做比较,[edi+0x8]是第三个成员,这时候我想到了数组,存放数组首地址的地址+0x4通常是数组的尾地址,edi+0x8和edi+0x4  应该是这种情况。那么这个操作就很好理解了,应该是判断数组的长度..或者说里面有没有东西。

接着分析,顶住ebp这个封包内容,看有没有那个Call把它作为参数。





最后发现在范围内只有这个call把封包内容当作参数传入了,基本上可以断定它就是加密Call了。

很明显它有4个push的参数,前两个都是来源[edi+0x4] 至于为什么传2个一模一样的我们不管他,而第3个push 往前面翻一翻可以发现来自于 [edi+0x8]-[edi+0x4] 前面说过了这是尾地址减去首地址,应该是封包长度。

我相信你也看见了,它先把封包首地址+0x2 封包长度-0x2, 也就是说封包内容前2个字节是不加密的,来看看之前的封包截图。





我想前2个字节应该是代表这个封包前2字节之后的有效长度,之所以不加密应该是游戏服务器可以更好的读取和区分。

第4个push下断一看它是不断变化的,也不难猜 估计是密钥 加密就像是用密钥上锁,服务器拿到之前再用密钥打开。密钥应该是服务器隔一段时间更新下发一次,我们要想获得它得往上回溯得到它的偏移表达式和基地址,从里面读取就没问题了,基本功内容就不写出来了 这里没几个偏移就找到基地址了。

摸清楚了函数的参数,我们已经可以直接调用它来加密我们自己组装的明文包了,这样就可以用send()发给服务器了。同样的,这么做也并不“完美”,我们先进加密call里面去看看代码。




(代码太多就不放老长的图了,假装一下它是那种长图~)

我们发现这是一Call到底,里面没有调用任何其他的call,下断F8执行一遍之后也没有发现什么花里胡哨的跳转。那么我们另一条路就好走多了------tou功能! 顾名思义,我们要tou游戏加密call的功能。

怎么tou?其实也很简单,C++ 是支持内联汇编的,正好OD工具直接帮我们把汇编显示了出来,直接复制到我们的代码里面,只不过需要稍稍修改一下——JCC指令。

OD反汇编显示出来的JCC 跳转指令后面都是直接跟得立即数,内联汇编中并不支持这种写法,所以我们全部改成标签跳转就可以了,没什么技巧和技术 就是需要一点汇编基础和细心耐心。

如图:建议写一个裸函数,__asm 内联汇编把汇编复制进去就得勒。




(假装...一下..放个N长得图或者代码也没意思..)

这样就可以调用我们tou出来的函数加密了,由于是直接复制出来的,所以效果和原版一模一样。不过在我们用参数最少最简单的发包函数send()带货之前,我们还需要 打 通 最 后一公里,先看看send()函数的定义。





第2 第 3 个参数也就是封包内容和长度我们有,第4个参数 常量0 我们不用管他,但是第一个参数需要解决一下,这代表东西要送到那里去。

好在三大发包函数第一个参数都是SOCKET套接字描述符,游戏里面使用的WSASend 函数当然是的,所以咱们可以直接Ctrl+G到WSASend里面下断点Ctrl+F9到调用处回溯第一个参数。





ECX看来就是我们要找的SOCKET了,都帮我们标注出来了,暖暖的很贴心~!

随便往上翻一个偏移,来到了这,如图:





游戏为了获取SOCKET调用了这个函数,不过OD已经帮我们标注出来了,那我们肯定没必要进Call追数据了,OD认识的肯定是系统的API函数,我们直接上网查查这个函数是咋回事,然后学着游戏的样子调用它就ok了。





第二个参数游戏直接传入了常量0x15 所以我们不用关心它,第一个参数是一个窗口句柄...我们怎么才能方便的获取它呢?

既然它是一个窗口句柄那么可以使用 FindWindow() 系统API函数获得,但是这个函数需要一个窗口类名,或者窗口标题....嗯,这就不得不借用Visual Studio自带的工具Spy++了。





Spy++根据窗口句柄的数值查询到窗口的类名或者标题名,而窗口句柄的数值我们可以在游戏调用GetWindowLongW的地方下断复制出来(可惜下次打开游戏会变化,不然也不用这么麻烦了),然后扔到Spy++查询一下就OK了,如图:








这下就得到类名拉,只需要通过FindWindow()传入这个类名就可以获得我们想要的那个窗口句柄了~!
接下来只需要把我们上面讲的内容有机的结合一下,就可以封装成我们自己的明文发包函数拉~!


(未完待续)

点评

帖中工具、游戏、完整源码geihub链接 https://github.com/Li-lab-dev/-   广西壮族自治区桂林市  发表于 2020-7-19 21:39

发表于 2020-6-6 09:36:31 | 显示全部楼层   吉林省长春市
6666#在这里快速回复#
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

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