【问题标题】:Reassemble PDUs in lua wireshark dissector在 lua wireshark 解剖器中重新组装 PDU
【发布时间】:2014-10-09 03:22:31
【问题描述】:

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

  • 对象通过协议发送,我们称它们为“消息”。每条消息可以很大,可能高达 100 MB,也可以非常小,例如 50 字节。

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

到目前为止,我已经成功制作了一个解析器,它可以将所有块单独记录到 Wireshark,但我想更进一步,并将所有消息(组合成消息的块)记录在 Wireshark 中。这可以做到吗?怎么做?是否有可能在我下面开发的解析器之上实现解析器?

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

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)

【问题讨论】:

  • 不幸的是,上次我检查(几年前),不可能在 Lua 中制作“链式解剖器”。您可以使用 C API 来做到这一点,这些 API 非常难以使用,但确实提供了类似这样的额外功能。
  • 请注意,如果可以使用 C API 完成,则可能可以从 Lua 脚本中挂钩该功能,尽管那样它不会是纯链接,而是“解析器扩展” ?
  • @JohnZwinck 有趣的是,在谷歌上搜索 Chained Dissectors 后,我发现了这个:wiki.wireshark.org/Lua/Dissectors。你认为这会为我解决问题吗?
  • @www.jensolsson.se:我不能肯定地说,但我也看过那个页面并且无法让我的用例正常工作。我只能说祝你好运,如果你真的必须考虑使用 C。

标签: lua network-programming network-protocols wireshark-dissector


【解决方案1】:

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

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

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

 local stateMap = {}
 function msgproto.init()
     stateMap = {}
 end

将您的 tvb 转换为 ByteArray 并存储到 stateMap 以及来自其他调用解析器的数组。当您将所有数据组装到一个数组中后,我们称它为oarr,用它制作一个 tvb:

    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))

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

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

【讨论】:

    猜你喜欢
    • 2012-05-11
    • 2017-09-07
    • 2016-12-02
    • 1970-01-01
    • 2013-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多