现在的位置: 首页 > 综合 > 正文

PCQQ UDP协议的研究<1>——准备工作

2019年08月26日 ⁄ 综合 ⁄ 共 4491字 ⁄ 字号 评论关闭

http://www.10qf.com/thread-24-1-1.html

很多朋友都对PCQQ很感兴趣,大概都源于对这只企鹅的喜爱吧。PCQQ协议之所以这么多人想去研究,除了研究本身能带来的满足感之外,最主要还在于这种协议的挑战性。

    那么,PCQQ的分析要从那里开始呢?这是新手们都会问的一句话。别急,我也是新手。不过这方面我还算有稍许的经验。不过这个PCQQ嘛,本身没有什么技术含量,所以,不要有什么心理包袱。再所以,请大家不要直接问我有没有PCQQ的源码,这样很不礼貌,对吧。呵呵!
    好了,说起PCQQ,我们就不得不提到套接字(socket),TCP/IP,UDP,这些概念说难不难,说易也不易,要看我们的理解程度了。具体这些概念大家还是看一下百度吧,那儿有专家们的权威解释。套接字是两台主机之间的通信约定,具体是协议规则不是某一种编程语言所特有的。也就是说在windows平台下,我们要使用套接字只要调用平台帮我们封装好的win32
API就行了.而在各自的编程语言里,官方都会在运行的支持库或框架里封装好适合自己语言风格的类库,供代码里调用。

    在这里,我以c#为例,给大家说一下怎么开始我们的PCQQ之旅吧!
    第一步:
    打造适合自己的UDP封装类。
   UDP类封装遵循以下流程:绑定端口(这一步可以省去),连接服务器,完了之后接收消息。
这里我给大家参考一下我一个项目里的代码,但是大家要自己理解后写成自己的代码,否则咱们就没有下文了。

[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using Lingchen.Common.Utils;

namespace Lingchen.Net.QQCore
{
/// <summary>
/// 连接管理类
/// </summary>
public class ConnectionManager
{
public bool IsConnected
{
get
{
if (this.m_udpCLient != null) return this.m_udpCLient.Connected;
else return false;
}
}
/// <summary>
/// 接收缓冲区大小
/// </summary>
internal const int RECEIVE_SIZE = 1024 * 24;
/// <summary>
/// 发送超时设置
/// </summary>
internal const int SENDRECEIVE_TIMEOUT = 3;
/// <summary>
/// 服务器的IP终结点
/// </summary>
public IPEndPoint ServerPoint { get; set; }
/// <summary>
/// 客户端IP地址
/// </summary>
public IPAddress ClientIP { get; set; }
/// <summary>
/// 服务器时间
/// </summary>
public DateTime ServerTime { get; set; }
/// <summary>
/// 是否需要重定向服务器
/// </summary>
public bool NeedLocation { get; set; }
/// <summary>
/// Udp封装访问对象
/// </summary>
private Socket m_udpCLient;
/// <summary>
/// 所有事务管理都经过此对象
/// </summary>
private QQClient m_qqClient;
/// <summary>
/// 接收字节缓冲区
/// </summary>
private byte[] m_receiveBytes =new byte[RECEIVE_SIZE];
/// <summary>
/// 管理事件
/// </summary>
private EventStrategy m_eventStrategy;
public ConnectionManager(QQClient client,EventStrategy eventStrategy)
{
this.m_qqClient = client;
this.m_eventStrategy = eventStrategy;
this.NeedLocation = false;
this.ServerPoint = new System.Net.IPEndPoint(IPAddress.Parse("112.95.242.111"), 8000);
}
/// <summary>
/// 初始化UDP连接
/// </summary>
public void InitConnection()
{
if (this.m_udpCLient != null)
{
try
{
this.m_udpCLient.Shutdown(SocketShutdown.Both);
}
catch
{
}

}
this.m_udpCLient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
#region 绑定本地端口,这一步可有可无
if (!this.m_udpCLient.IsBound)
{
int port = 4000;
while(true)
try
{

this.m_udpCLient.Bind(new IPEndPoint(IPAddress.Any, port++));
break;
}
catch { }
}
#endregion
//this.m_udpCLient.SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.ReceiveTimeout , SENDRECEIVE_TIMEOUT);
}
/// <summary>
/// 启动连接
/// </summary>
/// <returns></returns>
public void Start(bool needConnect)
{
if (needConnect)
{
try
{
this.m_udpCLient.Connect(this.ServerPoint);
}
catch
{
}
}
if (!this.IsConnected) this.m_qqClient.EventStrategy.TriggerLog(this.m_qqClient, new SocketErrorEventArgs() { Message = "服务器连接失败,请检查网络连接是否正常", LogType = LogType.Exception });
else
{
this.m_udpCLient.BeginReceive(this.m_receiveBytes, 0, this.m_receiveBytes.Length, SocketFlags.None, (p) =>
{
int length = this.m_udpCLient.EndReceive(p);
if (length > 0)
{
//过滤
ByteBuffer buf = new ByteBuffer(this.m_receiveBytes, 0, length);
this.m_qqClient.PacketStategy.ParseInPacket(buf);
}
this.Start(false);
}, null);
}
}
public void SendAsync(Lingchen.Net.QQCore.Packets.OutPacket outPacket)
{
if (this.m_udpCLient.Connected)
{
byte[] buffer=outPacket.ToArray();
#if DEBUG
string l = Util.TileHexString(buffer);
#endif
this.m_udpCLient.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, p =>
{
int length= this.m_udpCLient.EndSend(p);
if (length > 0)
{

}

}, null);
}
}




}
}


    点击下载

本帖隐藏的内容

ConnectionManager.cs


这个关键的异步迈出了,接下来就是开始我们的正式旅程了。

下一步留在楼下,希望大家多多支持本站。好戏在下文哦!


PCQQ研究第二步:
   抓包工具,是指的能过滤成udp协议并且指定为tx服务器目标端口为8000的协议嗅探工具。比较出名的有wireshark,还有专门研究QQ类协议的 QQAnalyzer.这写软件都能很好的抓取并辅助分析出协议来。
    两款软件在网上都有破解版可以下载到,因此,我们这里就直接用上 QQAnalyzer 3.1破解版。(360报毒,最好在研究的时候从压缩文件解压缩出来,用完之后用360删除,毒不可不防,管他有没有毒)
    另外就是PCQQ的版本选择了。目前QQ的版本琳琅满目,但是最近据说QQ2011以及以下的版本都正式停掉了,因此,我们这能选网上分析资料相对较少的QQ2012或者2013了。我们就选QQ2013正式版SP1吧,反正2012的版本和2013的相差不太大。选最新的也没什么好顾虑的。
    最后,为了避免其他软件产生的协议影响,比如QQ管家或是QQ音乐,反正最好是运行的软件越少越好。

首先,运行QQAnalyzer软件之后,

点抓包设置,按如图进行选择


选择好之后便可开始抓包。


我们在开启抓包软件之后,要做的第一件事,就是打开QQ,开始一遍完整的QQ登录。
   等登陆上去之后立刻将QQanalyzer停止。
    以下图片是我抓到自己QQ之后截取的。

 

从上面有清晰看出我们要分析的地方。
源IP地址:就是本机在所在的局域网对应的对外ip
目标IP地址:腾讯的服务器ip。这个ip并不是一成不变的,每次登录都会为当前登录的QQ帐号寻找最适合的服务器。
源端口:是本机对外开放给服务器的端口,不一定是4000,但是一般QQ的客户端是从4000开始的,如果被其他软件占用了端口,会在4000基础上加1,依此类推。直到累加后的端口没有被其他软件占用。 我们在程序里的端口之所以绑不绑定这些端口都无关紧要就是这个原因。
目的端口:腾讯的服务器的开放端口,固定为8000.当然手机协议或其他协议则另当别论。一般我们在抓包软件里过滤协议就是以这个端口为特征而过滤的。

接下来,就是我们要研究的重点了。

本机与服务器通讯所产生的每一个包体都是以十六进制方式传输的,我们在抓包软件看到的仅仅是将十六进制数据的副本以文本形式显示出来而已,方便我们查看和分析。

 

NO.X 这里的X是指的过程中产生的包的序号标记,这是qqAnalyzer自己标记的,我们可以不用管他。
SEND 147字节,是指的向服务器发送了147个字节。说明这个包是我们发送给服务器的包。

再接下来,就是我们的重头戏协议规则分析了。先在这卖个关子,待留在下文继续披露。




抱歉!评论已关闭.