1. Wireshark對Lua的支持
本節相關內容可參考Wireshark開發指南第10章”Lua Support in Wireshark”。
Wireshark集成了Lua解釋器,以支持Lua腳本(自己編譯的話根據編譯配置決定是否支持Lua)。
啟動wireshark,依次點擊“Help”,”About Wireshark“菜單,在打開的對話框中的”Wireshark”標簽頁上觀察版本信息,如果如下圖一樣顯示With Lua,說明此版本支持Lua插件。
然后打開wireshark主目錄下的init.lua文件,確保disable_lua的值為false,即開啟了lua:
在Wireshark中,可以使用Lua編寫以下幾種插件:
- Dissectors
協議解析器,用於解析報文 - Post-dissectors
后置解析器,在其他解析器之后被調用 - Listeners
監聽器,用來收集解析后的信息
還需要注意:
- wireshark啟動時,會調用下圖目錄中的init.lua,順序是先調用global目錄的,再調用personal目錄的;
- 通過命令行參數:
-X lua_script:my.lua
傳入的my.lua將會在Init.lua之后被調用 - 所有的Lua腳本會在解析器注冊過程的最后被調用,而這一過程是在wireshark啟動時就發生的,早於報文被讀取的時刻。
2. Lua插件API簡介
本節相關內容可參考Wireshark開發指南第11節”Wireshark’s Lua API Reference”。
Wireshark提供了豐富的Lua API供開發者使用,這里只介紹下文需要用到的一些。
2.1 Proto
表示一個新的Protocol,在Wireshark中Protocol對象有很多用處,解析器是其中主要的一個。主要接口有:
接口 | 說明 |
proto:__call (name,desc) | 創建Proto對象。name和desc分別是對象的名稱和描述,前者可用於過濾器等 |
proto.name | get名稱 |
proto.fields | get/set字段 |
proto.prefs | get配置項 |
proto.init | 初始化,無參數 |
proto.dissector | 解析函數,3個參數tvb,pinfo,tree,分別是報文內容,報文信息和解析樹結構 |
proto:register_heuristic (listname, func) | 為Proto注冊一個啟發式解析器,被調用時,參數func將被傳入與dissector方法相同的3個參數 |
2.2 ProtoField
表示協議字段,一般用於解析字段后往解析樹上添加節點。根據字段類型不同,其接口可以分為兩大類。
整型:
• ProtoField.{type} (abbr, [name], [desc],[base], [valuestring], [mask])
type包括:uint8, uint16, uint24, uint32, uint64, framenum
其他類型
• ProtoField.{type} (abbr, [name], [desc])
type包括:float, double, string, stringz, bytes, bool, ipv4, ipv6, ether,oid, guid
這些接口都會返回一個新的字段對象。方括號內是可選字段,花括號內是可替換的類型字段。
2.3 Tvb
Tvb(Testy Virtual Buffer)表示報文緩存,也就是實際的報文數據,可以通過下面介紹的TvbRange從報文數據中解出信息。主要接口有:
接口 | 說明 |
tvb:__tostring() | 將報文數據轉化為字符串,可用於調試 |
tvb:reported_len() | get tvb的(not captured)長度 |
tvb:len() | get tvb的(captured)長度 |
tvb:reported_length_remaining() | 獲取當前tvb的剩余長度,如果偏移值大於報文長度,則返回-1 |
tvb:offset() | 返回原始偏移 |
2.4 TvbRange
表示Tvb的可用范圍,常用來從Tvb中解出信息。主要接口有
接口 | 說明 |
tvb:range([offset], [length]) | 從tvb創建TvbRange,可選參數分別是偏移和長度,默認值分別是0和總長度 |
tvbrange:{type}() | 將tvbrange所表示范圍內的數據轉換成type類型的值,type包括但不限於:uint,uint64,int,int64,float,ipv4,ether,nstime,string,ustring,bytes,bitfield等,其中某些類型的方法可以帶一些參數 |
2.5 Pinfo
報文信息(packet information)。主要接口有:
接口 | 說明 |
pinfo.len pinfo.caplen | get報文長度 |
pinfo.abs_ts | get報文捕獲時間 |
pinfo.number | get報文編號 |
pinfo.src pinfo.dst | get/set報文的源地址、目的地址 |
pinfo.columns pinfo.cols | get報文列表列(界面) |
取得報文列表列后,就可以設置該列的文本,比如
pinfo.cols.info = “hello world”
將Info列的文本設為hello world。
2.6 TreeItem
表示報文解析樹中的一個樹節點。主要接口有:
接口 | 說明 |
treeitem:add([protofield], [tvbrange], [value], [label]) | 向當前樹節點添加一個子節點 |
treeitem:set_text(text) | 設置當前樹節點的文本 |
treeitem:prepend_text(text) | 在當前樹節點文本的前面加上text |
treeitem:append_text(text) | 在當前樹節點文本的后面加上text |
2.7 DissectorTable
表示一個具體協議的解析表,比如,協議TCP的解析表”tcp.port”包括http,smtp,ftp等。可以依次點擊wireshark菜單“Internals”、“Dissector tables”,來查看當前的所有解析表。tcp.port解析表在“Integer tables”選項卡中,顧名思義,它是通過類型為整型的tcp端口號來識別下游協議的:
DissectorTable的主要接口有:
接口 | 說明 |
DissectorTable.get(name) | get名為name的解析表的引用 |
dissectortable:add(pattern, dissector) | 將Proto或Dissector對象添加到解析表,即注冊。pattern可以是整型值,整型值范圍或字符串,這取決於當前解析表的類型 |
dissectortable:remove(pattern, dissector) | 將滿足pattern的一個或一組Proto、Dissector對象從解析表中刪除 |
3. 參考