本文介绍利用Lua脚本语言,实现wireshark解析器,解析自定义通信协议:
- 解析器组成部分
- TCP粘包处理
- wireshark集成
解析器组成部分
do
--[[
创建一个自定义协议simpleProtocol
第一个参数是协议名称会体现在过滤器中
第二个参数是协议的描述信息,无关紧要
--]]
local simpleProtocol = Proto("simpleProtocol", "Simple Protocol")
--将字段添加到协议中
simpleProtocol.fields =
{
--协议字段
}
--[[
下面定义simpleProtocol解析器的主函数,这个函数由wireshark调用
第一个参数是Tvb类型,表示的是需要此解析器解析的数据,如UDP协议的数据部分
第二个参数是Pinfo类型,是协议解析树上的信息,即Packet List显示部分
第三个参数是TreeItem类型,表示上一级解析树,即Packet Details显示部分
--]]
function simpleProtocol.dissector(tvbuf, pktinfo, tree)
--解析部分
end
--向wireshark注册解析器,具体哪个端口上处理解析
local udpTable = DissectorTable.get("udp.port")
udpTable:add(8000, simpleProtocol)
end
TCP粘包处理
1、单TCP segment多应用PDU
这种情况大多使用循环解决
2、单应用PDU多TCP segment
这种情况需要wireshark为我们重新拼接被TCP协议栈拆分的数据
下面框架可以同时处理这两种情况:
--[[
假设,自定义协议的dissector函数入参tvbuf,解析出了协议报文的应有长度frameLenth,并在进入下面解析前得到
--]]
--pinfo.desegment_offset表示已有的报文长度
offset = pinfo.desegment_offset or 0
while true
do
--一个自定义协议报文需要的长度
local nextFrame = offset + frameLength;
if tvbuf:len() < nextFrame then
--pinfo.desegment_len表示已有的报文长度,传递给desegment_offset
pinfo.desegment_len = nextFrame - tvbuf:len()
return
end
--一个自定义协议的报文处理部分
///
if tvbuf:len() == nextFrame then
break
end
--[[
上面处理了第2种情况,下面循环回去处理第1种情况
--]]
end
wireshark集成
将上述的自定义通信协议解析器simpleprotocol.lua保存至wireshark安装目录,进入wireshark安装目录,找到init.lua文件打开,最后一行增加下面内容:
dofile(DATA_DIR.."simpleprotocol.lua")
参考
1、Lua介绍: [百度百科]
2、Lua for wireshark: [wireshark官网对Lua的应用介绍]