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

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

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

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

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

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

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

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

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

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

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

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

接下來看下INFO列是否顯示我們協(xié)議的標(biāo)簽"AMIN"。如果沒有,則顯示之。

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

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

在這里,把我們的解碼樹添加上去,以便我們有一個可以折疊的樹頭。接下來構(gòu)造子樹,我們?nèi)〉昧藬?shù)據(jù)段的字節(jié)長度。按網(wǎng)絡(luò)字節(jié)順序編碼。如果其他人有更好的tvb_get
函數(shù)去讀取長度值,歡迎提出來。

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

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

這是WireShark上AMIN協(xié)議的截圖。
8.0 提示
8.1 CodeBase
我在CodeBase[^]上發(fā)現(xiàn)了大量的例子。如果不參考這個網(wǎng)站,寫解碼器將是一個艱巨的任務(wù)。你們應(yīng)當(dāng)花些時間閱讀下官方的WireShark API 文檔。
同事告訴我CodeBase網(wǎng)站是一個付費(fèi)網(wǎng)站。我有個方法能使用CodeBase而無需認(rèn)證用戶。使用這個鏈接就可以(使用搜索框以便找到非文檔方法)。
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.
當(dāng)你定義了你的數(shù)據(jù)類型映射后,你可以使用'.'操作來不顯示你的數(shù)據(jù)包。例如,amin.type==0 只顯示那些類型為0的數(shù)據(jù)包。
8.3 其他列子
在plugins文件夾中能找到更復(fù)雜的例子。我的建議是去看看H223解碼器。這個解碼器覆蓋了例如TCP方面的知識,以及怎樣將數(shù)據(jù)包組合到一起解碼(例如一個分割成多個數(shù)據(jù)包的會話)。
8.4 捕捉循環(huán)數(shù)據(jù)包
如果你想用WireShark抓取本地數(shù)據(jù)包,例如127.0.0.1 。你必須執(zhí)行一些額外的步驟才行。這個鏈接能幫助你解決這個問題。那個網(wǎng)站上的建議步驟如下:
安裝一個循環(huán)適配器。 Windows 2003[^], Windows XP[^], Windows 2000[^]轉(zhuǎn)到MS的循環(huán)適配器屬性頁。設(shè)置:IP 10.0.0.10掩碼 255.255.255.0適配器/額外設(shè)置/網(wǎng)絡(luò)地址: 55-55-55-55-55-55在命令行中 (cmd.exe): 
接著:

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

9.0 總結(jié)
如果協(xié)議本身并不復(fù)雜,那么在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 參考文獻(xiàn)
"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.許可證
這篇文章,包括文章內(nèi)容和源代碼,都遵循許可證The Code Project Open License (CPOL)
>>看來一套多人開發(fā)的軟件,其架構(gòu)的設(shè)計是唯一性的,通過一個接口連接各種功能的插件,以實(shí)現(xiàn)為先前設(shè)計好的架構(gòu)增加新功能,可復(fù)用性
新聞熱點(diǎn)
疑難解答