Wireshark 如何按动态字段名进行过滤

我有一个协议,其中数据负载在结构化数组中。例子:

DataBlock 1:
   name: xxx
   city: xxx
   origin: xxx
DataBlock 2:
   name: xxx
   city: xxx
   origin: xxx
DataBlock 3:
   name: xxx
   city: xxx
   origin: xxx

而且这都在一个名为ServerBlocks的协议的一个帧内。

我的wireshark筛选器来查找所有的ServerBlocks是

ServerBlocks

在DataBlock 3中查找名称的筛选器是...

ServerBlocks.3.name

问题是我想对该字段应用通配符。我需要这样做,因为我不知道name == 'John'的索引号是多少。

我要找的是:

ServerBlocks.*.name == 'John'

每个ServerBlocks帧中的数组的大小可能不同,因此我永远不会知道要过滤的索引数。John可以是索引1或索引X,但我只想在ServerBlocks上应用一个显示过滤器,其中一个DataBlock具有名称== 'John'。

我在以下地方查找过: https://wiki.wireshark.org/DisplayFilters and https://www.wireshark.org/docs/wsug_html_chunked/ChWorkBuildDisplayFilterSection.html

但没有找到可以帮助我的东西。

FYI: 我能够更改Lua定义的ProtoField,使得数组索引不必在字段中间,而可以在末尾或开头...例子:

ServerBlocks.name.1

1.ServerBlocks.name

但即使有这种灵活性,我仍然不确定如何正确地过滤,以便我可以找到name == John的位置,而不知道确切的索引。

点赞
用户2755698
用户2755698

我建议取消字段名称的索引,而直接为它们使用一个公共过滤器。如果“ServerBlocks”代表所有块,你应该为每个块创建一个可折叠树形结构,并使用摘要行为每个块提供概述信息,这样你就不需要展开树形结构就可以很容易地查看它包含的信息。通过这种方式,你可以在任何块中过滤名称。

因此,你应该有类似以下的显示方式,而不是现在所展示的块:

[+] DataBlocks:3 块

如果你展开该树,你会看到以下内容:

[-] DataBlocks:3 
    [+] DataBlock 1: name1, city1, origin1
    [+] DataBlock 2: name2, city2, origin2
    [+] DataBlock 3: name3, city3, origin3

当然,如果展开一个特定的 DataBlock,你将以你提供的方式看到各个详细信息。

为了过滤特定的名称,你可以使用 myproto.datablocks.datablock.name == foo 这样的过滤器。它将匹配所有名称为 foo 的数据包,而不管它们在哪个 datablock 中。

那么,在仍然使用相同的过滤器名称的情况下,如何为每个块应用枚举?首先,你需要预先知道有多少块,或者可能需要通过数据不断循环,直到耗尽字节。这完全取决于协议和编码方式。这里,我假设你有一种方式可以确定有多少块,然后下面的伪代码可能对你有所帮助:

blocks_tree = myproto_tree:add(datablocks, tvbuf(offset, datablocks_len))

for i = 1, numblocks do
    datablock_len = TODO
    block_tree = blocks_tree:add(datablock, tvbuf(offset, datablock_len):set_text(
        string.format("DataBlock %d: ", i)

    block_tree:add(datablock_name, tvbuf(offset, namelen))
    block_tree:append_text(tvbuf(offset, namelen):string() .. ", ")

    block_tree:add(datablock_city, tvbuf(offset + namelen, citylen))
    block_tree:append_text(tvbuf(offset + namelen, citylen):string() .. ", ")

    block_tree:add(datablock_origin, tvbuf(offset + namelen + citylen, originlen))
    block_tree:append_text(tvbuf(offset + namelen + citylen, originlen):string())

    offset = offset + namelen + citylen + originlen
end

如果你事先不知道 datablocks_len,你可以稍后使用 blocks_tree:set_len(somelen),一旦你确定其长度时就可以这样做。我还假设名称、城市和来源都是字符串,并且你知道如何确定每个字符串的长度(即 namelen、citylen 和 originlen)。

有关更多信息,请参阅 Wireshark Lua 和相关 wiki 页面,包括一些可能对你在这里使用的示例脚本。同时也别忘了《Wireshark Lua API 参考手册》(Wireshark’s Lua API Reference Manual)。

2019-11-13 16:07:25