Wireshark中lua脚本介绍

Wireshark中lua脚本介绍

概述

Wireshark是非常强大的报文解析工具,是网络定位中不可缺的使用工具,在物联网中很多为自定义协议,wireshark无法解析,此时lua脚本就有了用武之地。Lua是一个脚本语言,不需要编译可以直接调用,完美解决了自定义报文解析。

代码框架

-- create a new dissector
local NAME = "Doip"
local PORT = 13400
local Doip = Proto(NAME, " Doip Protocol")
-- dissect packet
function Doip.dissector (tvb, pinfo, tree)
end
-- register this dissector
DissectorTable.get("udp.port"):add(PORT, Doip)

 

如上一个简单的lua代码分为三部分:

  1. 创建Proto对象
  2. 创建dissector方法
  3. 注册解析器

加载解析器到wireshark

将lua文件放在wirekshark的安装目录,在wireshark的根目录中找到init.Lua,打开后将文件中的enable_lua设置为true,并在文件目录中增加我们编写的lua脚本,使用的为dofile(DATA_DIR.."DoIP.lua”)。

uploading.4e448015.gif转存失败重新上传取消

Figure 1lua脚本放置位置

uploading.4e448015.gif转存失败重新上传取消

Figure 2修改enable_lua为true

uploading.4e448015.gif转存失败重新上传取消

Figure 3注册新编写脚本

重新打开wireshark或者shift+ctrl+L快捷键进行lua加载即可进行解析。

 

Lua插件API接口

  1. Proto对象

表示一个新的protocol,使用

接口

说明

proto:__call (name,desc)

创建Proto对象。name和desc分别是对象的名称和描述,前者可用于过滤器等

proto.name

get名称

proto.fields

get/set字段

proto.prefs

get配置项

proto.init

初始化,无参数

proto.dissector

解析函数,3个参数tvb,pinfo,tree,分别是报文内容,报文信息和解析树结构

proto:register_heuristic (listname, func)

为Proto注册一个启发式解析器,被调用时,参数func将被传入与dissector方法相同的3个参数

 

常用使用:

local NAME1          = "red"

local PORT           = 5004

local RTP_PROTO_TYPE = 106

local red    = Proto(NAME1, "Red Protocol")

  1. Protofield

此对象为协议字段,用于解析字段后在描述字上添加节点,根据接口不同可以分成两大类:

整型:

ProtoFiled.{type}(abbr,[name],desc,base,valuestring,mask)

Type包括:uint8,uint16,uint24,uint32,uint64,framenum

Abbr:过滤器的名字

Name:在解析树中的名字

Base:One of base.DEC, base.HEX or base.OCT, base.DEC_HEX, base.HEX_DEC, base.UNIT_STRING or base.RANGE_STRING.

Valuestring:可以用表的形式来进行解析,也可以理解为switch语句

Mask:类型掩码

Desc:字段描述

其他类型:

ProtoField.{type},(abbr,[bane],[desc])

Type包括:float,double,string,stringz,bytes,bool,ipv4,ipv6,ether,oid,guid.

[]内的事可选字段,{}中的事可替换字段。

示例如下:

-- create fields of red

fields_M = ProtoField.uint8 (NAME1 .. ".M", "M",base.HEX,Payload_type,0x80)

fields_pt = ProtoField.uint8 (NAME1 .. ".PT", "PT", base.DEC,Payload_type,0x7F)

fields_seqno   = ProtoField.uint16(NAME1 .. ".seqno", "Sequence number")

fields_h264bytes = ProtoField.bytes(NAME1 .. ".bytes", "H264Data")

fields_fec        = ProtoField.bytes(NAME1 .. ".fec", "FEC Payload")

这些字段添加到结构树种后显示如下:

uploading.4e448015.gif转存失败重新上传取消

  1. Tvb

Testy vitual Buffer表示报文缓存,也就是实际报文数据,可以通过一下方法将报文数据中解析出信息,接口如下:

tvb:__tostring()

将报文数据转化为字符串,可用于调试

tvb:reported_len()

get tvb的(not captured)长度

tvb:len()

get tvb的(captured)长度

tvb:reported_length_remaining()

获取当前tvb的剩余长度,如果偏移值大于报文长度,则返回-1

tvb:offset()

返回原始偏移

 

 常用的字段是tvb:len()

  1. Pinfo

报文信息(packet information),接口如下:

接口

说明

pinfo.len pinfo.caplen

get报文长度

pinfo.abs_ts

get报文捕获时间

pinfo.number

get报文编号

pinfo.src pinfo.dst

get/set报文的源地址、目的地址

pinfo.columns pinfo.cols

get报文列表列(界面)

获得列表信息后就可以设备该列文本,比如

-- show protocol name in protocol column

pinfo.cols.protocol = “RED”

如上,可以将协议类型显示为RED

 

 

  1. Treeitem

解析树,用来展示字段的树形结构

接口

说明

tree_item:add_packet_field(protofield, [tvbrange], encoding, [label])

使用协议字段创建一个子树,可以根据入参调整大小字节序ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN

treeitem:add([protofield], [tvbrange], [value], [label])

增加一个子树,并返回该子树,使用大字节序解析

treeitem:add_le([protofield], [tvbrange], [value], [label])

增加一个子树,并返回该子树,使用小字节序解析

treeitem:append_text

附加文本到这个表

treeitem:prepend_text(text)

在表前增加文本

treeitem:add_proto_expert_info(expert, [text])

设置树项的专家标志并将专家信息添加到包中。

 

  1. DissectorTable

这个是一个具体协议解析表,比如TCP的解析表tcp.port包括http,SMTP,ftp等

此对象的接口如下:

接口

说明

DissectorTable.get(name)

get名为name的解析表的引用

dissectortable:add(pattern, dissector)

将Proto或Dissector对象添加到解析表,即注册。pattern可以是整型值,整型值范围或字符串,这取决于当前解析表的类型

dissectortable:remove(pattern, dissector)

将满足pattern的一个或一组Proto、Dissector对象从解析表中删除

  1. 其他API接口

https://www.wireshark.org/docs/wsdg_html_chunked/lua_module_Proto.html

 

 

 

  1. 样例:

 

local version_str = string.match(_VERSION, "%d+[.]%d*")

local version_num = version_str and tonumber(version_str) or 5.1

local bit = (version_num >= 5.2) and require("bit32") or require("bit")

 

-- create a new dissector to decode rtp private payload

local NAME1          = "red"

local PORT           = 5004

local RTP_PROTO_TYPE = 106

 

local red            = Proto(NAME1, "Red Protocol")

 

-- create fields of red

fields_M             = ProtoField.uint8 (NAME1 .. ".M", "M", base.HEX,Payload_type,0x80)

fields_pt            = ProtoField.uint8 (NAME1 .. ".PT", "PT", base.DEC,Payload_type,0x7F)

fields_seqno         = ProtoField.uint16(NAME1 .. ".seqno", "Sequence number")

fields_h264bytes     = ProtoField.bytes(NAME1 .. ".bytes", "H264Data")

fields_fec           = ProtoField.bytes(NAME1 .. ".fec", "FEC Payload")

 

red.fields           = { fields_M, fields_pt, fields_seqno, fields_h264bytes,fields_fec }

 

local RTP_dis        = Dissector.get("rtp")

local H264_dis       = Dissector.get("h264")

local Data_dis       = Dissector.get("data")

 

-- dissect packet

function red.dissector(tvb, pinfo, tree)

    length = tvb:len()

    if length == 0 then return end

    -- decode private header

    local subtree = tree:add(red, tvb(0,3))

    subtree:add(fields_M, tvb(0,1))

    subtree:add(fields_pt, tvb(0,1))

    subtree:add(fields_seqno, tvb(1,2))

 

    -- show protocol name in protocol column

    pinfo.cols.protocol = red.name

   

    local fec_id = tvb(0,1):uint()

    local fec_type = bit.band(fec_id,0x7F)

    if fec_type == 109 then

        tree:add(fields_fec,tvb(3))

    else

        H264_dis:call(tvb(3):tvb(), pinfo, tree)

    end

end

 

--decode first layer  as rtp

local udp_dissector_table = DissectorTable.get("udp.port")

udp_dissector_table:set(PORT,RTP_dis)

 

-- register this dissector

-- DissectorTable.get("rtp.pt"):add(PORT, red)

--decode private protocol layer  3-bytes private datas + standard h264

local rtp_dissector_table = DissectorTable.get("rtp.pt")

rtp_dissector_table:set(RTP_PROTO_TYPE,red)

 

 

附录:

red.dissector(tvb, pinfo, tree)

 

参考:https://blog.csdn.net/qq_40421919/article/details/103516694

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值