逆向思維--魔獸世界封包分析(1)

weixin_33860553發表於2011-02-05

本文作者:sodme
本文出處:http://blog.csdn.net/sodme
宣告:本文可以不經作者同意任意轉載,但任何對本文的引用都須註明作者、出處及此宣告資訊。謝謝!!

  特別宣告:
  本人非常欣賞暴雪及他們的遊戲,之所以寫這個文章,是想讓大家瞭解一些網路封包分析方面的常見方法以及學習暴雪遊戲在網路處理方面的經驗,偶認為作為一個網路程式設計者,熟練掌握封包分析的工具和方法應該是其基本功之一。本文所列的所有封包分析內容,全部是採用普通黑箱方式即可得來的,並未涉及對魔獸世界可執行程式的逆向工程。同時,除此文涉及的內容外,本人拒絕向任何人透露更詳細的關於魔獸世界封包方面的更多內容,有興趣者請自己進行相關的試驗,本人在此文中也將盡量避免公開敏感的封包內容及相關加解密演算法。謹以此文獻給忠愛的暴雪!

  一、登入模組流程及封包分析

  我們先看登入流程。從封包流程來看,魔獸的登入流程是這樣的:

  1.由Client向登入/賬號伺服器(Login Server)傳送使用者名稱及密碼等資訊。此資料包的最後部分是使用者名稱(明文表示,未加密),在使用者名稱的前一個位元組表示的是使用者名稱的長度。登入/賬號伺服器向Client返回登入成功及後續連線到遊戲伺服器伺服器所必備的資訊等。這中間的兩個來往資料包,我還沒有看出具體有什麼作用。在這個互動過程中,由登入/賬號伺服器向Client傳送所有的遊戲伺服器列表,伺服器列表資料包的內容包括:ip, port, 伺服器上所擁有的角色個數等資訊,因伺服器列表內容過多,被客戶端分為兩次接收完畢。

  2.Client收到Login Server的伺服器列表後,根據最近訪問的伺服器標識(這個資訊應該是包含在那個伺服器列表資料包中),連線到最近遊戲的那個遊戲伺服器(Game Server)。連線成功後,Game Server首先向Client傳送一個8位元組的資料包,據以往的常識判斷,這個資料包的內容很可能是以後客戶端與伺服器通訊的加密金鑰。

  3.Client向Game Server再次傳送自己的賬號資訊。Game Server與Client經過兩個資料包的互動後,向Client傳送角色資料包,此包中包括了玩家在該Game Server所建立的所有角色資訊,當然這個資訊只是部分的,並不是該角色的所有資訊。

  4.在此後的通訊過程中,Client每隔30秒向Game Server傳送一個保持連線的包,該包長度為10位元組,包的最後四位元組是一個遞增數字,前面6位元組暫時未看出規律。

  5.只要Client沒有點選某個角色進入最終的Game Server,則Client要始終與Login Server保持連線。當Client點選角色進入Game Server時,Client才與Login Server斷開連線。在以後的遊戲過程中,Client始終與且僅與該Game Server進行資料通訊。

  通過對登入流程中的資料包初步分析,可以得出以下幾個結論:
  1.Client向Login Server發的第一個資料包,使用者名稱部分是採用明文的,且該資料包的內容,每次登入都一樣,並沒有因時間的不同而發生改變。由此可以推算:針對於此資料包中的密碼加密演算法是固定不變的,換句話說,密碼的加密演算法是比較容易通過逆向工程被找到的。偶認為,針對於此處,伺服器也應該先向客戶端傳送一個加密金鑰,以後的通訊可以用該金鑰作為安全驗證的依據。但暴雪沒有這樣作,最大的可能是為了提高伺服器的效率,在登入伺服器上,如果每個客戶端一旦連線成功,登入伺服器都得向客戶端廣播一個資料包的話,可能這個量還是比較大的,這可能延長了玩家的登入等待時間,所以他們沒有在這塊作。

  2.Client在登入Login Server的地址,每次Login Server的登入地址都可能是不一樣的。偶沒有在客戶端目錄裡找到這些地址,只在客戶端目錄裡找到了四個大區的四個域名,我猜想,魔獸世界是用的DNS解析的簡單方法來實現Login Server的簡單動態均衡的。不知道這個猜想是否正確。

  3.“根據玩家最近在玩的哪個遊戲,由客戶端和伺服器自動為玩家選擇進入這個遊戲伺服器”,這一項設定充分體現了暴雪一貫的風格:為玩家著想,最大限度地提高遊戲的舒適度。再次對暴雪的態度予以肯定!

  4.一旦玩家進入了遊戲世界,客戶端與伺服器的通訊埠會一直保持不變。即:魔獸世界的遊戲世界伺服器群設計結構採用的是帶閘道器的伺服器叢集。

  5.偶覺得在整個的登入流程中,讓我產生最大疑問的就是Login Server與Client的連線保持邏輯。當Client與Game Server連線了之後,Client並未與Login Server斷開,是一直保持連線的。後來,經進一步的抓包分析,Client之所以要與Login Server保持這樣的連線,是為了當Client重新選擇伺服器時,不至於重新連線Login Server。當Client點選了"選擇伺服器"按紐後,Login Server會每隔5秒向Client發一個當前所有的伺服器列表資料包。要知道,這個伺服器列表資料包的內容可是非常大的,如果有玩家就開啟了這個視窗不關閉,Login Server向這種情況的所有玩家每5秒鐘就發一個伺服器列表資料包,這個廣播量可是很大的哦(2k左右,這可是一個使用者是2k哦)。偶認為這裡的邏輯設計是相當不合理的。Login Server如果為了給客戶端提供一個最新的全域性伺服器列表,可以保持連線,但也沒必要每隔5秒就向客戶端發一個伺服器列表,最多隻在客戶端在某個伺服器上建立了不同的角色後再更新這個列表也是可以的,但只用更新這個列表中的變化內容即可,不用發全部的完整包,這樣,在通訊量上就小了很多。據說,魔獸剛開始的時候,產生DOWN機的原因就是登入模組沒有處理好,偶不知道現在的這個情況是不是已經經過改良的了。但偶還是認為每隔5秒就向客戶端傳送一個2K的包,這一點是不可以被接受的。

  以上只是針對於魔獸世界登入流程的簡單分析,沒有多少技術含量,拿出來跟大家相互討論討論,看看有沒有可以借鑑的地方,後面還會有其它部分的封包分析。歡迎繼續關注偶的Blog: http://blog.csdn.net/sodme

  偶在文章前面部分說過,作為一個網路程式設計人員,熟練使用截包軟體和掌握基本的封包分析方法是其基本能力之一,發此文的目的一個原因也是希望向正在作網路程式設計的兄弟介紹一下相關工具的使用和常見的分析方法。下面補充一下關於封包分析的基本方法和相關工具:

  1.你需要一個截包工具,偶推薦:commview,小巧但功能強大,支援自定義的封包分析外掛以DLL形式裝載,也就是說只要你願意,你可以寫個DLL對某類特殊形式的包進行顯示、記錄、解密等特別處理。

  2.如何檢視真正的封包資料。在commview裡,會詳細列出自網路卡級別以上的各層封包資料,包括Ethernet層,IP層和TCP層。而我們作封包分析時,只需要關注TCP層。但TCP層裡也有很多內容,對於我們的分析需求來說,我們需要關注的是其Data欄位(在協議目錄裡可以看到"data length標識,點選即可檢視data段")的內容。

  3.TCP的幾個狀態對於我們分析所起的作用。在TCP層,有個FLAGS欄位,這個欄位有以下幾個標識:SYN, FIN, ACK, PSH, RST, URG.其中,對於我們日常的分析有用的就是前面的五個欄位。它們的含義是:SYN表示建立連線,FIN表示關閉連線,ACK表示響應,PSH表示有DATA資料傳輸,RST表示連線重置。其中,ACK是可能與SYN,FIN等同時使用的,比如SYN和ACK可能同時為1,它表示的就是建立連線之後的響應,如果只是單個的一個SYN,它表示的只是建立連線。TCP的幾次握手就是通過這樣的ACK表現出來的。但SYN與FIN是不會同時為1的,因為前者表示的是建立連線,而後者表示的是斷開連線。RST一般是在FIN之後才會出現為1的情況,表示的是連線重置。一般地,當出現FIN包或RST包時,我們便認為客戶端與伺服器端斷開了連線;而當出現SYN和SYN+ACK包時,我們認為客戶端與伺服器建立了一個連線。PSH為1的情況,一般只出現在DATA內容不為0的包中,也就是說PSH為1表示的是有真正的TCP資料包內容被傳遞。TCP的連線建立和連線關閉,都是通過請求-響應的模式完成的。

  <未完待續>

 

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/sodme/archive/2005/06/18/397371.aspx

相關文章