问题描述
如果我在记事本中打开它,我有一个二进制文件,里面会显示乱码信息。 我正在开发一个与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 中使用十六进制编辑器时的样子的示例。
解决方法
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
现在,最后一个数据包对于 this
和 next
都将返回 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