用lua语言编写Wireshark插件解析自定义协议

上传人:宝路 文档编号:7845589 上传时间:2017-09-24 格式:DOC 页数:8 大小:340.01KB
返回 下载 相关 举报
用lua语言编写Wireshark插件解析自定义协议_第1页
第1页 / 共8页
用lua语言编写Wireshark插件解析自定义协议_第2页
第2页 / 共8页
用lua语言编写Wireshark插件解析自定义协议_第3页
第3页 / 共8页
用lua语言编写Wireshark插件解析自定义协议_第4页
第4页 / 共8页
用lua语言编写Wireshark插件解析自定义协议_第5页
第5页 / 共8页
点击查看更多>>
资源描述

《用lua语言编写Wireshark插件解析自定义协议》由会员分享,可在线阅读,更多相关《用lua语言编写Wireshark插件解析自定义协议(8页珍藏版)》请在金锄头文库上搜索。

1、用 lua 语言编写 Wireshark 插件解析自定义协议(y00111592 2012-01)Wireshark 默认支持大量网络协议,我们可以在 Wireshark 主菜单“Internals Support Protocols (slow!)”查看当前支持的所有协议。Wireshark 1.6.2 版本已支持 1170 种协议,包括我们熟悉的 Diameter、GTP、FTP、SCTP 等协议。上述都是业界的通用协议,然而对我们产品的自定义协议,Wireshark 是不得而知的,抓包后只能看到一串二进制码流,导致开发调试或者测试分析效率较低。有什么办法让 Wireshark 也能解析自

2、定义协议呢?本文介绍的用 lua 编写 Wireshark 解析器插件就是一种常用方法。Wireshark 软件内嵌一个 lua 语言执行引擎并提供一系列 lua 函数接口,从而满足用户各种各样的协议解析目的。下面以一个简单的自定义协议为例,演示如何编写 Wireshark 解析插件。不过本文只是业余学习的笔记和简单实践,不能覆盖“lua 编写 Wireshark 解析器插件”的所有知识点(更全面的介绍请参考 Wireshark 软件自带手册第 11 章“Lua Support in Wireshark”,只是开源软件的手册似乎总是不够详尽。 ) 。1. 配置 Wireshark 执行 lua

3、 脚本通过 Wireshark 主菜单“Help About Wireshark”可以查看当前安装版本已经内嵌 Lua 5.1 执行引擎。默认安装情况下 Wireshark 会在安装路径下生成一个 init.lua,它是Wireshark 启动过程执行的第一个 lua 脚本。一般来说,我们可以在此文件中添加 dofile 函数调用其他 lua 脚本,实现各种扩展目的。例如,默认安装后 init.lua 文件末尾有一句:dofile(DATA_DIR.console.lua)此语句执行了安装目录下的 console.lua 脚本,该脚本也是 Wireshark 自带的,用途是在主菜单 Tool

4、下创建一个子菜单 Lua。我们甚至可以在上述语句之前添加注释-符来取消它。dofile 是 lua 基础库提供的一个函数,用途如下:dofile (filename)Opens the named file and executes its contents as a Lua chunk. When called without arguments, dofile executes the contents of the standard input (stdin). Returns all values returned by the chunk. In case of errors, do

5、file propagates the error to its caller (that is, dofile does not run in protected mode).我们下来编写的解析器也是以.lua 脚本形式保存,然后在 init.lua 文件末尾中添加一个dofile 调用即可。2. 需要解析的自定义协议假设我们需要基于 UDP 协议实现一种根据员工 ID 查询员工姓名的信息服务,客户端向服务器端的 12345 端口发送 QueryRequest,服务器返回应答 QueryResponse,数据结构如下:消息名称 消息结构QueryRequest Uint16 usMsgTyp

6、e; /消息类型, 查询请求=0Uint32 uiEmployeeID; /员工工号QueryResponse Uint16 usMsgType; /消息类型,查询应答=1Uint32 uiEmployeeID; /员工工号Uint16 usQueryResult; /查询操作结果,成功 =0, 失败=1Char32 szEmployeeName; /查询结果,如果成功,填写员工姓名;否则填写失败原因假设员工数据库信息有两条记录如下:员工 ID 员工姓名1 Liu Dehua2 Zhang Xueyou将上述协议实现之后,服务器端部署在 192.168.56.1, 客户端在 192.168.5

7、6.22。以下就是启动 1 次查询过程的 Wireshark 抓包结果:上图是 QueryRequest 消息,uEmployeeID 指定为 1。上图是 QueryResponse 消息,返回 uEmployeeID=1 的查询结果。从上面 2 个图可见,Wireshark 已经自动地把以太网帧、IP 报文、UDP 数据报都解析出来,唯独我们自定义协议的消息无法解析,以 Data 来显示。把上述抓包结果保存到一个pcap 文件中。下面我们逐步实现对该协议的解析。3. Wireshark 的 lua 函数接口3.1. Proto 协议在 Wireshark 中 Proto 主要用途是声明一个新

8、的协议,进而可以给它编写解析器函数。3.1.1. Proto.new:声明一个新的协议例如:my_proto = Proto (myProto,My Protocol for Query Employee,My Self-defined Protocol)3.1.2. proto.dissector:解析器函数例如:function my_proto.dissector(buffer,pinfo,tree)pinfo.cols.protocol:set(myProto)pinfo.cols.info:set(This is a message of myProto)enddissector 函

9、数的第一个参数 buffer 对应需要解析的二进制码流,第二个参数 pinfo 对应Packet List 窗口的信息,tree 是 Packet Details 窗口的树结构,如下图所示:Wireshark 已经为我们提供了处理这三个参数的接口了。有关 buffer 的 lua API,可以参考官方手册“11.12. Functions for handling packet data”,如下图所示:有关 pinfo 的 lua API,可以参考官方手册 “11.9. Obtaining packet information ”,如下图所示:有关 tree 的 lua API,可以参考官方手

10、册“11.11. Adding information to the dissection tree”,如下图所示:把上述代码保存到一个 d:/myproto.lua 脚本中,并在 init.lua 脚本中末尾增加一句:dofile(d:/ myproto.lua)然后启动 Wireshark 程序,就可以在协议列表中找到我们定义的协议了,如下图所示:3.2 ProtoField 协议字段(域)但凡协议都有具体的字段,Wireshark 提供了 25 种函数可以创建各种类型字段(详细请参考帮助文档 11.10.6. ProtoField) 。我前面定义的协议字段类型很简单,只有 16 位无符号

11、整数、32 位无符号整数、32 字符长度的字符串三种。下面是各字段的具体 lua 代码实现:字段定义 Lua 定义Uint16 usMsgType local f_usMsgType = ProtoField.uint16(“usMsgType”, “MsgType”, base.DEC, 0 = QueryRequest , 1 = QueryResponse )Uint32 uiEmployeeID local f_uiEmployeeID = ProtoField. uint32(“uiEmployeeID”, “EmployeeID”, base.DEC)Uint16 usQueryR

12、esult local f_usQueryResult = ProtoField. uint32(“usQueryResult”, “QueryResult”, base.DEC, 0 = Success , 1 = Failed )Char32 szEmployeeNamelocal f_szEmployeeName = ProtoField. string (“szEmployeeName”, “EmployeeName”)然后我们把这些字段加到前面定义的 Proto 中去:my_proto.fields = f_usMsgType, f_uiEmployeeID, f_usQueryRe

13、sult, f_szEmployeeName 把上述代码追加到 d:/myproto.lua 脚本中,重启 Wireshark 就可以看到 MYPROTO 协议已经具有 4 个字段了:我们还可以在主窗口的“显示过滤表达式”快捷方式中,指定上述字段来做过滤:如下图所示,左侧 Field name 窗口中选择了 usMsgType 后,右侧显示了我们前面预定义的两个取值:3.2. DissectorTable 协议解析器表DissectorTable 就是若干协议解析器 (Dissector)汇集成 Table,Wireshark 默认支持了一系列 Dissector 和 DissectorTab

14、le,在主菜单“Internals Dissector tables”可以查看当前已支持的 DissectorTable,如下图所示:图中所示的 UDP port 就是一个 DissectorTable,它底下包含很多不同端口号,根据具体UDP 端口号调用具体 Dissector 来解析协议消息。例如 UDP 端口号 69 是 TFTP 协议采用的知名端口,Wireshark 遇到这种消息将自动调用 TFTP 协议解析器来处理。本文介绍的自定义协议基于 UDP 端口号 12345,所以我也把它添加到 UDP port 这个 DissectorTable 下。3.2.1. DissectorTa

15、ble.get:返回指定的 DissectorTable 实例下面的代码首先通过 DissectorTable.get 获取了“udp.port”表:Local udp_port_table = DissectorTable.get(udp.port)3.2.2 dissectortable:add:向 DissectorTable 实例中添加 dissectorLocal my_port = 12345Udp_port_table:add(my_port, my_proto)把上述代码追加到 d:/myproto.lua 脚本中,重启 Wireshark 就可以看到 MYPROTO 已经增加

16、 UDP port 下面:不但如此,我们打开前面抓包的文件,可以看到有些东西悄悄变化了:说明前面的解析器函数已经被正确调用了,至此我们已经完成了一个解析器雏形。下面将完善解析器函数,使之真正能够解析协议消息。4. 自定义协议的解析器函数我们要怎么呈现解析结果呢?看看下图是 Wireshark 默认对 UDP 协议的解析结果:我们自定义协议的解析也将生成一个类似的树状结构。前面我们已经写了一个简单的my_proto.dissector 函数函数如下所示:function my_proto.dissector(buffer,pinfo,tree)pinfo.cols.protocol:set(myProto)pinfo.cols.info:set(This is a message of myProto)end参数 tree 就是我们要构造的树状结构的根节点,通过下面两句代码添加

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 中学教育 > 试题/考题

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号