了解发包函数
1.一款网络游戏,必定是会发包的,对于PC端而言,想要进行网络通讯,就拿最简单的CS架构而言势必会调用win32 API函数或底层函数
2.这里列举出常用的API如:send sendto wsasend wspsend
3.有一些正向开发经验的同学,肯定是见过这几个函数的
4.接下来我们来看看这款游戏到底是调用的那个API呢?或者说是哪几个呢?
确定发包函数
1.我们选中汇编窗口,按ctrl+g,输入send,回车跳转到该函数头部
2.来到函数头部,我们下F2断点,确定是否是send发包
3.发现下断就断,很明显可知很大可能性是send发包
确定包地址是否固定
1.确定了send发包,现在我们来看看该函数的函数类型,主要看参数
int send( SOCKET s, const char FAR *buf, int len, int flags );
2.注意看第二个参数是一个指针,指向一个缓存区地址,我们需要发送的数据就存放在这个缓冲区中,第三个参数是缓冲区大小,说白了就是需要发送数据有多少字节
3.现在我们断下看看这个CALL的第二个参数是否是固定地址
4.在不同操作下,我们发现rdx是固定的地址,由此可见是固定地址
确定是否线程发包
1.我们上面确定了是send发包的包地址是一个固定地址,接下来就好办了,只需要进一步确定是否是线程发包就可以找到明文CALL
2.首先我们要确定该游戏是否用到了线程发包
3.我们这里在send下断点,这里我们寻路触发,注意这里最好操作快点,因为有心跳包的影响
4.我们操作快一点,分别在寻路,喊话断下,按Ctrl+F9不断返回,看是否返回地址一样
5.经过分析不同的操作居然返回的地址几乎一样,由此可见在一个线程中循环执行发包
6.到这里就可以确定是线程发包
跳出线程发包
1.我们确定为线程发包,主要目的是为了跳出线程发包,找到明文CALL
2.现在我们看看如何跳出线程发包呢?其实说白了就是跳出线程
3.这里给大家画了一个正向代码的架构模型图,方便看看
4.正如大家看到的,我们在send流程断下的地方,都属于线程2的范畴,而需要找到明文CALL,则需要跳出(Ctrl+F9)线程2
5.为了跳出线程2,靠Ctrl+F9是不可能跳出去的,因为我们看到一个线程不停的在循环检索固定地址的数据
6.这时候就需要借助内存数据的访问写入断点,从而跨线程的寻找调用代码
7.这里明确要记住的是,你只有内存数据的访问写入才有跨线程的特性,而仅仅靠简单的Ctrl+F9执行到返回是不可能跨线程的
8.所以怎么跳出去呢?其实很简单,上面我们也确定了包地址是固定的,所以只需要在包地址下写入断点就会跳出线程啦
9.这里还需要说明下, 经过我们观察心跳包是8字节也就是只修改了包缓冲区前8字节,所以找好在那个包地址(首地址+偏移)下写入是尤其重要的!
10.当我们寻路的时候,发现修改的是超过8字节的缓冲区,这时候我们就可以利用这个特点,尽量在后8字节下写入
11.当下写入后,我们寻路,此时就断到了线程2以外的代码处啦
12.到这里,基本可以大概率确定跳出去了,但是我们还是需要确定一下!
确定是否跳出线程成功
1.其实确定是很简单的,那就是通过功能触发断下,多返回几层,找到分支的那个点就可以啦
2.正如上面模型图给大家画的那样,这里给大家再画一个流程图
3.通过几个功能的返回CALL分析,我们最终确定了再返回的第二层就是明文CALL,因为这个CALL是基本上所有关于发包的功能都会断下,而只要再返回一层,那就只有
在单独的功能才能断下啦
4.好啦,到此泽诺尼亚的明文CALL就找到了,是不是很简单!
5.最后感谢大家对迪大学院的支持!285530835
www.didacollege.com