令人费解的 16 位校验和/CRC 逆向工程问题

逆向工程 嵌入式 串行通讯 CRC
2021-06-30 06:42:18

我们很难弄清楚如何为我们需要逆向工程的串行通信协议计算校验和/CRC。这是 1990 年使用的通信协议(至少)。它由嵌入式代码用于显示单元之间的通信。到目前为止,我们已经注意到一些事情,但与理解 CRC 没有任何关系。以下是我们收集的几条消息:

有些消息很短。我们认为这是某种承认。存在 2 个版本:

  • 7F 25 64 12 78 21 44 7F 7F
  • 7F 25 64 12 79 31 65 7F 7F

据我们所知,这些是一些计时信息。注意字节数 27 是如何以 5 的增量变化的:

  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 10 38 17 30 00 7F 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 15 38 17 30 00 7E 7E 2F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 1A 38 17 30 00 7F 7F 5
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 1F 38 17 30 00 7F 7F 0
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 24 38 17 30 00 7F 7F 1
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 29 38 17 30 00 B 19 6F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 2E 38 17 30 00 F 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 33 38 17 30 00 7F 7F 10
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 38 38 17 30 00 7F 7F 6
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 3D 38 17 30 00 7F 7F 3
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 42 38 17 30 00 7F 7F 4
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 47 38 17 30 00 F 7F 7F 1
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 4C 38 17 30 00 7F 6F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 51 38 17 30 00 7F 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 56 38 17 30 00 7F 7F 1
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 5B 38 17 30 00 7F 7F 6
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 60 38 17 30 00 7F 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 65 38 17 30 00 7F 2
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 6A 38 17 30 00 7F 7F 5

其中一些消息仅更改一位(末尾的校验和除外):

  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 71 38 17 30 00 7F 7F 2C
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 73 38 17 30 00 7F 7F 7F

所以,我们设法弄清楚了:

  1. 显然,7F25 是消息的开始,7F7F 是结束(这是所有消息的常量)。
  2. 字节数 N-2 和 N-3 充当某种校验和/CRC。
  3. 任何地方都没有字节高于 7F。绝不。
  4. 查看一些消息,似乎单个位更改不会引起校验和字节的大变化。这为我们指明了 CRC 算法的方向。
  5. 我们被告知创建该协议的公司可能使用了 CRC16-CCITT 的一些变体。我们一直无法确认/验证这一点。

我们迷路了。任何帮助解决这个谜语将不胜感激。

谢谢。

编辑 1

我尝试了许多不同的 CRC 变体,以及许多不同的消息部分。没有什么有趣的。除了这个...

如果您查看 2 条非常短的消息,您可以看到在删除开始消息字节和结束消息字节后,我们只剩下 3 个字节 + 2 个校验和字节的消息。只有一个消息字节发生变化,即最后一个。2 条消息之间的差异(0x78 在最后一个位置变为 0x79)导致仅消息的最后一位发生变化。这会导致 2 个校验和字节发生变化(0x21 变为 0x31,0x44 变为 0x65)。以位为单位转换此信息,01111000 变为 01111001(仅更改最后一位 -> 00000001),这导致第一个校验和字节的 00100001 变为 00110001(00010000 的更改)和 010001010 变为第一个校验和的字节(010001010a) 00100001)。(通过更改,我的意思是 XOR 操作)

现在,有趣的部分是,如果我应用 CRC16-CCITT 的变体(XModem、Kermit、0xFFFF 等),结果(我必须应用到校验和字节的 XOR 操作从 0x78 终止消息到 0x79终止消息)是一样的!!结果不是(校验和字节不是预期的),但更改最后一个字节对校验和的影响确实相同。这将我指向 CCITT CRC 的方向,只是起始值与明显不同。我确实尝试了消息的所有可能性(只有最后一个字节,然后是最后 2 个,等等)。只有 3 个字节的可能性非常有限!

所有这一切可能只是一个(非常有趣的)巧合,但我认为有一个更简单/优雅(又名数学)的解释。我只是缺乏数学技能来看到明显的......

编辑 2

“没有字节高于 7F”这部分当然很容易解释:这个协议通过串行通信只有 7 位数据。呸!但这意味着如果检查是一个 crc,它将产生大于 7F 的校验和,然后必须是“mod 7F”才能通过串行通信传输。

尽量不“不遗余力”。

0个回答
没有发现任何回复~