做網(wǎng)站廣告收入會員卡營銷策劃方案
文章目錄
- Wireshark Protobuf Lua-dissector
- Step 1: 獲取 Wireshark
- Step 2: 配置ProtoBuf相關(guān)設(shè)置
- 添加ProtoBuf查找路徑
- Step 3 運行和調(diào)試Lua代碼
- 1. 添加Lua腳本
- 2. 運行和調(diào)試
- Step 4: 寫Lua Dissector代碼 :)
- Step 5(Optional): Decode As
- Github工程地址
Wireshark Protobuf Lua-dissector
最近工作中遇到需要Wireshark抓包排查項目網(wǎng)絡(luò)庫的問題,并且需要用ProtoBuf協(xié)議解析抓到的二進制數(shù)據(jù)。網(wǎng)絡(luò)上查了一圈都沒有找到簡單明了的教程能讓我快速上手的,就搞了這個教程,幫自己紀錄的同時也希望能幫到遇到同樣問題的你。
這個教程專注于幫你寫Lua插件幫你解析Wireshark中的ProtoBuf包,請確保已經(jīng)掌握基礎(chǔ)的Wireshark使用方法。如果還沒掌握,網(wǎng)上有很多教學,很快就可以上手了!
Step 1: 獲取 Wireshark
直接從 官網(wǎng) 下載。
Step 2: 配置ProtoBuf相關(guān)設(shè)置
添加ProtoBuf查找路徑
顧名思義,告訴Wireshark去哪里查詢你的.proto文件。我把我的所有(其實就一個).proto文件都放到了同一個文件夾里,然后添加到Wireshark里即可。
在版本 4.2.3中, 你可以通過一下方法配置ProtoBuf查找路徑:
Edit -> Preferences,接著在左側(cè)菜單中找到并展開Protocols標簽,然后找到Protobuf并打開對應(yīng)頁面,就會得到以下的界面:
然后點擊 “Protobuf search paths” 旁邊的Edit按鈕打開新窗口:
我把所有.proto文件都放一起了,也沒有其他外部引用,所以我只添加了一個文件夾路徑就OK啦。
Step 3 運行和調(diào)試Lua代碼
1. 添加Lua腳本
創(chuàng)建并將我們自己寫的Lua腳本放到指定文件夾中,Wireshark才能識別到我們的Lua腳本:
Help -> About Wireshark
點擊Folder頁簽,雙擊Personal Lua Plugins路徑打開文件夾,并將我們寫好的腳本放入其中。
為了測試方便,我們現(xiàn)在只需要寫一行簡單的打印即可:
print("Hello World")
2. 運行和調(diào)試
成功將Lua腳本放到對應(yīng)文件夾后,Wireshark會在每次啟動的時候都運行一下你的腳本。你可以打開Lua控制臺窗口看看腳本運行的結(jié)果。
打開控制臺很簡單,點擊 Tools -> Lua Console:
上半部分的文本輸入框是可以實時輸入并且運行的Lua代碼,我們這里用不到先不管它。重點放在下半部的輸出窗口,可以看到我們腳本運行的結(jié)果已經(jīng)打印出來了。
不過我們不希望每次改了代碼還要重新運行Wireshark怎么辦呢?Wireshark提供了重載Lua腳本的功能,可以在 Analysis -> Reload Lua Plugins 中找到,或者直接點擊快捷鍵 Ctrl+Shift+L。
需要注意的是,重載Lua腳本之后,Wireshark會在已經(jīng)捕獲的每個包上重新跑一遍我們的Lua腳本。如果你此時已經(jīng)捕獲了大量的包,那么重載可能會消耗不少的時間。
Step 4: 寫Lua Dissector代碼 😃
到這步為止,所有的配置都已經(jīng)完成,只需用Lua實現(xiàn)我們的ProtoBuf Dissector即可。
在我們寫之前還有一些很有用的參考資料:
-
Wireshark有Lua APIs的文檔在這里。
-
還有兩個很好的簡單教程在這里和那里。
以下的代碼示例是在我綜合了上面的內(nèi)容之后,摘掉非必要的代碼而實現(xiàn)的一個極簡的Lua Dissector。不過也存在過于精簡而不符合實際運用的需要,這個就需要使用者根據(jù)自己的實際需求和協(xié)議設(shè)計去修改代碼了。
--獲取Wireshark庫里現(xiàn)成的ProtoBuf解析器
local protobuf_dissector = Dissector.get("protobuf");--Proto類可以拿來實現(xiàn)自己的解析器
--不過我這里只用來幫我注冊上Wireshark的回調(diào)
--然后需要實際解析ProtoBuf的時候,我會調(diào)用上面獲取到的官方解析器
--@param myProto 名字
--@param "My Proto" 描述
local my_proto = Proto("MyProto", "My Proto");---Wireshark會在每個包上調(diào)用這個預(yù)設(shè)函數(shù)
---@param tvb table 一個輔助操作讀取到的二進制流的類對象
---@param pinfo table 儲存了包體信息的類對象
---@param tree table GUI上展示信息用的根節(jié)點
-- 我的數(shù)據(jù)流會截取到的數(shù)據(jù)格式如下:(因項目而異)
-- [Header][Message Data]
-- Header: [2 bytes length]
my_proto.dissector = function(tvb, pinfo, tree)if tvb:captured_len() == 0 then return end;if pinfo.port_type == 2 then --TCPpinfo.columns.columns.protocol:set(my_proto.name);--創(chuàng)建一個新的UI節(jié)點來展示我們ProtoBuf解析的數(shù)據(jù),當然也可以不創(chuàng)建新節(jié)點,直接展示在tree上local subtree = tree:add(my_proto, tvb());local offset = 0;local length = tvb(0, 2):le_uint(); --[2 bytes length]local data_len = length - 2; --計算實際的數(shù)據(jù)長度offset = offset + 2;--這行很關(guān)鍵,官方的解析器會根據(jù)這個字段去.proto文件里找對應(yīng)的協(xié)議去解析pinfo.private["pb_msg_type"] = "message,myProto.Message";pcall(Dissector.call, protobuf_dissector, tvb(offset, data_len), pinfo, subtree);end
end--將我的Proto類對象注冊到TCP端口上
--要注意的是,當你還不清楚實際發(fā)生的端口號時,先填0,后續(xù)再配置即可(具體配置方法看下一部分"Decode As")
DissectorTable.get("tcp.port"):add(0, my_proto);
Step 5(Optional): Decode As
當你需要動態(tài)調(diào)整Tcp端口時,可以在以下的菜單中手動配置:
Analyze -> Decode As
點擊"+"號添加新的一行,字段選"TCP port"然后填入實際端口號,最后在Current下拉框中,找到我們剛剛添加的"MYPROTO"解析器后單擊選擇。
最后點擊保存就配置完成啦!
PS:如果你的代碼無誤,又看不到你的解析器,請檢查一下你是不是沒有重載Lua代碼。
Github工程地址
源碼和教程我都有上傳到Github,有需要的同學可以自行上去取源碼
https://github.com/Kayn-Liu/WiresharkProtoBufDissectorLua.git