QQ協議分析之TCPF包結構

包結構類型:

TCPF包我們把它分爲5類:

登錄請求包(LIP,LogIn Packet),它是由客戶端向服務器發出登錄請求的數據包。

登錄應答包(LRP,Login Reply Packet),它是由服務器響應客戶端登錄請求的數據包。

註銷請求包(LOP,LogOut Packet),它是由客戶端向服務器發出註銷登錄請求的數據包,服務器對這個包不作應答。

客戶端其它包(CSP,Client Sent Packet),它是由客戶端向服務器發送的其它包。

服務器其它包(SSP,Server Sent Packet),它是由服務器向客戶端發送的其它包。


包頭:

所有TCPF包的前7個字節是包頭,包頭可以識別TCPF包的內容。包頭的格式爲:

第0字節:TCPF包標識:0x02。

第1-2字節:發送者標識。如果是0x01 0x00,表明是由服務器發送。客戶端的標識與所使用的使用的QQ版本有關,目前最新版本QQ2003(0808)的標識爲0x0A 0x1D。具體的協議的格式與這個字段所標識的客戶端版本有關。目前我們以這個最新的0A1D版本來討論。

第3-4字節:命令編號。具體的命令編號含義在《QQ協議概述》(Protocol Overview.rtf)中有描述。如果這個字段是0x00 0x01,那麼這是一個註銷請求包。如果這個字段是0x00 0x22,而發送者標識是0x01 0x00,那麼這是一個登錄應答包。如果這個字段是0x00 0x22,而發送者標識是其它(例如0x0A 0x1D),那麼這是一個登錄請求包。其它的命令代碼表明是其它包,我們通過發送者標識來區分它是CSP還是SSP。

第5-6字節:命令序列號。客戶端和服務器都有各自的當前發送序列號。每初始發出一個指令的時候,使用當前的序列號,然後把當前序列號加一,如果超過0xFFFF,就繞回。如果是響應對方發出的命令,則使用這個命令的序列號。例如,客戶端當前的序列號爲0x1110,它向服務發送一個0x0016命令,它使用0x1110這個序列號,服務器收到以後,返回一個序列號爲0x1110的0x0016命令響應。下一次,客戶端又發送一個0x0026命令,這一次它使用加一了的序列號0x1111,服務器也響應0x1111序列號的一個0x0026命令響應。如果這是服務器要向客戶端發送0x0017命令,它使用它自己的當前序列號,比如說0x2220,客戶端收到以後,也響應一個序列號爲0x2220的0x0017命令應答。我們可以通過序列號來判斷髮出的指令是否已經得到了應答,如果沒有,可以重發。服務器對收到的命令的序列號順序沒有要求。服務器也不會一定按照發出的順序給予應答。


包尾:

所有的TCPF包都以0x03作爲包尾。在包頭和包尾中間的包數據則不同類型的包有所不同。



LIP包:

登錄請求包的包數據格式爲:

第7-10字節(4 bytes):發出登錄請求的QQ號碼。這是一個Big Endian(高位在前)的unsigned long型數值。例如:0x01 0x82 0x5D 0x90就是0x01825D90,轉換爲十進制是25320848,表明發出請求的QQ號是25320848。

第11-26字節(16 bytes):隨機密鑰。這個密鑰由於加密後面的數據。QQ使用TEA算法來加密數據。它使用的是128bit(16 bytes)的密鑰。在0A1D版本中,這個密鑰已經固定爲16個01。

第27-106字節(80 bytes):加密後的登錄包數據。


LRP包:

從第7字節開始到包尾前:加密的登錄應答包數據。解密的密鑰隨客戶端版本的不同,有不同的可能。在舊有版本中,使用登錄包的隨機密鑰,在後期的版本,使用用戶QQ密碼的MD5 Digest。在0A1D中,使用QQ密碼的MD5 Digest的MD5 Digest(這體現了騰訊有多麼的愚昧和無恥,爲了改變而改變)。LRP包內數據很重要的是16個字節的Session Key,它用來作爲以後通訊的加密密鑰。


LOP包:

它的序列號總是0xFFFF。不過,在新的版本中,好象已經沒有了這個要求。

第7-10字節(4 bytes):發送註銷登錄請求的QQ號碼。

第11字節到包尾前:加密的註銷登錄包數據。使用Session Key作爲密鑰。


CSP包:

第7-10字節(4 bytes):發送請求的QQ號碼。

第11字節到包尾前:加密的包數據。使用Session Key作爲密鑰。


SSP包:

從第7字節開始到包尾前:加密的服務器發送包數據,使用Session Key作爲密鑰。


QQ加密算法概述:

QQ使用的加密算法來源於一種稱爲TEA(Tiny Encryption Algorithm)加密算法。它是在1994年由英國劍橋大學的David Wheeler和Roger Needham所發明的一種加密方法。大概來說,它是使用128bit密鑰加密64bit數據產生64bit輸出的一種算法。這種算法的可靠性是通過加密輪數而不是算法的複雜度來保證的。具體的算法可以參考:[url]http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html[/url]。實現可以參考:[url]http://abcn.net/crypto.htm[/url]

QQ使用16輪的加密(這是最低限,推薦應該是32輪)。

QQ在使用這個算法的時候,由於需要加密不定長的數據,所以使用了一些常規的填充辦法和交織算法(也就是說,把前一組的加密結果和後一組的進行運算,產生新的結果)。

具體的填充算法是:原始字符串加上8個字節再加上填充字符數應該是8的倍數(至少填充2個字節)。填充後的字符串是這樣組織的。第一個字節,爲填充字符數減2 OR 上0xA8。後面是填充字節。然後是待加密的數據,最後是7個0。填充的字節一般是0xAD,但再0A1dD版本中,會使用隨機的填充字符串。一般,我們會用解密後最後是否7個零來判斷是否正確的解密。

交織算法:第一個64bits塊,按照一般的TEA加密。下一個64bit塊與上一組的加密結果XOR生成待加密數據,加密後與上一組的待加密數據XOR生成加密結果。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章