Lua wireshark解析器以OLE自动化格式提取时间戳

Lua wireshark解析器以OLE自动化格式提取时间戳,lua,wireshark-dissector,ole-automation,Lua,Wireshark Dissector,Ole Automation,参考: 我正在用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方法实现的,该方法运行良好 这是我的简化剖析器,它“解码”一条仅由时间戳组成的8字节消息: local logger_proto = Proto("logger", "

参考:

我正在用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方法实现的,该方法运行良好

这是我的简化剖析器,它“解码”一条仅由时间戳组成的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
在测试包中,我发送了两次时间戳,第二次是以相反的顺序发送字节,以测试endian问题的“抓住稻草”方法。分组数据是:

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
“正确”的时间戳应为

Feb 10, 2020 21:48:13 UTC
它看起来像ProtoField.absolute_time with base.UTC,这不是我想要的。所以我的问题是

是否有一个ProtoField选项以排除小数秒的格式正确提取此时间戳? 如果没有,我将如何提取日期/时间字节,并手动计算正确的日期格式?
我不得不学习一些关于OLE日期的知识,但在网站上找到了相关信息。我还使用了来自问题的信息以及来自的信息,为您提供了一个可能的解决方案。我怀疑这是否是一个最佳方案,但根据提供的数据,它似乎是可行的。希望它对你有用,但如果不行,它应该会让你更接近一个解决方案

一个长期的解决方案是,如果Wireshark可以为OLE日期提供本机支持,为此,我建议提交一个Wireshark增强,请求这样做

出于说明目的,可能的解决方案包括一些额外的内容:

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) 我相信这是可以清理/优化的,但我把它作为练习留给读者。使用以下手工制作的数据包进行测试:

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 time: 18302.9084853935 Days: 18302 Partial: 78493.1380001362 OLE Abs time: Feb 10, 2020 21:48:13.000000000 UTC
您可以使用将其转换为pcap文件进行测试。例如:text2pcap-a logger.txt logger.pcap。。。其中logger.txt是一个文本文件,包含粘贴在上面的原始数据包字节。

因此答案是将计算出的“nstime”传递给ProtoField.absolute_time字段。我完全错过了到UNIX格式的转换。如果没有本地Wireshark或LUA对OLE日期的支持,这是最好的解决方案,而且在实践中也可以使用。谢谢