使用Lua编写Wireshark解析ProtoBuf插件

news2024/11/24 13:07:32

文章目录

  • Wireshark Protobuf Lua-dissector
    • Step 1: 获取 Wireshark
    • Step 2: 配置ProtoBuf相关设置
      • 添加ProtoBuf查找路径
    • Step 3 运行和调试Lua代码
      • 1. 添加Lua脚本
      • 2. 运行和调试
    • Step 4: 写Lua Dissector代码 :)
    • Step 5(Optional): Decode As
    • Github工程地址

Wireshark Protobuf Lua-dissector

最近工作中遇到需要Wireshark抓包排查项目网络库的问题,并且需要用ProtoBuf协议解析抓到的二进制数据。网络上查了一圈都没有找到简单明了的教程能让我快速上手的,就搞了这个教程,帮自己纪录的同时也希望能帮到遇到同样问题的你。

这个教程专注于帮你写Lua插件帮你解析Wireshark中的ProtoBuf包,请确保已经掌握基础的Wireshark使用方法。如果还没掌握,网上有很多教学,很快就可以上手了!

Step 1: 获取 Wireshark

直接从 官网 下载。

Step 2: 配置ProtoBuf相关设置

添加ProtoBuf查找路径

顾名思义,告诉Wireshark去哪里查询你的.proto文件。我把我的所有(其实就一个).proto文件都放到了同一个文件夹里,然后添加到Wireshark里即可。

在版本 4.2.3中, 你可以通过一下方法配置ProtoBuf查找路径:

Edit -> Preferences,接着在左侧菜单中找到并展开Protocols标签,然后找到Protobuf并打开对应页面,就会得到以下的界面:

添加Proto文件路径

然后点击 “Protobuf search paths” 旁边的Edit按钮打开新窗口:

设置Proto文件路径

我把所有.proto文件都放一起了,也没有其他外部引用,所以我只添加了一个文件夹路径就OK啦。

Step 3 运行和调试Lua代码

1. 添加Lua脚本

创建并将我们自己写的Lua脚本放到指定文件夹中,Wireshark才能识别到我们的Lua脚本:

Help -> About Wireshark

插件路径

点击Folder页签,双击Personal Lua Plugins路径打开文件夹,并将我们写好的脚本放入其中。

为了测试方便,我们现在只需要写一行简单的打印即可:

print("Hello World")

2. 运行和调试

成功将Lua脚本放到对应文件夹后,Wireshark会在每次启动的时候都运行一下你的脚本。你可以打开Lua控制台窗口看看脚本运行的结果。

打开控制台很简单,点击 Tools -> Lua Console

在这里插入图片描述

上半部分的文本输入框是可以实时输入并且运行的Lua代码,我们这里用不到先不管它。重点放在下半部的输出窗口,可以看到我们脚本运行的结果已经打印出来了。

不过我们不希望每次改了代码还要重新运行Wireshark怎么办呢?Wireshark提供了重载Lua脚本的功能,可以在 Analysis -> Reload Lua Plugins 中找到,或者直接点击快捷键 Ctrl+Shift+L

需要注意的是,重载Lua脚本之后,Wireshark会在已经捕获的每个包上重新跑一遍我们的Lua脚本。如果你此时已经捕获了大量的包,那么重载可能会消耗不少的时间。

Step 4: 写Lua Dissector代码 😃

到这步为止,所有的配置都已经完成,只需用Lua实现我们的ProtoBuf Dissector即可。

在我们写之前还有一些很有用的参考资料:

  1. Wireshark有Lua APIs的文档在这里。

  2. 还有两个很好的简单教程在这里和那里。

以下的代码示例是在我综合了上面的内容之后,摘掉非必要的代码而实现的一个极简的Lua Dissector。不过也存在过于精简而不符合实际运用的需要,这个就需要使用者根据自己的实际需求和协议设计去修改代码了。

--获取Wireshark库里现成的ProtoBuf解析器
local protobuf_dissector = Dissector.get("protobuf");

--Proto类可以拿来实现自己的解析器
--不过我这里只用来帮我注册上Wireshark的回调
--然后需要实际解析ProtoBuf的时候,我会调用上面获取到的官方解析器
--@param myProto 名字
--@param "My Proto" 描述
local my_proto = Proto("MyProto", "My Proto");

---Wireshark会在每个包上调用这个预设函数
---@param tvb table 一个辅助操作读取到的二进制流的类对象
---@param pinfo table 储存了包体信息的类对象
---@param tree table GUI上展示信息用的根节点
-- 我的数据流会截取到的数据格式如下:(因项目而异)
-- [Header][Message Data]
-- Header: [2 bytes length]
my_proto.dissector = function(tvb, pinfo, tree)
    if tvb:captured_len() == 0 then return end;
    if pinfo.port_type == 2 then --TCP
        pinfo.columns.columns.protocol:set(my_proto.name);
        --创建一个新的UI节点来展示我们ProtoBuf解析的数据,当然也可以不创建新节点,直接展示在tree上
        local subtree = tree:add(my_proto, tvb());
        local offset = 0;
        local length = tvb(0, 2):le_uint(); --[2 bytes length]
        local data_len = length - 2; --计算实际的数据长度
        offset = offset + 2;
        --这行很关键,官方的解析器会根据这个字段去.proto文件里找对应的协议去解析
        pinfo.private["pb_msg_type"] = "message,myProto.Message";
        pcall(Dissector.call, protobuf_dissector, tvb(offset, data_len), pinfo, subtree);
    end
end

--将我的Proto类对象注册到TCP端口上
--要注意的是,当你还不清楚实际发生的端口号时,先填0,后续再配置即可(具体配置方法看下一部分"Decode As")
DissectorTable.get("tcp.port"):add(0, my_proto);

Step 5(Optional): Decode As

当你需要动态调整Tcp端口时,可以在以下的菜单中手动配置:

Analyze -> Decode As

手动绑定端口

点击"+"号添加新的一行,字段选"TCP port"然后填入实际端口号,最后在Current下拉框中,找到我们刚刚添加的"MYPROTO"解析器后单击选择。

最后点击保存就配置完成啦!

PS:如果你的代码无误,又看不到你的解析器,请检查一下你是不是没有重载Lua代码。

Github工程地址

源码和教程我都有上传到Github,有需要的同学可以自行上去取源码
https://github.com/Kayn-Liu/WiresharkProtoBufDissectorLua.git

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

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

相关文章

YOLOv8训练好模型后,追加轮数继续训练、或者提前终止训练,缩减训练轮数

一、前言 而且此教程适用的情况是你已经训练好了此模型,想继续追加一些轮数。比如训练进度是120/120,已经完成了,继续追加10轮,或者你原先定的是200轮,希望缩减到150轮,可以使用我说的这个方法。为什么缩减…

【C语言】最大公约数

给定两个数&#xff0c;求这两个数的最大公约数 方法&#xff1a;辗转相除法 例&#xff1a;36与24的最小公约数 36/241...12 24/122...0 那么12就是36与24的最大公约数。 代码如下&#xff1a; #include <stdio.h> int main() { int a 0; int b 0; scan…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:RowSplit)

将子组件横向布局&#xff0c;并在每个子组件之间插入一根纵向的分割线。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含子组件。 RowSplit通过分割线限制子组件的宽度。初始化…

FPGA和ASIC

前言 大家好&#xff0c;我是jiantaoyab&#xff0c;这是我所总结作为学习的笔记第16篇,在本篇文章给大家介绍FPGA和ASIC。 一个四核i7的CPU的晶体管中有20亿的晶体管&#xff0c;需要链接起20亿的晶体管可不是一件容易的事情&#xff0c;所以设计一个CPU需要用年来算&#x…

挑战杯 机器视觉的试卷批改系统 - opencv python 视觉识别

文章目录 0 简介1 项目背景2 项目目的3 系统设计3.1 目标对象3.2 系统架构3.3 软件设计方案 4 图像预处理4.1 灰度二值化4.2 形态学处理4.3 算式提取4.4 倾斜校正4.5 字符分割 5 字符识别5.1 支持向量机原理5.2 基于SVM的字符识别5.3 SVM算法实现 6 算法测试7 系统实现8 最后 0…

第七课-----分支切平面

割平面方法的基本思想是对于一个优化问题而言&#xff0c;通过不断添加约束条件来切割可行域&#xff0c; 最终将可行域不断变小&#xff0c;相当于搜索空间变小。在LP中讲过&#xff0c;一个等式约束就等价于一个超平面&#xff0c;一个不等式约束就代表一个半空间&#xff0c…

17.搜索二维矩阵Ⅱ

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,2…

2.26回顾章节主体线索脉络,课程要求(评分)

3)翻译程序、汇编程序、编译程序、解释程序有什么差别&#xff1f;各自的特性是什么&#xff1f; 翻译程序是指把高级语言源程序翻译成机器语言程序&#xff08;目标代码&#xff09;的软件。 翻译程序有两种&#xff1a;一种是编译程序&#xff0c;它将高级语言源程序一次全部…

lua脚本的基础内容

官方地址&#xff1a;http://luajit.org/ 官方wiki地址&#xff1a;http://wiki.luajit.org/Home 推荐书籍&#xff1a; OpenResty 最佳实践&#xff1a;https://moonbingbing.gitbooks.io/openresty-best-practices/content/ lua基础文档&#xff1a;https://www.runoob.com/l…

mac电脑修改终端zsh显示的用户名

电脑名称一直没有修改&#xff0c;所以电脑名称都是Apple的MacBook Pro&#xff0c;如下图所示&#xff1a; mac电脑终端显示用户名太长一点也不美观&#xff0c;而且占用很长的行&#xff0c;浪费空间&#xff0c;可以通过修改来调整要显示什么内容&#xff1a; 方式一 要想换…

解决Linux中Eclipse启动时找不到Java环境的问题

按照报错的意思是没有在/usr/local/eclipse/jre/bin/java下找到java环境&#xff0c;我检查了一下eclipse的目录结构发现在/usr/local/eclipse没有jre/bin/java&#xff0c;我的想法是自己建对应文件夹然后软连接到我的java环境 cd /usr/local/eclipse sudo mkdir jre cd jre s…

Java中为什么只有值传递?

Java中为什么只有值传递&#xff1f; 对于对象参数而言&#xff0c;实际参数传递给形式参数的只是一个内存地址&#xff0c;让形式参数也指向实际参数所指向的地址&#xff0c;传递的值的内容是对象的引用。 为什么会是这样&#xff1f;让我慢慢为你讲解。 对于Java的传递类…

自定义协议

应用层 有许多现成的协议(HTTP协议做网站必备),也有许多需要程序员自定义的协议. 1.自定义协议 自定义协议: 1.明确传递的信息是什么 2.约定好信息按照什么样的格式来组织成二进制字符串 举个例子: 当我们点外卖时,打开软件,会显示商家列表,列表中有很多项,每一项都包含了一…

波奇学Linux:线程安全和自选锁和读写锁

STL不是线程安全的 单例模式的线程安全 自选锁&#xff1a;当线程申请锁失败时&#xff0c;不是挂起&#xff0c;而是一直申请 挂起等待锁 &#xff1a;当线程申请锁失败时&#xff0c;把锁挂起 一般临界区时间短的适合自选锁&#xff0c;长的适合挂起等待锁

前后端分离:现代Web开发的协作模式

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

android中单例模式为什么会引起内存泄漏?

单例模式使用不恰当会造成内存泄漏。因为单例的静态特性使得单例的生命周期和应用的生命周期一样长&#xff0c; 如果一个对象已经不需要使用了&#xff0c;但是单例对象还持有该对象的引用&#xff0c;那么这个对象就不能被正常回收&#xff0c;因此会导致内存泄漏。 举个例子…

MySQL语法分类 DDL(1)

DDL&#xff08;1&#xff09;(操作数据库、表) 数据库操作(CRUD) C(Create):创建 //指定字符集创建 create database db_1 character set utf8;//避免重复创建数据库报错可以用一下命令 create database if not exists db_1 character set utf8;R(Retrieve):查询 //查询所…

PostMan测试文件上传

后端代码 package com.example.backend.controller;import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; import com.example.backend.common.Result; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import org…

19. UE5 RPG使用GameplayEffect的Attribute Based Modifiers

前几篇文章我也说了GE的基础使用&#xff0c;但是&#xff0c;对一些属性的应用没有述说&#xff0c;后续&#xff0c;我将一点一点的将它们如何使用书写下来。 这一篇&#xff0c;主要就讲解一下Attribute Based Modifiers使用&#xff0c;先说一下它的应用场景&#xff0c;一…

使用Laravel安装器创建项目

使用Laravel安装器创建项目&#xff0c;使用Laravel安装器创建前先确保你的机器上已经下载了Laravel安装程序&#xff0c;可以通过终端界面查询是否下载了Laravel安装器&#xff0c;在终端中输入Laravel 查询&#xff0c;如下图所示则已下载Laravel安装程序&#xff0c;&#x…