利用wireshark lua扩展能力增加自定义解析器[注释解读版]

前言

Wireshark提供了lua扩展能力,可以定制一些ListnerDissector,用于一些自定义的使用场景,例如:

lua插件适应场景
Listener报文统计、内容抽取等
Dissector协议树解析,在wireshark中立等可看

已在以前的文档中积累了对于Listener的使用,见Listener。

本文将继续介绍下Dissector的扩展使用。

介绍方式上,采用对于官网例子作详细地注释进行解读。

想多说点

这次尝试源于一次对于接口文档的阅读,想避免在后期又一次地翻阅文档,重新查看协议说明和字段描述。

为什么要重新费心费力去做某些重复的事情呢?

那么利用Wireshark Lua脚本将其固化下来,将是非常好的实践!

解析器基本组件

组件说明
Proto定义协议,包括字段和解析器函数定义;在解析树中体现为一个节点
ProtoField定义协议字段类型
Dissector Chain解析器链,某个解析器完成自身协议层解析后,可以在尾部继续调用其它解析器,完成整个报文解析

Tvb参数组件特殊说明

  • buf(offset[, length])切片操作
tvb 参数说明
offset必须,注意从零开始
length可选,如果不指定,将获取整个tvb长度
  • buf(offset[, length]):转型操作
tvb API说明
buf(…):tvb()调用其它解析器需要重新生成新的tvb作为参数
buf(…):uint*()获取数值,例如,uint*类型系列

启用扩展

  • 将扩展lua脚本文件放入Wireshark安装目录
  • Wireshark安装目录的init.lua中增加相应导入脚本
dofile(DATA_DIR.."example.lua")

讲解官网解析器例子


-- 分析器根协议
--- + 第一个参数为协议缩写,将后期用于过滤条件,所以,要求全局唯一
--- + 第二个参数为协议描述,默认用于协议解析树的节点Label,要求全局唯一local p_multi = Proto("multi", "MultiProto")-- 嵌套自定义子协议
local p_multi_priority = Proto("multi.flags", "MultiProto Flags")-- 协议字段值解析映射,对于枚举类型非常适合,将码值解析为更易懂的文本
-- 对于没有定义映射,将显示为'Unknown (value)'样式
local falseortrue = {[0] = "false",[1] = "true"
}-- 协议字段类型声明,常用的字段类型为uint*系列,以及stirng、bytes等类型
--- + 第一个参数将用于过滤条件,最好以根协议的缩写命名开头,但具有唯一性即可
--- + 第二个参数为字段描述,在协议解析树中作为节点名字,在协议内要求描述唯一
p_multi_priority.fields.priority_value = ProtoField.uint8("multi.flags.priority", "Priority Value", base.DEC)
p_multi_priority.fields.prefix_flag = ProtoField.uint8("multi.flags.prefix", "Prefix Flag", base.DEC, falseortrue)
p_multi_priority.fields.suffix_flag = ProtoField.uint8("multi.flags.suffix", "Suffix Flag", base.DEC, falseortrue)-- 解析器函数
--- + 第一个参数为报文数据,可以进行切片操作
--- + 第二个参数为wireshar解析行描述对象,可以操作修改行描述信息
--- + 第三个参数为wireshar当前解析树,可以继续增加新的子树和链接其它协议器
function p_multi_priority.dissector(buf, pkt, tree)-- 协议解析区域,在自身根节点中通过buf的第二个参数指明-- 选中时,Wireshark会高亮的节点对应的码流区域,其它add操作亦然-- 具体此协议,解析一个字节长度local subtree = tree.add(p_multi_priority, buf(0, 1))local u8 = buf(0, 1):uint()subtree:add(p_multi_priority.fields.priority_value, buf(0, 1), bit32.band(u8, 0xF))subtree:add(p_multi_priority.fields.prefix_flag, buf(0, 1), bit32.rshift(bit32.band(u8, 0x10), 4))subtree:add(p_multi_priority.fields.suffix_flag, buf(0, 1), bit32.rshift(bit32.band(u8, 0x20), 5))
end-- 自身解析层
-- 解析映射
local vs_protos = {[2] = "mtp2",[3] = "mtp3",[4] = "alcap",[5] = "h248",[6] = "ranap",[7] = "rnsap",[8] = "nbap"
}p_multi.fields.proto = ProtoField.uint8("multi.protocol", "Protocol", base.DEC, vs_protos)
p_multi.fields.dir   = ProtoField.uint8("multi.direction", "Direction", base.DEC, { [1] = "incoming", [0] = "outgoing"})
p_multi.fields.raw   = ProtoField.bytes("multi.text", "Text")-- 默认链接解析器,对于不需要深入解析的区域,可以采用裸码流解析器
local data_dis = Dissector.get("data")-- 解析器能够识别的链接解析器
local protos = {[2] = Dissector.get("mtp2"),[3] = Dissector.get("mtp3"),[4] = Dissector.get("alcap"),[5] = Dissector.get("h248"),[6] = Dissector.get("ranap"),[7] = Dissector.get("rnsap"),[8] = Dissector.get("nbap"),[9] = Dissector.get("rrc"),-- 注意,解析器的不同获取方式[10] = DissectorTable.get("sctp.ppi"):get_dissector(3), -- m3ua[11] = DissectorTable.get("ip.proto"):get_dissector(132), -- sctp
}-- 注意,解析器函数链接类其它协议器
function p_multi.dissector(buf, pkt, tree)-- 修改报文行的协议为已识别的协议pkt.cols.protocol:set(p_multi.name)-- local length = buf:len()-- 生成自身解析树local subtree = tree:add(p_multi, buf(0, 3))local offset = 0-- 注: subtree:add_le 可以按照字节序小端来获取报文中的数据subtree:add(p_multi.fields.proto, buf(offset, 1))offset = offset + 1subtree:add(p_multi.fields.dir, buf(offset, 1))offset = offset + 1-- 调用自身解析树的子协议进行解析--- 注意第一个参数需要产生新的tvb--- 注意第三个参数为自身子树节点p_multi_priority.dissector(buf(offset, 1):tvb(), pkt, subtree)offset = offset + 1-- 尾部链接其它解析器,注意树节点参数的不同local proto_id  = buf(0,1):uint()local dissector = protos[proto_id]if dissector ~= nil then-- 链接其它可以识别的解析器dissector:call(buf(offset):tvb(), pkt, tree)elseif proto_id < 2 then-- 特殊分支,在自身解析层完成,注意树节点为自身树subtree:add(p_multi.fields.raw, buf(offset))else-- 作为默认链接裸数据解析器data_dis:call(buf(offset):tvb(), pkt, tree)endend-- 增加自动解析配置,按照端口号进行解析
local udp_encap_table  = DissectorTable.get("udp.port")
udp_encap_table:add(7555, p_multi)

参考

  • Dissector Example
  • Proto API
  • Tvb API

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/637230.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java数据结构与算法:排序算法之堆排序

Java数据结构与算法&#xff1a;排序算法之堆排序 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;欢迎来到本专栏。在这寒冷的冬天&#xff0c;让我们一起点燃知识的火花&#xff0c;今天我们要探讨的主题是Java中一种高效的排序算…

rk1126, 实现 yolov8 目标检测

基于 RKNN 1126 实现 yolov8 目标检测 Ⓜ️ RKNN 模型转换 ONNX yolo export model./weights/yolov8s.pt formatonnx导出 RKNN 这里选择输出 concat 输入两个节点 onnx::Concat_425 和 onnx::Concat_426 from rknn.api import RKNNONNX_MODEL ./weights/yolov8s.onnxRKNN_MOD…

MySQL 索引(下)

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾MySQL-进阶篇 &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现…

C++轮子 · STL关联容器

上一篇文章中我们简单的介绍了一下STL中的序列容器和容器适配器,这篇文章中我们将重点介绍STL中的关联容器(最后四个在概念上应该不是关联容器,但是因为和前面的容器联系太紧密,统一放在这里讲解),主要内容包括: std::setstd::mapstd::multi_mapstd::multi_setstd::unor…

推荐新版AI智能聊天系统网站源码ChatGPT NineAi

Nine AI.ChatGPT是基于ChatGPT开发的一个人工智能技术驱动的自然语言处理工具&#xff0c;它能够通过学习和理解人类的语言来进行对话&#xff0c;还能根据聊天的上下文进行互动&#xff0c;真正像人类一样来聊天交流&#xff0c;甚至能完成撰写邮件、视频脚本、文案、翻译、代…

GoZero微服务个人探究之路(七)添加中间件、自定义中间件

说在前面 官方已经自己实现了很多中间件&#xff0c;我们可以方便的直接使用&#xff0c;不用重复造轮子了 开启方式可以看官方文档 中间件 | go-zero Documentation 实现自定义的中间件 在业务逻辑中&#xff0c;我们需要实现自定义功能的中间件 ------这里我们以实现跨源…

Typescript的类型推导与联合类型

考虑以下 TypeScript 代码片段&#xff1a; function processInput(input: string | number): void {if (typeof input "string") {console.log(Input is a string: ${input.toUpperCase()});} else if (typeof input "number") {console.log(Input is …

Spring+SprinMVC+MyBatis配置方式简易模板

SpringSprinMVCMyBatis配置方式简易模板代码Demo GitHub访问 ssm-tpl-cfg 一、SQL数据准备 创建数据库test&#xff0c;执行下方SQL创建表ssm-tpl-cfg /*Navicat Premium Data TransferSource Server : 127.0.0.1Source Server Type : MySQLSource Server Versio…

Linux ---- 小玩具

目录 一、安装&#xff1a; 1、佛祖保佑&#xff0c;永不宕机&#xff0c;永无bug 2、小火车 3、艺术字和其它 天气预报 艺术字 4、会说话的小牦牛 5、其他趣味图片 我爱你 腻害 英雄联盟 帅 忍 龙 你是猪 福 好运连连 欢迎 加油 想你 忘不了你 我错了 你…

细说JavaScript事件处理(JavaScript事件处理详解)

js语言的一个特色和就是它的动态性&#xff0c;即一时间驱动的方式对用户输入作出反应而不需要依赖服务器端程序。事件是指人机交互的结果&#xff0c;如鼠标移动、点击按钮、在表单中输入数据或载入新的Web洁面等。 一、什么是事件 1、事件类型 1.1、事件源 1.2、事件处理…

Node.js Stream.pipeline() Method

Why Stream.pipeline 通过流我们可以将一大块数据拆分为一小部分一点一点的流动起来&#xff0c;而无需一次性全部读入&#xff0c;在 Linux 下我们可以通过 | 符号实现&#xff0c;类似的在 Nodejs 的 Stream 模块中同样也为我们提供了 pipe() 方法来实现。 未使用 Stream p…

Java开发安全之:Unreleased Resource: Streams需确保流得到释放

Overview java 中的函数 getResponseBytes() 有时无法成功释放由 getInputStream() 函数分配的系统资源。 Details 程序可能无法成功释放某一项系统资源。 在这种情况下&#xff0c;在某些程序路径上&#xff0c;所分配的资源未释放。 资源泄露至少有两种常见的原因&#xf…

Pyro —— Understanding how pyro works

目录 Simulation fields Inside the Pyro Solver Colliders Pressure projection Simulation fields Pyro是纯体积流体解算器&#xff0c;表示流体状态的数据存于各种标量场和矢量场&#xff1b;Smoke Object会创建这些场&#xff0c;且能可视化这些场&#xff1b; vel场&…

【JavaEE】网络原理:网络中的一些基本概念

目录 1. 网络通信基础 1.1 IP地址 1.2 端口号 1.3 认识协议 1.4 五元组 1.5 协议分层 什么是协议分层 分层的作用 OSI七层模型 TCP/IP五层&#xff08;或四层&#xff09;模型 网络设备所在分层 网络分层对应 封装和分用 1. 网络通信基础 1.1 IP地址 概念:IP地址…

Java设计模式之工厂方法模式详解

Java设计模式之工厂方法模式详解 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在今天的篇章中&#xff0c;我们将深入探讨Java设计模式中的一种魔法&#xff0c;那…

C语言/c++指针详细讲解【超详细】【由浅入深】

指针用法简单介绍 指针&#xff0c;是内存单元的编号。 内存条分好多好多小单元&#xff0c;一个小单元有 8 位&#xff0c;可以存放 8 个 0 或 1&#xff1b;也就是说&#xff0c;内存的编号不是以位算的&#xff0c;而是以字节算的&#xff0c;不是一个 0 或 1 是一个编号&…

函数 - JS

基本语法 function 关键字&#xff1b;函数名&#xff0c;应简明扼要且具有描述性&#xff0c;没有函数名就是匿名函数&#xff1b;参数列表&#xff0c;个数≥0&#xff0c;小括号不能省略&#xff1b;函数体。 /* 基本语法 */ function 函数名(参数) { 函数体 }声明与调用 …

立体视觉几何(一)

1.什么是立体视觉几何 立体视觉对应重建&#xff1a; • 对应&#xff1a;给定一幅图像中的点pl&#xff0c;找到另一幅图像中的对应点pr。 • 重建&#xff1a;给定对应关系(pl, pr)&#xff0c;计算空间中相应点的3D 坐标P。 立体视觉&#xff1a;从图像中的投影恢复场景中点…

list下

文章目录 注意&#xff1a;const迭代器怎么写&#xff1f;运用场合&#xff1f; inserterase析构函数赋值和拷贝构造区别&#xff1f;拷贝构造不能写那个swap,为什么&#xff1f;拷贝构造代码 面试问题什么是迭代器失效&#xff1f;vector、list的区别&#xff1f; 完整代码 注…

React16源码: React中的reconcileChildIterator和reconcileChildrenArray的源码实现

reconcileChildIterator 和 reconcileChildrenArray 1 &#xff09;概述 在react更新某一个节点的时候&#xff0c;要根据这个节点&#xff0c;它的类型去获取它的children比如说如果是 Function Component&#xff0c;它要调用这个 component 计算出它的return的属性return的…