1. Lua简介
Lua是一种轻量级的脚本语言,解释执行,不需要编译器之类的。 Lua的基本语法可以参考 官网 或者 菜鸟教程。
Wireshark内置了对Lua脚本的支持,可以直接编写Lua脚本,无需配置额外的环境,使用起来还是非常方便的。 [Wireshark Developer's Guide]里的第10章和第11章都是关于Lua支持的文档,有需要的话可以详细查阅。
2. Wireshark Lua插件基本结构
Wireshark Lua插件主要包括Dissector和DissectorTable两个重要概念:
- Dissector(解剖器): 用于解析特定协议的类,我们需要编写的主要是这一部分。
- DissectorTable(解剖器表): 用于组织不同解析器,使Wireshark能够根据协议选择合适的解析器。
3. 编写Lua插件实例
本周简单写了一段lua脚本并再wireshark里启用。对于课设任务要求,小组仍在多加努力,争取赶上任务要求进度
do
-- 定义协议名称和描述
local myProtocol = Proto("MyProtocol", "Custom Protocol")
-- 定义协议字段
local f_field1 = ProtoField.uint8("MyProtocol.field1", "Field 1", base.HEX)
local f_field2 = ProtoField.uint16("MyProtocol.field2", "Field 2", base.HEX)
-- 将字段添加到协议
myProtocol.fields = {f_field1, f_field2}
-- 获取data解析器
local data_dissector = Dissector.get("data")
-- 解析器函数
local function myProtocol_dissector(buf, pkt, root)
local buf_len = buf:len()
-- 根据协议报文格式判断是否为自定义协议
if buf_len < 3 or buf(0, 1):uint() ~= 0xAA then
-- 不是自定义协议,调用data解析器
return data_dissector:call(buf, pkt, root)
end
-- 提取字段值
local field1_value = buf(1, 1):uint()
local field2_value = buf(2, 2):uint()
-- 在Packet Details窗口显示协议信息
local tree = root:add(myProtocol, buf)
tree:add(f_field1, buf(1, 1)):append_text(", Field 1: " .. field1_value)
tree:add(f_field2, buf(2, 2)):append_text(", Field 2: " .. field2_value)
-- 设置Packet List窗口的协议列
pkt.cols.protocol = "MyProtocol"
-- 返回true表示成功解析
return true
end
-- 将解析器函数注册到协议解析器
function myProtocol.dissector(buf, pkt, root)
myProtocol_dissector(buf, pkt, root)
end
-- 将协议解析器添加到udp.port解析器表,监听特定端口
local udp_table = DissectorTable.get("udp.port")
udp_table:add(12345, myProtocol)
end
4. 启用Lua插件
- 将上述代码保存为lua文件,例如
my_protocol.lua
。 - 打开Wireshark,选择菜单【文件】-【全局配置文件夹】,找到
init.lua
文件。 - 在
init.lua
文件末尾添加以下内容:
dofile("path/to/my_protocol.lua")
将路径替换为实际文件路径。
想要启用Lua插件,首先要确认你的Wireshark版本是支持Lua的(Windows版本默认应该都是启用支持了的)。可以通过【帮助】-【关于】窗口确认:
- 重新启动Wireshark或选择【分析】-【重新载入Lua插件】。
5. 调试和测试
- 抓取包含自定义协议的数据包。
- 在Wireshark中查看Packet List,应该能够看到协议列显示为"MyProtocol"。
- 选择数据包,查看Packet Details,应该显示解析后的协议字段信息。
6. 高级功能
如果自定义协议中包含嵌套的协议(例如以太网、IP等),可以在解析器函数中调用其他解析器。示例代码已提供如何在解析器函数中调用以太网解析器。