Lua wireshark 解析器以 OLE 自动化格式提取时间戳
Lua wireshark dissector extract timestamp in OLE automation format
参考:
我正在 LUA 中编写一个简单的 UDP 解析器来解码包含被编码为 OLE 自动化日期的时间戳的数据包。编码结果为 8 字节数据模式:
C2 F5 4F 12 FD 6B E5 40
解码为 43871.90848539352 = '2/10/2020 9:48:13 PM'。在 C# .NET 中,这是通过 DateTime.ToOADate() 方法(工作正常)。
这是我的简化解析器,其中 'decodes' 仅包含时间戳的 8 字节消息:
local logger_proto = Proto("logger", "LOGGER")
local logger_hdr={
atime = ProtoField.absolute_time("test.atime","test atime",base.UTC),
rtime = ProtoField.relative_time("test.rtime","test rtime",base.UTC),
}
logger_proto.fields=logger_hdr
function logger_proto.init() end
function logger_proto.dissector(tvbuf, pktinfo, root)
root:add(logger_hdr.atime,tvbuf:range(0,8))
root:add(logger_hdr.atime,tvbuf:range(8,8))
end
在测试数据包中,我发送了两次时间戳,第二次是使用相反顺序的字节来测试字节序问题('grasping at straws' 方法)。数据包数据为:
C2 F5 4F 12 FD 6B E5 40 40 E5 6B FD 12 4F F5 C2
检索到的两个时间戳是
Aug 25, 2073 03:14:26.-4360608 UTC
Jul 2, 2004 14:06:53.307230146 UTC
'correct' 时间戳应该是
Feb 10, 2020 21:48:13 UTC
看起来 ProtoField.absolute_time 和 base.UTC 并不是我想要的。所以我的问题是
- 是否有 ProtoField 选项可以以排除小数秒的格式正确提取此时间戳?
- 如果不是,我将如何按字节提取 date/time 并进行计算以手动格式化正确的日期?
我不得不学习一些关于 OLE 日期的知识,但在 DateTime.ToOADate Method. I also used information from the question as well as from Convert us-timestamp to absolute_time 找到了相关信息,为您提出了一个 可能的 解决方案。我怀疑它是否是最佳选择,但根据提供的数据,它 似乎 有效。希望它对你有用,但如果没有,它应该会让你更接近解决方案。
如果 Wireshark 可以提供对 OLE 日期的 本地 支持,那么一个长期的解决方案是,为了实现这一点,我建议提交 Wireshark 增强 bug report 请求这样的东西。
一个可能的解决方案(有一些额外的东西用于说明目的):
local p_logger = Proto("logger", "LOGGER")
local logger_hdr = {
-- Only the oletime_abs field is useful; the rest just help illustrate things
-- and helped me during debugging. Remove/rename as you see fit.
oletime = ProtoField.double("logger.oletime", "OLE time"),
-- Note: .int64 doesn't work so just using .int32
oletime_days = ProtoField.int32("logger.oletime.days", "Days"),
oletime_partial = ProtoField.double("logger.oletime.partial", "Partial"),
oletime_abs = ProtoField.absolute_time("logger.oleabstime", "OLE Abs time", base.UTC)
}
p_logger.fields = logger_hdr
function p_logger.dissector(tvbuf, pinfo, tree)
local logger_tree = tree:add(p_logger, tvbuf(0,-1))
local OLE_DIFF_TO_UNIX = 25569
local SECS_PER_DAY = 86400
local oletime = tvbuf:range(0, 8):le_float() - OLE_DIFF_TO_UNIX
local oletime_days = math.floor(oletime)
local oletime_partial = (oletime - oletime_days) * SECS_PER_DAY
local secs = oletime_days * SECS_PER_DAY + math.floor(oletime_partial)
local nstime = NSTime.new(secs, 0)
pinfo.cols.protocol:set("LOGGER")
logger_tree:add(logger_hdr.oletime, tvbuf:range(0, 8), oletime)
logger_tree:add(logger_hdr.oletime_days, tvbuf:range(0, 8), oletime_days)
logger_tree:add(logger_hdr.oletime_partial, tvbuf:range(0, 8), oletime_partial)
logger_tree:add(logger_hdr.oletime_abs, tvbuf:range(0, 8), nstime)
end
-- Register dissector (this particular registration is just for my testing)
local udp_table = DissectorTable.get("udp.port")
udp_table:add(33333, p_logger)
我确定这可以被清理 up/optimized,但我将其作为练习留给 reader。使用以下手工制作的数据包进行测试:
0000 00 0e b6 00 00 02 00 0e b6 00 00 01 08 00 45 00 ..............E.
0010 00 37 00 00 40 00 40 11 b5 ea c0 00 02 65 c0 00 .7..@.@......e..
0020 02 66 82 35 82 35 00 23 e8 54 c2 f5 4f 12 fd 6b .f.5.5.#.T..O..k
0030 e5 40 40 e5 6b fd 12 4f f5 c2 00 00 00 00 00 00 .@@.k..O........
0040 00 00 00 00 00 .....
... 你应该得到 "Logger" OLE 日期的以下解码:
LOGGER
OLE time: 18302.9084853935
Days: 18302
Partial: 78493.1380001362
OLE Abs time: Feb 10, 2020 21:48:13.000000000 UTC
您可以使用text2pcap
将其转换为pcap文件进行测试。例如:text2pcap -a logger.txt logger.pcap
... 其中 logger.txt
是包含上面粘贴的原始数据包字节的文本文件。
参考:
我正在 LUA 中编写一个简单的 UDP 解析器来解码包含被编码为 OLE 自动化日期的时间戳的数据包。编码结果为 8 字节数据模式:
C2 F5 4F 12 FD 6B E5 40
解码为 43871.90848539352 = '2/10/2020 9:48:13 PM'。在 C# .NET 中,这是通过 DateTime.ToOADate() 方法(工作正常)。
这是我的简化解析器,其中 'decodes' 仅包含时间戳的 8 字节消息:
local logger_proto = Proto("logger", "LOGGER")
local logger_hdr={
atime = ProtoField.absolute_time("test.atime","test atime",base.UTC),
rtime = ProtoField.relative_time("test.rtime","test rtime",base.UTC),
}
logger_proto.fields=logger_hdr
function logger_proto.init() end
function logger_proto.dissector(tvbuf, pktinfo, root)
root:add(logger_hdr.atime,tvbuf:range(0,8))
root:add(logger_hdr.atime,tvbuf:range(8,8))
end
在测试数据包中,我发送了两次时间戳,第二次是使用相反顺序的字节来测试字节序问题('grasping at straws' 方法)。数据包数据为:
C2 F5 4F 12 FD 6B E5 40 40 E5 6B FD 12 4F F5 C2
检索到的两个时间戳是
Aug 25, 2073 03:14:26.-4360608 UTC
Jul 2, 2004 14:06:53.307230146 UTC
'correct' 时间戳应该是
Feb 10, 2020 21:48:13 UTC
看起来 ProtoField.absolute_time 和 base.UTC 并不是我想要的。所以我的问题是
- 是否有 ProtoField 选项可以以排除小数秒的格式正确提取此时间戳?
- 如果不是,我将如何按字节提取 date/time 并进行计算以手动格式化正确的日期?
我不得不学习一些关于 OLE 日期的知识,但在 DateTime.ToOADate Method. I also used information from the
如果 Wireshark 可以提供对 OLE 日期的 本地 支持,那么一个长期的解决方案是,为了实现这一点,我建议提交 Wireshark 增强 bug report 请求这样的东西。
一个可能的解决方案(有一些额外的东西用于说明目的):
local p_logger = Proto("logger", "LOGGER") local logger_hdr = { -- Only the oletime_abs field is useful; the rest just help illustrate things -- and helped me during debugging. Remove/rename as you see fit. oletime = ProtoField.double("logger.oletime", "OLE time"), -- Note: .int64 doesn't work so just using .int32 oletime_days = ProtoField.int32("logger.oletime.days", "Days"), oletime_partial = ProtoField.double("logger.oletime.partial", "Partial"), oletime_abs = ProtoField.absolute_time("logger.oleabstime", "OLE Abs time", base.UTC) } p_logger.fields = logger_hdr function p_logger.dissector(tvbuf, pinfo, tree) local logger_tree = tree:add(p_logger, tvbuf(0,-1)) local OLE_DIFF_TO_UNIX = 25569 local SECS_PER_DAY = 86400 local oletime = tvbuf:range(0, 8):le_float() - OLE_DIFF_TO_UNIX local oletime_days = math.floor(oletime) local oletime_partial = (oletime - oletime_days) * SECS_PER_DAY local secs = oletime_days * SECS_PER_DAY + math.floor(oletime_partial) local nstime = NSTime.new(secs, 0) pinfo.cols.protocol:set("LOGGER") logger_tree:add(logger_hdr.oletime, tvbuf:range(0, 8), oletime) logger_tree:add(logger_hdr.oletime_days, tvbuf:range(0, 8), oletime_days) logger_tree:add(logger_hdr.oletime_partial, tvbuf:range(0, 8), oletime_partial) logger_tree:add(logger_hdr.oletime_abs, tvbuf:range(0, 8), nstime) end -- Register dissector (this particular registration is just for my testing) local udp_table = DissectorTable.get("udp.port") udp_table:add(33333, p_logger)
我确定这可以被清理 up/optimized,但我将其作为练习留给 reader。使用以下手工制作的数据包进行测试:
0000 00 0e b6 00 00 02 00 0e b6 00 00 01 08 00 45 00 ..............E. 0010 00 37 00 00 40 00 40 11 b5 ea c0 00 02 65 c0 00 .7..@.@......e.. 0020 02 66 82 35 82 35 00 23 e8 54 c2 f5 4f 12 fd 6b .f.5.5.#.T..O..k 0030 e5 40 40 e5 6b fd 12 4f f5 c2 00 00 00 00 00 00 .@@.k..O........ 0040 00 00 00 00 00 .....
... 你应该得到 "Logger" OLE 日期的以下解码:
LOGGER OLE time: 18302.9084853935 Days: 18302 Partial: 78493.1380001362 OLE Abs time: Feb 10, 2020 21:48:13.000000000 UTC
您可以使用text2pcap
将其转换为pcap文件进行测试。例如:text2pcap -a logger.txt logger.pcap
... 其中 logger.txt
是包含上面粘贴的原始数据包字节的文本文件。