用于解析的帧的 Lua 长度

问题描述

如果我在记事本中打开它,我有一个二进制文件,里面会显示乱码信息。 我正在开发一个与wireshark一起使用的插件

所以我的问题是我需要帮助。我正在读取文件,需要在文件中找到 'V' '0' '0' '1' (0x56 0x30 0x30 0x31),因为它是标头的开头,意味着里面有一个数据包。我需要对整个文件执行此操作,例如解析。也应该以 V 0 0 1 开始 Frame 而不是以它结束。 我目前有一个代码,我正在搜索 0x7E 并解析它。我需要的是框架的长度。例如,找到了 V 0 0 1,因此从 V 到文件中下一个 V 0 0 1 之前的位置的长度。这样我就可以处理长度并将其添加到捕获的长度以获得位置,wireshark 可以使用。

例如我使用 0x7E 的不完美代码

local line = file:read()
local len = 0

for c in (line or ''):gmatch ('.') do
    len = len + 1
    if c:byte() == 0x7E then
        break
    end
    
end

if not line then 
    return false 
end

frame.captured_length = len

这也是 Frame 以 7E 结尾的问题,这是错误的。我需要一些完美适用于“V”“0”“0”“1”的东西。也许我需要使用string.find? 请帮帮我!

这是我的文件在 Visual Studio Code 中使用十六进制编辑器时的样子的示例。

enter image description here

解决方法

Lua 有一些简洁的模式工具。总结如下:

  • (...) 导出 () 中所有捕获的文本并将其提供给我们。
  • -,+,*,?,"尽可能少的可选匹配","尽可能多的强制匹配","尽可能多的可选匹配尽可能”、“可选只匹配一次”。
  • ^$:分别从根到文件的开始或结束。

我们将使用此通用输入和输出进行测试:

local output = {}
local input = "V001Packet1V001Packet2oooV001aaandweredonehere"

最简单的方法可能是递归拆分字符串,一个以“V”之前的字符结尾,另一个以“1”之后的字符开始。我们将使用一个模式来导出 V001 之前和之后的部分:

local this,next = string.match(input,"(.-)V001(.*)")
print(this,next)    --> "","Packet1V001Packet2..."

很简单。现在我们需要再做一次,我们还需要消除第一个空包,因为它是模式的一个怪癖。我们大概可以说不应该添加任何空的 this 字符串:

if this ~= "" then
    table.insert(output,this)
end

现在,最后一个数据包对于 thisnext 都将返回 nil,因为最后不会有另一个 V001。当模式不匹配时,我们可以通过简单地添加字符串的最后一部分来为此做好准备。

全部放在一起:

local function doStep(str)
    local this,next = string.match(str,"(.-)V001(.*)")
    print(this,next)

    if this then 
        --  There is still more packets left
        if this ~= "" then
            --  This is an empty packet
            table.insert(output,this)
        end

        if next ~= "" then
            --  There is more out there!
            doStep(next)
        end
    else
        --  We are the last survivor.
        table.insert(output,str)
    end
end

当然,这可以改进,但它应该是一个很好的起点。为了证明它有效,这个脚本:

doStep(input)
print(table.concat(output,"; "))

打印:

Packet1; Packet2ooo; aaandweredonehere