原文:http://www.cnblogs.com/wendellyi/p/3475461.html
一、平台
操作系统:windows 7
wireshark:1.10.3
lua:5.1
二、准备
lua 语言基本语法,特别是关于表操作和循环
wireshark 文档,包括用户使用文档和开发者文档,这些在 wireshark 官方网站都能找到
三、开始
我们首先定义一个简单的协议,我们使用 C 语言的语法描述,
struct foo { char protocol_type[16]; /* request response notify */ char service_type[16]; /* 我们定义的各种服务类型 */ unsigned int msg_len; /* 消息体的长度 */ char msg_content[0]; /* 消息体的内容,由于是变长的所以采用此方法定义 */ };
现在可以让我们使用 lua 定义一个最基本的框架
do --[[ 创建一个新的协议结构 foo_proto 第一个参数是协议名称会体现在过滤器中 第二个参数是协议的描述信息,无关紧要 --]] local foo_proto = Proto("foo", "Foo Protolcol") --[[ 下面定义字段 --]] local foo_protocol_type = ProtoField.string("foo.prototype", "Protocol Type", base.NONE) local foo_service_type = ProtoField.string("foo.servicetype", "Service Type", base.NONE) local foo_msg_len = ProtoField.uint32("foo.msglen", "Message Length", base.DEC) local foo_msg_content = ProtoField.string("foo.msgcontent", "Message Content", base.NONE) -- 将字段添加都协议中 foo_proto.fields = { foo_protocol_type, foo_service_type, foo_msg_len, foo_msg_content } --[[ 下面定义 foo 解析器的主函数,这个函数由 wireshark调用 第一个参数是 Tvb 类型,表示的是需要此解析器解析的数据 第二个参数是 Pinfo 类型,是协议解析树上的信息,包括 UI 上的显示 第三个参数是 TreeItem 类型,表示上一级解析树 --]] function foo_proto.dissector(tvb, pinfo, treeitem) -- 设置一些 UI 上面的信息 pinfo.cols.protocol:set("FOO") pinfo.cols.info:set("Foo Protocol") local offset = 0 local tvb_len = tvb:len() -- 在上一级解析树上创建 foo 的根节点 local foo_tree = treeitem:add(foo_proto, tvb:range(offset)) -- 下面是想该根节点上添加子节点,也就是自定义协议的各个字段 -- 注意 range 这个方法的两个参数的意义,第一个表示此时的偏移量 -- 第二个参数代表的是字段占用数据的长度 foo_tree:add(foo_protocol_type, tvb:range(offset, 16)) offset = offset+16 foo_tree:add(foo_service_type, tvb:range(offset, 16)) offset = offset+16 foo_tree:add(foo_msg_len, tvb:range(offset, 4)) offset = offset+4 -- 计算消息内容的长度 local foo_content_len = tvb_len-offset foo_tree:add(foo_msg_content, tvb:range(offset, foo_content_len)) offset = offset+foo_content_len end -- 向 wireshark 注册协议插件被调用的条件 local tcp_port_table = DissectorTable.get("tcp.port") tcp_port_table:add(12345, foo_proto) end
四、扩展
(1)单 TCP 分节多应用 PDU
这种情况可以在我们的协议解析函数中使用循环解决,但是应用层 PDU 一般都需要有我们自定义的分割标识符,不然无法区分,这里我们使用协议尾端标记的方式,采用0xFF分割,这里我们假设我们的协议体中不会出现这个值,也就是我们的消息体长度字段的值不会出现这个值。
(2)单应用 PDU 多 TCP 分节
这种情况就需要 wireshark 为我们重新拼接被 TCP 协议栈拆分的数据,不过这已经有接口可用了,下面是处理两种情况的框架
do -- 这里便于运算需要将数据类型进行转换 local tvbrange = tvb:range(0) local bytearray = tvbrange:bytes() local offset = pinfo.desegment_offset or 0 while true do local pdu_flg = false local pdu_end_index = 0 -- ByteArray 类型的索引与 C 类似 -- 这与 lua 本身处理表的方式有所区别 for i = offset, tvb_len do if 0xFF == bytearray:get_index(i) then pdu_flg = true pdu_end_index = i end end -- 如果没有找到 PDU 的结束符,进行合包延迟解析 if false == frame_end_flg then -- 如果明确知道这个应用协议还需要多少字节 -- 可以明确地将需要的值填上,而不是使用下面的值 -- 只是表示需要更多的分节 pinfo.desegment_len = DESEGMENT_ONE_MORE_SEGMENT return end -- 下面是正常的处理流程,在上面的代码中已经有体现了 -- 不过此时协议最大边界为 pdu_end_index end end
五、完善
(1)谈到网络协议,如果涉及到整数必然会有字节序的问题,如果 wireshark 默认使用的是大端字节序,如果协议中的整数采用的是小端字节序,那么请考虑使用 TreeItem 类型的 le_add() 方法替代 add() 方法。
(2)在 add 和 le_add 方法中,我们可以显式设定我们自己的值,可以给 add 方法传递第三个值,例如,
local protocol_type = tvb:range(offset, 16):string() foo_tree:add(foo_protocol_type, tvb:range(offset, 4), protocol_type)
这样显示的就是 protocol_type 的内容,另外这里的 protocol_type 类型一定要与上面定义 foo_protocol_type 让 wireshark 解析的一致,不然这个值是无效的,也就是说这个地方 protocol_type 如果是整数,就是无效,反过来也是一样。
(3)在协议解析树上增加节点不一定要提前定义字段,也就是字段的定义不是必须的,例如,
local protocol_type = tvb:range(offset, 16):string() foo_tree:add(tvb:range(offset, 16), "Protocol Type: " .. protocol_type)
效果是一样的,但是在过滤器中无法使用此字段。
(4)pinfo.cols.info:set 方法可以延迟调用,也就说可以在确定了消息的各种属性之后在调用,这样可以更清晰的显示协议的摘要。
六、参考
(1)wireshark 用户手册,在 wireshark 的安装目录下有 chm 的版本,最值得参考的是第11章的数据类型和各种方法的解释。
(2)重组被拆分的 TCP 分节,http://stackoverflow.com/questions/13138088/how-do-i-reassemble-tcp-packet-in-lua-dissector
(3)处理一个分节多应用 PDU,http://stackoverflow.com/questions/14387426/reassembling-packets-in-a-lua-wireshark-dissector
(4)调用子协议的方法,http://blog.csdn.net/phunxm/article/details/5972904
相关推荐
使用Lua脚本为wireshark编写自定义通信协议解析器插件 .
用lua语言编写Wireshark插件解析自定义协议
即当wireshark不能及时解析一些新的协议时,可以自己动手根据新协议字段编写解析文件。有新协议的话可以基于此脚本改写. 使用方法: 1. 打开wireshark根目录中的init.lua文件, 将disable_lua=false 并在最后添加...
用lua语言编写Wireshark插件解析自定义协议.doc
RNDIS数据在原生Wireshark只能解析到USB URB层,后面是RAW DATA;为了调研方便,于是用lua语言开发了rndis的解析插件。 20210806: 更新了脚本中的一些解析bug。 20220315: 支持linux控制头的rndis处理
其中cmpp与sgip协议,上下行短信内容可以直接解码为汉字内容,添加方法如下: 1. 将下载的文件解压至Wireshark根目录 2. 修改Wireshark根目录init.lua文件,拉到最后,添加如下内容: dofile("CMPPv2.lua")...
1 确认你的Wireshark支持lua 如果Wireshark安装目录下面有init lua文件就说明支持Lua 2 将rtp h264 lua拷贝到Wireshark的安装目录下 3 需要启动对Lua的支持 默认不启动对Lua的支持 编辑 init lua文件 在“disable ...
利用Wireshark解析自定义协议,以portal协议为实例,并利用LUA脚本进行解释。
本文介绍了如何使用Lua编写wireshark的dissector,通过Lua可以快速写出我们自己的dissector,从而可以分析网络数据包。
wireshark解析omci报文的插件
2. 安装好wiresshark后的目录(**/**/Wireshark)下创建一个 lua 文件夹。把root3.0放在当前文件夹下 并解压 3. 在wiresshark目录下 init.lua 文件目录添加上一行 dofile(DATA_DIR.."lua/robotV3_0/robot.lua"&#...
使用lua编写的YGoPro卡片脚本.zip使用lua编写的YGoPro卡片脚本.zip使用lua编写的YGoPro卡片脚本.zip使用lua编写的YGoPro卡片脚本.zip使用lua编写的YGoPro卡片脚本.zip使用lua编写的YGoPro卡片脚本.zip使用lua编写的...
Wireshark协议插件 sgip ,联通短信协议,luna 脚本 Wireshark sgip协议插件
支持同时解析多个视频流,并以发送和接收的信息为文件名 第一步:在init.lua脚本中设置disable_lua = false 第二步:在init.lua文末有一句dofile(DATA_DIR.."h264_export.lua") 第三步:将下载的h264_export.lua文件...
【使用方法】使用插件时,将插件的lua脚本放置在Wireshark的安装目录中plugins目录下 并在主目录找到init.lua文件,在文件中找到enable_lua或disable_lua,将enable_lua = true或disable_lua = false,即使Lua脚本...
将附件的rtp_h264_extractor.lua文件,放到wireshark安装目录下,然后修改wireshark安装目录下的init.lua文件: (1)若有disable_lua = true这样的行,则注释掉; (2)在文件末加入dofile("rtp_h264_extractor.lua...
Wireshark+lua插件方式抓包及解析OMCI协议报文详细信息
基于LUA的wireshark插件,利用listener搭建一个对esp协议包的包序号连续性检验的提示器
用Lua脚本开发的一种私有协议的解析插件的源码,附有.pcap抓包文件,简小精短。
wireshark解析H265数据时需要安装的插件,具体步骤百度即可