一、平台

操作系统:windows 7

wireshark:1.10.3

lua:5.1

二、准备

lua 语言基本语法,特别是关于表操作和循环

wireshark 文档,包括用户使用文档和开发者文档,这些在 wireshark 官方网站都能找到

三、开始

我们首先定义一个简单的协议,我们使用 C 语言的语法描述,

 struct foo
{
char protocol_type[]; /* request response notify */
char service_type[]; /* 我们定义的各种服务类型 */
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 =
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, ))
offset = offset+ -- 计算消息内容的长度
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(, foo_proto)
end

四、扩展

(1)单 TCP 分节多应用 PDU

这种情况可以在我们的协议解析函数中使用循环解决,但是应用层 PDU 一般都需要有我们自定义的分割标识符,不然无法区分,这里我们使用协议尾端标记的方式,采用0xFF分割,这里我们假设我们的协议体中不会出现这个值,也就是我们的消息体长度字段的值不会出现这个值。

(2)单应用 PDU 多 TCP 分节

这种情况就需要 wireshark 为我们重新拼接被 TCP 协议栈拆分的数据,不过这已经有接口可用了,下面是处理两种情况的框架

 do
-- 这里便于运算需要将数据类型进行转换
local tvbrange = tvb:range()
local bytearray = tvbrange:bytes()
local offset = pinfo.desegment_offset or while true do
local pdu_flg = false
local pdu_end_index = -- 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, ):string()
foo_tree:add(foo_protocol_type, tvb:range(offset, ), protocol_type)

这样显示的就是 protocol_type 的内容,另外这里的 protocol_type 类型一定要与上面定义 foo_protocol_type 让 wireshark 解析的一致,不然这个值是无效的,也就是说这个地方 protocol_type 如果是整数,就是无效,反过来也是一样。

(3)在协议解析树上增加节点不一定要提前定义字段,也就是字段的定义不是必须的,例如,

 local protocol_type = tvb:range(offset, ):string()
foo_tree:add(tvb:range(offset, ), "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 协议解析插件的更多相关文章

  1. Lua编写wireshark插件初探——解析Websocket上的MQTT协议

    一.背景 最近在做物联网流量分析时发现, App在使用MQTT协议时往往通过SSL+WebSocket+MQTT这种方式与服务器通信,在使用SSL中间人截获数据后,Wireshark不能自动解析出MQ ...

  2. 修改wireshark协议解析规则

    不同的协议有不同的解码器,wireshark尝试为每个包尝试找到正确的解码器,特定的情况有可能会选择错误的解码器. 1.使用了其它协议的标准端口,被错误解码,使用udp的80端口发送数据被当作QUIC ...

  3. 使用Lua编写Wireshark插件解析KCP UDP包,解析视频RTP包

    前段时间写了一个局域网音视频通话的程序,使用开源 KCP 来实现可靠UDP传输. 通过研究发现KCP在发包时,会在数据包前面加上它自己的头.如果数据包较小,KCP可能会把多个数据包合成一个包发送,提高 ...

  4. 用lua编写wireshark插件分析自己定义的协议

    参见: https://yoursunny.com/study/IS409/ScoreBoard.htm https://wiki.wireshark.org/LuaAPI/TreeItem http ...

  5. IM通信协议逆向分析、Wireshark自定义数据包格式解析插件编程学习

    相关学习资料 http://hi.baidu.com/hucyuansheng/item/bf2bfddefd1ee70ad68ed04d http://en.wikipedia.org/wiki/I ...

  6. Wireshark无法解析OpenFlow配置协议 解决方法

    在使用wireshark对OpenFlow交换机与FlowVisor的通信过程进行抓包分析的时候,在其选项中有openflow_v1选项,但Wireshark竟无法解析OpenFlow协议. 在查阅相 ...

  7. 【wireshark】协议解析

    1. 普通解析 Wireshark启动时,所有解析器进行初始化和注册.要注册的信息包括协议名称.各个字段的信息.过滤用的关键字.要关联的下层协议与端口(handoff)等.在解析过程,每个解析器负责解 ...

  8. wireshark 1.10.0 编译 及 协议解析部分的一些变化

    wireshark不久前升级到1.10.0稳定版,这个版本正如其版本号一样,相比1.8.x有较大变化. 我们先说说在windows下编译的问题,1.8.4/1.8.6版本的编译见我的文章:http:/ ...

  9. 欧姆龙FinsTCP与FinsUDP协议解析 —— 利用Wireshark对报文逐字节进行解析详细解析附含报文模拟器等

    前言 – Fins欧姆龙这个协议网上极少有相关的模拟器.Tcp的这一块倒是有但是Udp的基本都是不可用 1. Fins协议结构也很简单 协议分为两种 一种tcp一种udp 2. Tcp比Udp的报文会 ...

随机推荐

  1. SQLServer添加链接服务器

    右键,添加链接服务器 在安全里面输入用户名和密码 添加成功之后的使用方法 select * from [192.168.1.63,3326].[数据库].[dbo].[表]

  2. RAID5配置及服务器2003系统安装方法。2000系统的安装要使用7.9版本的引导盘

    服务器2003系统安装方法.2000系统的安装要使用7.9版本的引导盘 RAID5配置: 1.为新到的惠普DL380服务器装系统,首先要配置RAID阵列. 如下图进行配置. 启动到如上图阶段,按F8. ...

  3. 神经网络的结构汇总——tflearn

    一些先进的网络结构: # https://github.com/tflearn/tflearn/blob/master/examples/images/highway_dnn.py # -*- cod ...

  4. [Swift通天遁地]三、手势与图表-(7)创建饼形图表并导出图表为PNG图片

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  5. Django day27 认证组件,权限组件()

    一:认证组件 1.写一个类 class LoginAuth(): # 函数名一定要叫authenticate,接收必须两个参数,第二个参数是request对象 def authenticate(sel ...

  6. vuejs {{}},v-text 和 v-html的区别

    <div id="app"> <p>{{message}}</p> <!-- 输出:<span>通过双括号绑定</spa ...

  7. sessionStorage 的使用

    sessionStorage 的使用: sessionStorage.removeItem("data"); sessionStorage.getItem("data&q ...

  8. day03_12/13/2016_bean的管理之依赖注入

  9. IIS Express配置多站点同时运行

    环境:Win10 Pro.Visual Studio 2015 Community.IIS Express 10 VS2015集成IIS Express,所以无需单独下载, 默认安装位置:C:\Pro ...

  10. MVC系列学习(八)-分布视图

    1.本次学习实例 1.1.建议:为了尽可能让项目简单,就新建一个空的mvc项目,同时添加任何视图不用模板页 1.2注意:在添加LoginPart的分部视图时,要记得沟一个沟 2.项目代码,如下 总共三 ...