wireshark 用lua语言全面解析usb协议规则
捕获USB协议内容:
local usb_table_out = DissectorTable.get("usb.product")
捕获usb过滤协议,首先要得到解析器表,
解析器表的列表可以在 视图-->内部-->解析器表中查找对应要解析的预制表
这里,找到usb.product 、usb.control、usb.bulk、usb.interrupt等
usb.product 可以解析所有的usb包,
usb.control 解析usb传输控制包,
Usb.bulk 解析usb批量包,
Usb.interrupt 解析usb 中断传输包
如果用usb.product 那么就需要找到对应usb独有的端口号 以便添加并解析子协议
local my_port_out = 62128368
找到你想要解析的usb枚举协议,找到箭头所指的字节并转换为十进制, 添加端口号,
如果是usb.control Usb.bulk Usb.interrupt 则端口号填0xFF或0xFFFF
local my_proto_out = Proto("YiliOut", "YiliOut")
Proto(name, dec)
返回创建新的协议
name:在协议中的名字
Dec:描述协议的文字
usb_table_out:add(my_port_out, my_proto_out)
最后添加端口号 和新协议就添加了子协议 在usb.product
接下来只需要在中间添加解析协议的代码了
function my_proto_out.dissector(buffer, pinfo, tree)
do
pinfo.cols.protocol:set("YiliOut")
local offset = 0 ;
local leng = buffer:len();
local myProtoTree = tree:add(my_proto_out, buffer:range(offset))
local temp = buffer:range(offset, 1):le_uint()
my_proto_out 是新创建的子协议.dissector(buffer,pinfo,tree) 创建一个解析协议的函数,里面有三个参数
Buffer:缓冲区数据信息
Buffer 长度 :len() 获取
Pinfo:包的信息
Tree:能够包含更多的详细信息,tree是一个树节点,它可能是一个子树,或多个子树的兄弟或子树的子树等等
local myProtoTree = tree:add(my_proto_out, buffer:range(offset))
Tree:add 添加新的子树结构并返回子树名字
my_proto_out 新协议, buffer:range(offset)范围为空 offset缺省为0
local temp = buffer:range(offset, 1):le_uint()
将buffer数据中offset 表示起始位置, 1 表示偏移量代表几个字节,:le_uint()表示小端模式,uint()表示大端模式,将数据转化为无符号整形赋值给temp
direction = Field.new("usb.bmRequestType.direction")
stage = Field.new("usb.control_stage")
有的时候,buffer没有我们想要的信息,比如
Buffer只能从b8这里开始获取, 41获取不到,这时我们需要找到41这个字节的解析,上图表明了0x41 字节的解析, 我需要Direction这个数据, 可以在
视图-》内部-》支持的协议-》在usb寻找Direction,这里我们找到并向上图一样在函数外部定义这样的字段, 这样我们就能把这个信息提取出来
local transfer_stage = tonumber(tostring(stage()))
local transfer_type = tonumber(tostring(direction()))
再用上图方法变成数字进行匹配分析。
local versionField = ProtoField.uint8("bRequest", "请求号", base.HEX)
在函数外部定义
ProtoField 协议字段,添加子树项的时候使用
ProtoField:uint8(abbr, name,base,valuestring,mask)
创建一个无符号8位整形字段
Abbr:字段简写名字(过滤器中显示)
Name:字段真实名字(出现在树项中)
Base:Base.HEX, Base.DEC, Base.OCT, Base.UNIT_STRING, Base.NONE 其中一个
valueString:包含与值对
应的文本的表
Mask:整个字段的掩码, 只显示相应的位
返回:要添加到源字段树,子树的集合字段
versionField就是一个协议字段, 我们要把它添加到我们新协议的子项:
my_proto_out.fields = {versionField, idField, indexField, lengthField}
在函数外部 添加字段, 新协议.fields 添加子字段信息
local myProtoTree = tree:add(my_proto_out, buffer:range(offset))
myProtoTree:add(versionField, version)
myProtoTree:add(idField, protocol)
myProtoTree:add(indexField, index)
myProtoTree:add(lengthField,length)
myProto = myProtoTree:add(my_proto_buf, buffer:range(offset))
原本默认是没有树节点的 ,所以我们需要先用新协议创建一个树节点myProtoTree,再用myProtoTree:add方法添加新协议的树项的子树项字段
如果想在子树项再添加子树, 则直接将返回值引出来 就是子树的接口,就像上图的myProto 就是my_proto_buf子树的子树的接口,可以通过myProto:add继续添加子树
myProto 就是my_proto_buf子树的子树的接口,可以通过myProto:add继续添加子树
version = buffer:range(offset, 1):le_uint()
上面的version protocol index length 则是我的显示的数据range()第一个参数是数据起始位置, 第二个是偏移量,le_uint()小端无符号整形
local motorTableDirec = {[0]="反向",[1]="正向"}
local motorTableStop = {[0]="急停未触发",[1]="急停触发"}
local motorTableSlowStop = {[0]="缓停未触发",[1]="缓停触发"}
local motorTableStart = {[0]="未开始",[1]="开始"}
local motorDirec = ProtoField.uint8("motorDirec", "电机方向", base.HEX, motorTableDirec, 0x1)
local motorStop = ProtoField.uint8("motorStop", "电机急停", base.HEX, motorTableStop, 0x2)
local motorSlowStop = ProtoField.uint8("motorSlowStop", "电机缓停", base.HEX, motorTableSlowStop, 0x4)
local motorStart = ProtoField.uint8("motorStart", "电机开始", base.HEX, motorTableStart, 0x8)
上面的 motorTableDirec 、motorTableStop 就是valueString
Valuestring 会根据 motorDirec、motorStop子段的数据进行匹配 如果=0,则匹配到反向,=1 匹配正向
motorDirec 字段的最后一个0x1 就是mask 意思是显示哪一位,1就只显示第一位,2只显示第二位,0x4 只显示第四位
这里的反向, 就是匹配上了掩码的数值,就会显示对应内容,编写完后,在init.lua 最下面添加doFile(“......lua”) 你的文件名
version = buffer:range(offset, 1):le_uint()
上面的version protocol index length 则是我的显示的数据range()第一个参数是数据起始位置, 第二个是偏移量,le_uint()小端无符号整形
local motorTableDirec = {[0]="反向",[1]="正向"}
local motorTableStop = {[0]="急停未触发",[1]="急停触发"}
local motorTableSlowStop = {[0]="缓停未触发",[1]="缓停触发"}
local motorTableStart = {[0]="未开始",[1]="开始"}
local motorDirec = ProtoField.uint8("motorDirec", "电机方向", base.HEX, motorTableDirec, 0x1)
local motorStop = ProtoField.uint8("motorStop", "电机急停", base.HEX, motorTableStop, 0x2)
local motorSlowStop = ProtoField.uint8("motorSlowStop", "电机缓停", base.HEX, motorTableSlowStop, 0x4)
local motorStart = ProtoField.uint8("motorStart", "电机开始", base.HEX, motorTableStart, 0x8)
上面的 motorTableDirec 、motorTableStop 就是valueString
Valuestring 会根据 motorDirec、motorStop子段的数据进行匹配 如果=0,则匹配到反向,=1 匹配正向
motorDirec 字段的最后一个0x1 就是mask 意思是显示哪一位,1就只显示第一位,2只显示第二位,0x4 只显示第四位
这里的反向, 就是匹配上了掩码的数值,就会显示对应内容,编写完后,在init.lua 最下面添加doFile(“......lua”) 你的文件名