最近在弄wireshark,網上資料很少,不過找到了一篇不錯的,翻譯過來,方便大家查看。不過設置編譯環境那章寫的不怎么好,可以參考下官網或其他人寫的經驗貼。
原文地址:http://www.codePRoject.com/Articles/19426/Creating-Your-Own-Custom-Wireshark-Dissector
相關例子源代碼地址:http://www.codeproject.com/KB/ip/custom_dissector/packet-amin_src.zip
WireShark是一款強大的網絡協議分析開源軟件。你是否曾經為不知道怎樣開發自定義協議解析器而煩惱?進一步說,是否曾試圖研究過WireShark的API,但發現這過程太難了。這篇文章會告訴你怎樣去開發屬于你自己的協議解析器。文章把Amin Gholiha 的"A Simple IOCP Server/Client class"作為例子來說明怎樣開發解析器,例子是用來解析AMIN協議的。
官網的Wireshark developer's guide 講述了如何建立Win32開發環境,但我覺得價值不大。在本章中我會講述得更詳細些(譯者注:我倒覺得官網的還可以,我的就是按照官網上的配置的,不過有一點就是Python的版本最好用配置文件里提到的版本,不然可能會出錯)。
如果你沒有VS2005/VS2003 等C語言編譯器,你可以從網上下個(現在官網的源代碼已經支持VS2010了)。
你必須下載并安裝Server 2003 R2的SDK(譯者注:一般安了VS的話就會自動安裝相應本機操作系統對應的SDK)。
在這里不會詳細描述Cygwin是什么,簡單的來說,Cygwin可以使得WireShark可以在Windows平臺和Linux平臺下編譯(譯者注:貌似Linux平臺下不用下載Cygwin吧,而且Linux下編譯非常簡單),Cygwin可以從Cygwin installer上下載并啟動。
在"Select Packages" 頁,需要選擇一些額外的包,這些包默認是不會安裝的。展開Category/Package,選中想要添加的包,點擊"New" 列,使得"Skip"變成版本號數字即可。下面是列出來需要添加的包:
Archive/unzipDevel/bisonDevel/flexInterpreters/perlUtils/patchWeb/wgetAfter clicking the Next button several times, the setup will then download and install the selected packages (this may take a while).
點擊幾次Next后,安裝程序就會下載并安裝所選的包(譯者注:這里說的比較簡單,有幾個界面作者沒有說,一個是讓你選擇操作的種類,要么在線安裝,要么只下載安裝包,要么從本地安裝包安裝Cygwin;還一個界面是讓你從哪個網站下載。都是些簡單的英語,一看就懂)。
下載Python 2.4 installer并安裝Python到默認路徑。注意:使用Python 2.5 會無法正常編譯,故不要使用2.5版本(譯者注:盡量使用配置文件里提到的版本,不然真的會編譯不成功,我就遇到過,另外建議不要修改默認安裝路徑)。
對于選擇Subversion客戶端軟件,我的專業意見是下載并使用TortoiseSVN[^]。開啟右鍵菜單功能可能需要重啟計算機才能生效。這個功能很不錯,當你在瀏覽試圖中右鍵文件夾時會出現此菜單,通過他你能獲取源代碼樹。
你可能會有點奇怪,為什么為了編寫一個解析器卻下載整個源代碼。源代碼的"plugins"文件夾里包含了例子,以后你編譯的解析器也會放在這個文件夾里。
在Windows瀏覽器的C:/ drive 文件夾上右鍵。在彈出來的上下文菜單中, 選中"SVN checkout.." :在 URL of the repository中填入源代碼地址http://anonsvn.wireshark.org/wireshark/trunk/。在 checkout directory中寫上想到導出的文件夾c:/wireshark。用記事本或者其他你喜歡的文本編輯器打開C:/Wireshark/config.nmake。下面列出的幾個地方都必須修改:
VERSION_EXTRA: 這里可以自定義個人版本信息。例如:-myprotocol123. Mine reads: SVN-AMINPROTOCOL. 你可以在這里寫上任何你想寫的東西。PROGRAM_FILES: WireShark程序將來想要安裝的位置。通常保持默認值即可。MSCV_VARIANT: 這個地方很關鍵。如果你的VS版本被注釋掉了,那么要先把其他版本VS注釋掉,只保留你的VS版本。例如(譯者注:作者用的VS是VS2005,所以下面列出的所有版本中,只有VS2005的宏沒有被注釋掉):
啟動 cmd.exe (開始 > 運行 > "cmd")
Call "C:/Program Files/Microsoft Platform SDK for Windows Server 2003 R2/SetEnv.Cmd"Call "C:/Program Files/Microsoft Visual Studio 8/VC/bin/vcvars32.bat"cd c:/wireshark(譯者注:上面沒寫清楚,應該是先啟動CMD,然后運行"C:/Program Files/Microsoft Visual Studio 8/VC/bin/vcvars32.bat",再轉到c:/wireshark。第2條沒必要執行,至少我的沒有執行卻成功了。另外,所有的命令都必須在同一個CMD窗口執行,也就是說,后面提到了nmake命令也必須在此CMD中執行,不然提示無法識別nmake命令)。
VS的路徑按你自己本機上的路徑做相應修改。 在例子的ZIP包中, 你會發現step1.bat,step2.bat和step3.bat。 我打包這些批處理到ZIP包中是為了簡化步驟。 我知道有一些更好的方式去創建這些批處理, 所以按你自己想法來執行這些步驟。
在C:/WireShark 目錄中執行(需要在上面步驟8提到的同一個CMD中執行):
C:/wireshark> Nmake –f Makefile.nmake verify_tools 可能會得到這樣的輸出:

如果提示某些東西丟失,你可能需要重新執行Cygwin安裝程序。
步驟 10. 安裝庫文件
如果關閉了CMD,你必須重新執行步驟8。 你也可以執行step1, step2, step3 批處理以簡化執行過程。在C:/Wireshark目錄下執行(第一步可能會花點時間):
Collapse |Copy Codenmake –f Makefile.nmake setup nmake –f Makefile.nmake distclean步驟 11. 編譯Wireshark
如果關閉了CMD,你必須重新執行步驟8。 你也可以執行step1, step2, step3 批處理以簡化執行過程。
(這個命令會花費一些時間)
Collapse |Copy Code
nmake –f Makefile.nmake all 步驟 12. (可選) 創建Wireshark安裝程序
我有個想法,想把我編譯的WireShark版本分發給我的朋友。 通過執行下面的步驟你可以很容易的創建一個安裝程序:
下載并安裝 NSIS [^].下載 vcredist_x86.exe [^] 并把他放在c:/wireshark-win32/libs 目錄。該目錄下可能已經存在此文件,所以最好先檢查下。使用CMD,按步驟8或執行我提供的Step1/2/3 批處理,轉到C:/Wireshark目錄下,執行:
Collapse |Copy Codenmake –f Makefile.nmake packaging你會發現安裝文件c:/wireshark/packaging/nsis/wireshark-setup.exe。你可以嘗試運行下。3.0 執行編譯好的Wireshark
想要運行WireShark的話直接執行C:/wireshark/wireshark-gtk2/wireshark.exe并且確定程序已經啟動。我發現我必須先下載并安裝一次標準的Wireshark后才能運行我自己編譯的WireShark。這可能是因為我之前沒有安裝WinPcap的緣故。你可以從官網下載并安裝標準WireShark。
注意:如果你是使用的是VS2005,那么你也必須使用編譯WireShark時所用的VS的版本去測試解析器。由于某些原因,用VS2005編譯的協議解析插件無法在主流的WireShark版本上使用。如果你是使用的其他版本,則不需要使用編譯WireShark時所用的VS版本(譯者注:大概意思應該是VS2005有BUG,如果用VS2005開發協議解析插件,那么開發出來的插件只能在用VS2005編譯的WireShark上使用,可能我理解的有偏差,大家可以去看下英文原文)。
4.0 理解AMIN協議
Amin是一個足夠說明IOCP協議的C/S結構的協議。他的協議結構非常簡答,主要是基于TCP協議傳輸數據。這篇文章只是個說明怎樣編譯協議解析插件的開始,所以在這里我們只解析C/S之間傳輸的文本消息。傳輸文件則有點點復雜,這里我們將忽略此種消息類型。

4.1 數據包長度前綴
所有的Amin數據包都用前面4個字節來表示后面數據長度。這個值是以網絡字節順序,或者說MSB格式在網絡上傳輸。網絡字節順序的意思是最重要的信息放在開頭。例如,假定數據包長度是十進制12。用十六進制則為0x0000000c(如果你以long類型存儲的話)。如果你從網絡上接受到這個值,那么此值將會以0c 00 00 00的形式出現;這就是網絡字節順序。你可能會疑惑為什么字節順序是反的。如果你用字節數組來表示long類型,每個字節按順序存儲值。在這種情況下,byte[0]的值是0x0c,所以0x0c寫在了第一位。理解網絡字節順序這個概念很重要。
當我們使用WireShark來解析數據包時,理解2個或4個字節長度的整數在網絡字節順序或是說LSB格式下是怎樣表示很重要。而在其他協議中,值的表示方式一般為主機字節順序,即LSB。
注意:這個值表示的是接下來的數據長度,意思就是這開頭的4個字節并沒有包括在這個長度內。例如,如果你發送一個含有12個文本字符的數據包,長度將是12+1=13(1表示數據包包含的數據類型),綜合到一起是12+1+4=17。
4.2 數據類型
Amin數據包中緊跟在長度后面的一個字節暗示了包含的數據類型。我們只處理類型為0x00的數據包,這代表了數據類型是文本。注意:一個字節的話就不存在字節順序了。
4.3 Null結尾的字符串
在這里我們可以通過Amin的MFC界面構造一個以NULL結尾的字符串。默認的字符串是'ABCDEFGHIJKLMNOPQRST123456789'。
5.0 使用不包含自定義插件的Wireshark觀察Amin協議數據包
你可以從這里下載由Amin編寫的IOCP協議的C/S程序。注意:本文章不會去討論WireShark的基本使用方法。假定你曾經使用過并且知道怎樣去擺弄WireShark。下圖是沒有AMIN協議解析器時的WireShark界面。

注意到WireShark只是簡單的把數據包解釋為"Data"。在數據展示區里,我們可以知道我們的AMIN協議數據包長度為"1f 00 00 00 00"。接下來的是數據類型,在數據類型后面的是用ASCII碼"ABC..."。
6.0 編寫自己的解析器
在WireShark源代碼里有個文件夾叫Plugins,里面包含了很多標準協議解析器。然而,從那些解析器找出一個簡單一點做參考是有點難度的。[So, in combination with the H223 dissector, random examples from the internet, and the developer guide,]我在例子源代碼里準備了一個簡單的例子,這個例子可以在Amin文件夾下面找到。
6.1 make文件
為了去解析你的協議,你必須創建一些文件以便去編譯你的解析器。最簡單的方法就是從例子源代碼里的AMIN文件夾下復制下面的文件。
Makefile.am - 這個是UNIX/Linux平臺下的makefile模板Makefile.common - 這個文件包含了內置插件所依賴的文件Makefile.nmake - 這個文件是Windows平臺下WireShark內置插件的makefilemoduleinfo.h - 內置插件的版本信息moduleinfo.nmake - Windows平臺下DLL的版本信息packet-amin.c - 你自己寫的解析器的源代碼文件plugin.rc.in - Windows平臺下的DLL資源模板 一旦你復制了相應的文件到C:/Wireshark/plugins/yourprotocolname,你就可以按照下面的步驟編輯這些文件。
把文件中的所有AMIN改成你的協議名稱,但行42、43、114除外。在Makefile.common中,把所有AMIN替換成你的協議名稱,行31除外。在moduleinfo.h中,把所有AMIN替換成你的協議名稱,行8除外。另外你可以在行16把版本改成你自己想要的版本標識。這樣的話就方便你管理你的解析器計劃。在 moduleinfo.nmake中,把所有AMIN替換成你的協議名稱,行6除外。行9、10、11和12必須與moduleinfo.h的行16標記的版本標志對應。在packet-amin.c中,第一件事就是把文件名改為packet-你協議名稱.c. 所有的解析器都遵從本規定: packet-協議名稱.c。在源文件中,你可以簡單的吧"amin"替換成""。記住,確定所有的"AMIN"和"amin"都替換了。在某些情況下,你可能無法注冊過濾器名稱,因而WireShark會運行失敗。這一點一定要注意。現在該做剩下的事情了,現在將開始寫代碼了。7.0 自定義解析器代碼
你可以用你喜歡的文本編輯器打開packet-yourprotocol.c。讓我們一行一行的講解:

所有的解碼器都使用標準的頭文件。你當然也需要把theconfig.h,glib.h和packet.h放到開頭。
我的習慣是盡可能的不使用數字常量(譯者注:就是把數字用變量代替)。
這個變量對WireShark來說很重要。WireShark用他來標識我們的協議。
WireShark用這個解碼器句柄來引用解碼器。
這個解碼函數的前置聲明。我們將在后面實現這個函數。
WireShark將用這個端口號去判斷數據包是否屬于AMIN協議。

這里是數據包類型相關的配置信息。你可以按你自己協議的需要定義。[It adds a level of detail that makes the dissector look well thought out]

這里我們將我們協議的子組件與ID綁定。

這個函數的作用是注冊我們的協議,注意我們是怎樣傳遞端口號和解碼句柄的。

上面的數組定義了我們想要顯示的信息。這些聲明只是一些簡單的定義,在我們以后解碼數據包的時候WireShark會使用這些信息去區分數據類型。

上面的數組簡單的把ID綁定到了我們之前的定義上。記著要與上面定義的hf_
andett_
data 一一對應。

上面是注冊我們協議的過程。在我所看過的大多數例子中,他們都會[根據第一個函數返回結果]檢查proto_amin
是否已經初始化好。然而,WireShark官方開發者中的名叫"Jaap"的人發郵件給我說沒必要去執行這個過程。后面注冊協議和解碼句柄的過程會保證解碼器注冊成功。

解碼函數用來解碼實際的數據,以及顯示這些數據包的詳細信息。
首先,需要初始化一些樹指針和信息單元:

接下來看下INFO列是否顯示我們協議的標簽"AMIN"。如果沒有,則顯示之。

如果用戶想把此數據包的信息添加到主解碼樹中,則處理這個請求。

這個調用是將我們的解碼出來的解碼樹添加到主解碼樹種。

在這里,把我們的解碼樹添加上去,以便我們有一個可以折疊的樹頭。接下來構造子樹,我們取得了數據段的字節長度。按網絡字節順序編碼。如果其他人有更好的tvb_get
函數去讀取長度值,歡迎提出來。

7.1 編譯packet-yourprotocol.c
如果你的CMD窗口沒有關掉,你可以直接使用那個窗口。如果關了,執行step1/2/3.bat ,然后轉到c:/wireshark/plugins/yourprotocol目錄。如果你想編譯我的源代碼,則轉到c:/wireshark/plugins/amin下。在"請按任意鍵繼續"提示下,執行下面的命令:

如果編譯成功,你應當可以看到yourprotocol.dll。復制此文件到C:/WireShark/wireshark-gtk2/plugins/0.99.7-YOUR-BUILD。這個文件夾是用來存放其他解碼DLL分支的地方。如果你之前安裝了你編譯的WireShark,則還需要放到c:/program files/wireshark/plugins/0.99.7-YOUR-BUILD 里,前面的路徑按你安裝的具體位置更改下。前提是你復制了你編譯出來的DLL到合適的位置,你將能夠啟動WireShark并解碼AMIN的數據包了。一個比較好的測試是否已經部署好的方法是在"filter"中鍵入你的協議名稱看數據的底色是綠色還是紅色,如果像下面顯示的那樣,則表示解碼器加載對了。

這是WireShark上AMIN協議的截圖。
8.0 提示
8.1 CodeBase
我在CodeBase[^]上發現了大量的例子。如果不參考這個網站,寫解碼器將是一個艱巨的任務。你們應當花些時間閱讀下官方的WireShark API 文檔。
同事告訴我CodeBase網站是一個付費網站。我有個方法能使用CodeBase而無需認證用戶。使用這個鏈接就可以(使用搜索框以便找到非文檔方法)。
8.2 Wireshark過濾
After you've defined your data type map, you can use the '.' Operator to limit the packets being displayed. For example,amin.type==0 will only show packets where the type equals zero.
當你定義了你的數據類型映射后,你可以使用'.'操作來不顯示你的數據包。例如,amin.type==0 只顯示那些類型為0的數據包。
8.3 其他列子
在plugins文件夾中能找到更復雜的例子。我的建議是去看看H223解碼器。這個解碼器覆蓋了例如TCP方面的知識,以及怎樣將數據包組合到一起解碼(例如一個分割成多個數據包的會話)。
8.4 捕捉循環數據包
如果你想用WireShark抓取本地數據包,例如127.0.0.1 。你必須執行一些額外的步驟才行。這個鏈接能幫助你解決這個問題。那個網站上的建議步驟如下:
安裝一個循環適配器。 Windows 2003[^], Windows XP[^], Windows 2000[^]轉到MS的循環適配器屬性頁。設置:IP 10.0.0.10掩碼 255.255.255.0適配器/額外設置/網絡地址: 55-55-55-55-55-55在命令行中 (cmd.exe): 
接著:

你可以通過下面的命令測試下:

9.0 總結
如果協議本身并不復雜,那么在WireShark里編寫一個解碼器是一個很容易的事。此外,[the guys at Wireshark greatly appreciate those who take the time to legally reverse engineer protocols for inclusion within the Wireshark distribution.]
10.0 參考文獻
"A Simple IOCP Server/Client Class", Amin Gholiha, The Code Project, 09/05/2005Wireshark Developer's Guide, 22223 For Wireshark 0.99.6H223 Example MX Telecom Ltd.Wireshark – Network Traffic Analyzer, Gerald Combs11.0 歷史
July 22, 2007 - Fixed a typo in packet-amin.c: tvb_get_uint8 -> tvb_get_guint8. Thanks Keith!July 9, 2007 - Added a CodeBase link that allows you to search without being a member of CodeBase. Not sure if this is legal, send me an email if it isn't.July 3, 2007 - Removed extra "nmake Makefile.nmake setup" in tools installation section.July 2, 2007 - Updated source code and article to reflect suggestions made by Jaap. Changes include:Changed static int intialized=FALSE
to static gboolean
.Removed #include <gmodule.h>
, not needed.Commented out if(proto_amin == -1){}
.Moved the if(check_col(pinfo->cinfo, COLINFO)){
routine out of if(tree)
.Fixed comments on network versus host byte order.Added section 8.4 on capturing loopback packets.July 1, 2007 - Spell checking and other grammatical corrections. Fixed an issue withpackettypename[]
where{0,NULL}
was required to avoid a seg fault. Thank you Ronnie.June 29, 2007 – First draft.許可證
這篇文章,包括文章內容和源代碼,都遵循許可證The Code Project Open License (CPOL)
>>看來一套多人開發的軟件,其架構的設計是唯一性的,通過一個接口連接各種功能的插件,以實現為先前設計好的架構增加新功能,可復用性
新聞熱點
疑難解答