我正在尝试对一个不再受支持也没有可用源代码的相对较旧(10 年)的 LAN 游戏的 16 位校验和算法进行逆向工程。看起来,数据包在放置校验和字节时没有标准结构:
Example 1:
1f456e01
第一个字节1f似乎在每个数据包中重复出现,我认为它不参与生成校验和。
接下来的两个字节456e表示校验和,大概是CRC-CCITT非标准多项式的变体。
最后,01字节代表数据。
以下是具有各种数据值的数据包的更多示例:
1f466e02
1f496e05
1f4b6e07
1f4c6e08
我希望我可以发布更多不同的值,但到目前为止我只能捕捉到这些值。
我尝试摆弄reveng以使用以下命令对多项式进行逆向工程:
reveng -w 16 -s 01456e 02466e 05496e
在这里,校验和字节在最后重新定位,因为 reveng 期望它们采用这种格式。但这没有结果。
我曾尝试使用在线计算器将这些校验和与大多数(如果不是全部)常见的 crc 算法进行比较,但它们都没有给出与上述算法相近的输出。
老实说,我不知道还能去哪里找。
任何提示/帮助或任何东西都非常感谢。
编辑:
我设法捕获了更多样本,但是它们在结构方面略有不同:
示例 1:
0e ed76 00 312e362e37544553540000000000000000000000000000000000000000 00
这里的第一个字节0E代表一种索引,我仍然认为它不参与生成校验和。然后是两个字节的校验和,ED76然后是00某种分隔符(换行符?)字节,我也认为它不参与计算校验和。之后是数据序列:312e362e37544553540000000000000000000000000000000000000000最后是通过00终止字符进行的,我也认为与校验和无关。
我可以使用此字节序列的数据部分进行操作,因此这里有更多示例:
Example 2:
HEX:    0E109D00414141414141414141414141414141414141414141414141414141414100
ASCII:  ....AAAAAAAAAAAAAAAAAAAAAAAAAAAAA.
Example 3:
HEX:    0E8DC300424242424242424242424242424242424242424242424242424242424200
ASCII:  ....BBBBBBBBBBBBBBBBBBBBBBBBBBBBB.
Example 4:
HEX:    0E403500313131313131313131313131313131313131313131313131313131313100
ASCII:  .@5.11111111111111111111111111111.
Example 5:
HEX:    0E34CF00353535353535353535353535353535353535353535353535353535353500
ASCII:  .4..55555555555555555555555555555.
Example 6:
HEX:    0E3E0C00313233343536373839304142434445464748494A4B4C4D4E4F5051525300
ASCII:  .>..1234567890ABCDEFGHIJKLMNOPQRS.
编辑 2: 添加了更多示例,校验和字节反转以显示实际的 16 位 int(小端)
Data         Checksum
0x01         0x6E45  
0x02         0x6E46
0x03         0x6E47
0x0001       0x3284
0x0002       0x3285
0x0003       0x3286
0x0104       0x32A8
0x0005       0x3288
0x0903       0x33AF
0x0106       0x32AA
0x3600       0x0AAE          
0xAD00       0x1A05          
0xF300       0x230B 
0xF400       0x232C
0xF500       0x234D
0xF600       0x236E
0xF700       0x238F 
0xF800       0x23B0 
0xFE00       0x2476          
0xA800       0x1960          
0xE200       0x20DA
0xE500       0x213D          
0xEE00       0x2266
0x7300       0x128B
0x7600       0x12EE          
0xF700       0x238F          
0xB400       0x1AEC
0xB800       0x1B70          
0xBC00       0x1BF4
0x015E00     0xF68B
0x013D00     0xF24A
0x011C00     0xEE09 
编辑 3:更多示例可能更容易查看模式:
Checksum     Data (ASCII)
3540         11111111111111111111111111111
3561         11111111111111111111111111112
3582         11111111111111111111111111113
3981         11111111111111111111111111121
39A2         11111111111111111111111111122
c1a1         11111111111111111111111111211
4DC1         11111111111111111111111112111
5de1         11111111111111111111111121111
7201         11111111111111111111111211111
编辑 4:
在EDIT 3 个示例之一中有一个错字- 正确的校验和11111111111111111111111112111是4DC1而不是C10E. 编辑原始样本。向所有因此而失去时间的人道歉。
编辑 5:
事实证明,索引字节确实在计算校验和时起作用,这里有一个特殊的例子来证明它:
INDEX   CHECKSUM    PAYLOAD
0x2B    0x704E      0x7E
0x3E    0x72C1      0x7E
Same payload has different checksum for different indexes. (checksum bytes reversed to show the actual 16 bit int)
更多示例:
INDEX   CHECKSUM    PAYLOAD
0x3E    0x72C0      0x7D
0x1F    0x6E45      0x01
0x2B    0x704F      0x7F
结语
请参阅接受的确切算法的答案。特别感谢Edward、nrz和Guntram Blohm;如果没有你们的帮助,解决这个问题将需要一生的时间!