关于网络编程:在lua wireshk解剖器中重新组装PDU

Reassemble PDUs in lua wireshark dissector

在系统中,我有一个自定义协议,我想实现一个Wireshark解剖器,以便可以使用Wireshark分析通信。

  • 对象是通过协议发送的,我们称之为"消息"。每个消息可能很大,可能高达100 MB,也可能很小,例如50字节。

  • 每条消息被分成大约1 kB的块,并用序列号和Guid消息ID进行标记,这些消息可在另一端用于重组消息。

到目前为止,我已经成功地创建了一个解剖器,该解剖器将所有块分别记录到Wireshark中,但是我想进一步介绍一下,并且还将所有消息(大块组装成消息)记录到Wireshark中。能做到吗?如何做到?是否有可能在我下面开发的解剖器之上实施解剖器?

如果可以在下面的分解器的顶部实现分解器,我如何确保它仅分析myproto PDU?下面的Dissector在特定的tcp端口上触发,但这不适用于第二阶段的Dissector ...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
myproto_proto = Proto("myproto","My Protocol")

function myproto_proto.dissector(buffer, pinfo, tree)
    pinfo.cols.protocol ="myproto"

    local message_length = buffer(0, 4):le_uint()+4

    if message_length>pinfo.len then
        pinfo.desegment_len = message_length
        pinfo.desegment_offset = 0
        return;
    end

    local subtree = tree:add(myproto_proto, buffer(),"My Protocol Data")
    local packet = subtree:add(buffer(0, message_length),"Chunk")
    packet:add(buffer(0, 4),"Packet length:" .. buffer(0, 4):le_uint())
    packet:add(buffer(32, 16),"Message ID")
    packet:add(buffer(48, 4),"Block ID:" .. buffer(48, 4):le_uint())
    packet:add(buffer(52, 4),"Max Block ID:" .. buffer(52, 4):le_uint())
    packet:add(buffer(68, message_length-68-20),"Data")

    pinfo.desegment_len = 0
    pinfo.desegment_offset = message_length
    return

end

tcp_table = DissectorTable.get("tcp.port")
tcp_table:add(1234, myproto_proto)


假设您创建了第二个解剖器msgproto。由于您似乎在块和消息之间没有任何多路复用,因此不需要设置解剖器表。相反,在myproto_proto.dissector的末尾执行

1
 msgproto.dissector:call(buffer(68, message_length-68-20):tvb, pinfo, tree)

这会将所有块数据传递给您的msgproto。在消息协议解析器中,您可以使用块协议的字段,当然也可以使用仅包含一个块数据的tvb。现在,您需要将这些块拼凑成一个非常巨大的电视。使msgproto具有状态:

1
2
3
4
 local stateMap = {}
 function msgproto.init()
     stateMap = {}
 end

将tvb转换为ByteArray,并与其他调用到解剖器的数组一起存储到stateMap中。将所有数据组合到一个数组中后,将其称为oarr,然后用它制作一个tvb:

1
2
3
    local otvb = ByteArray.tvb(oarr,"message data")
    -- starting from 0, need to pass a tvb range, not a tvb.
    stree:add(msgproto.fields.payload, otvb(0))

假设您具有类型为Protofield.bytespayload字段。此代码将在Wireshark窗口底部的常规"框架"窗格旁边显示一个名为"消息数据"的新数据窗格。

我不确定Wireshark是否会喜欢您的超大型缓冲区。除此之外,我非常相信上面概述的方法将行得通。我没有以这种确切的顺序使用所描述的技术,但是我已经使用了所描述的所有技术,例如制作一个新的字节窗格,其中填充了用纯Lua压缩的数据。