我有一个现有的软件,没有资源和可能的编辑。它包含一个网格(看起来像旧的DevExpress网格,软件本身是在Delphi 7中创建的)。网格内容存储在内存中,我必须在外部进行读取和修改。

我成功地解码了结构,但日期和时间字段除外。它存储在8个字节中。我检查了所有常见的结构,例如TDateTime作为双变量,TTimeStamp作为两个整数,TFileTime,Windows OLE,MySQL时间戳,其他时间戳,但是没有发现任何紧密的相对关系。数据并检查表中的结果,因此我确定数据是正确的。

我提供了数据时间(以字节为单位)和结果以网格为单位的示例。如果有帮助,可以测试其他任何方法。

00 00 00 00 00 00 00 43 - 04.03.17840 11:03:41
00 00 00 00 00 00 00 41 - "0.131072 is not a valid timestamp"
00 00 00 00 00 00 00 42 - 09.04.001 10:05:34
00 00 00 00 00 00 67 42 - 15.01.0026 16:33:02
00 00 00 00 00 00 CB 42 - 22.06.1882 18:24:59
00 00 00 00 00 00 CC 42 - 28.02.1952 10:12:35
00 00 00 00 00 E4 CC 42 - 22.03.2014 07:24:02
00 00 00 00 00 E5 CC 42 - 29.06.2014 17:29:37
00 00 00 00 3D E5 CC 42 - 23.07.2014 10:03:17
00 95 1E 7E 3D E5 CC 42 - 23.07.2014 14:38:48
00 87 F9 7C 3D E5 CC 42 - 23.07.2014 14:36:18
00 4C 99 57 38 E5 CC 42 - 21.07.2014 14:38:26
80 55 0C 2E 3E E4 CC 42 - 15.04.2014 10:57:32


更新1:
评论中提到的年份中的奇怪差异导致发现,该日期是与前几个字节不严格线性关系。我已经测试过:

00 00 00 00   00 00 CA 42 - 16.10.1812
00 00 00 00   00 00 CB 42 - 22.06.1882
00 00 00 00   00 00 CC 42 - 28.02.1952


值之间的差异是〜70年(〜25452天) />
00 00 00 00   00 00 BA 42 - 23.11.0906
00 00 00 00   00 00 BB 42 - 26.09.0941
00 00 00 00   00 00 BC 42 - 30.07.0976


差异实际上是〜35年(〜12726天) />
00 00 00 00   00 00 BD 42 - 04.06.1011
00 00 00 00   00 00 BE 42 - 06.04.1046 (+35 years)
00 00 00 00   00 00 BF 42 - 07.02.1081 (+35 years)
...
00 00 00 00   00 00 C0 42 - 13.12.1115 (+35 years)
00 00 00 00   00 00 C1 42 - 19.08.1185 (+70 years)
00 00 00 00   00 00 C2 42 - 25.04.1255 (+70 years)
...
00 00 00 00   00 00 C8 42 - 02.06.1673 (+70 years)
00 00 00 00   00 00 C9 42 - 08.02.1743 (+70 years)
00 00 00 00   00 00 CA 42 - 16.10.1812 (+70 years)
...
00 00 00 00   00 00 CE 42 - 11.07.2091 (+70 years)
00 00 00 00   00 00 CF 42 - 18.03.2161 (+70 years)
...
00 00 00 00   00 00 D0 42 - 24.11.2230 (+70 years)
00 00 00 00   00 00 D1 42 - 07.04.2370 (+140 years)
00 00 00 00   00 00 D2 42 - 19.08.2509 (+140 years)


因此,看起来旧位有点像系数,而不是直接日期。 br />
00 00 00 00   00 00 CC 42 - 28.02.1952
00 00 00 00   00 01 CC 42 - 06.06.1952
00 00 00 00   00 02 CC 42 - 14.09.1952


〜100天

00 00 00 00   00 CC CC 42 - 09.09.2007
00 00 00 00   00 CD CC 42 - 17.12.2007
00 00 00 00   00 CE CC 42 - 26.03.2008


〜100天

00 00 00 00   00 FC CC 42 - 02.10.2020
00 00 00 00   00 FD CC 42 - 09.01.2021
00 00 00 00   00 FE CC 42 - 19.04.2021


〜100天

第四个字节:

00 00 00 00   00 CC CC 42 - 09.09.2007 05:10:12
00 00 00 00   01 CC CC 42 - 09.09.2007 14:29:26
00 00 00 00   02 CC CC 42 - 09.09.2007 23:48:26


〜9小时

>
00 00 00 00   CC CC CC 42 - 27.11.2007 10:35:16
00 00 00 00   CD CC CC 42 - 27.11.2007 19:54:30
00 00 00 00   CE CC CC 42 - 28.11.2007 05:13:45


〜9小时

关于+ 1m,+ 1h等故障的问题
由于我无法输入,因此很难测试随机日期并获取其代码,仅相反。
但是我可以手动添加值,并测试其内部结构。
这是我今天设法抓到的东西:

00 90 D2 80   4A E5 CC 42 - 28.07.2014 15:54:50
00 E3 D4 80   4A E5 CC 42 - 28.07.2014 15:54:51

80 5D 48 81   4A E5 CC 42 - 28.07.2014 15:55:50
80 5A 4B 81   4A E5 CC 42 - 28.07.2014 15:55:51

80 D4 49 9C   4A E5 CC 42 - 28.07.2014 16:54:50
00 8C 4C 9C   4A E5 CC 42 - 28.07.2014 16:54:51


评论

您能显示一次仅改变一秒钟/分钟/天/月/年的数据吗?

我怀疑您的某些价值观中有错别字。 CB 42和CC 42之间的差异约为70年,这意味着67 42和CB 42之间的差异(CBh-67h = 64h = 100d)应该约为7000年。

@ m0nhawk有点难,但是我在编辑后的帖子底部添加了信息。

@GuntramBlohm我进行了更新,似乎旧字节与日期不是线性的。

#1 楼

非线性是线索,它是浮点编码。如果您熟悉如何查看内存转储中的浮点值,则最高有效字节通常在0x3f-0x4f范围内,表示从3e-52e77的值是双精度的。在这种情况下,它是小端的。

00 4C 99 57 38 E5 CC 42 - 21.07.2014 14:38:26->解压到-> 63541636706968.0

换个方向,让我们检查该日期的标准编码。
UNIX time_t(自1970年以来的秒数)= 1405949906

这四个数量级太小了。不好;也许我们可以尝试自公元1年以来的秒数。假设现在每年365.2425天,并记住从1:开始的日期,月份和年份编号,则与解码后的数字相似,但相差约1000倍;编码值必须以毫秒为单位。预测不准确,我们大约要过1天。我们仍然应该测试它是否仍然可以在其他值上运行。我们必须检查我们的假设。我们在leap年使用的公历系统只能追溯到1582年,但是在此之前该系统的零位。我们必须猜测程序员是如何将其向后扩展到1AD的。

通过在程序中运行浮点零(所有零),可以找到零点。它应该显示程序员选择的确切日期时间来源。如果程序不接受零,则可以使用非常小的double值,例如DBL_MIN。您还必须检查该程序如何正确处理leap日,是否正确考虑了400年规则以及任何实现错误。

#2 楼

不查看前三行加上28.02.1952 10:12:3529.06.2014 17:29:3715.04.2014 10:57:32行,我得到以下信息:右边的值是1/128000秒,与UNIX时间戳的偏移量为4805619185047532800秒。因此,我们有了:

yourtime =  4805619185047532800 +128000 * unixtime


虽然看起来并不熟悉,但这意味着t=0-> 1187749 BC。

0x42t=0会是公元前10363年,仍然不是一个熟悉的数字。