I am trying to reverse engineer a 16 bit checksum algorithm of one relatively old (10 years) LAN game that is no longer supported nor has source code available. As it seems, data packets don't have standard structure when it comes to placing checksum bytes:
Example 1:
1f456e01
Where first byte 1f
seems to repeat itself in each packet and I assume it doesn't take part in generating checksum.
Next two bytes 456e
represent a checksum that presumably is a variation of CRC-CCITT
with non-standard polynomial.
Lastly, 01
byte represents data.
Here are few more examples of packets with various data values:
1f466e02
1f496e05
1f4b6e07
1f4c6e08
I wish I could post more diverse values but these are only ones I've been able to capture so far.
I tried fiddling with reveng to reverse engineer the polynomial with following command:
reveng -w 16 -s 01456e 02466e 05496e
Here the checksum bytes are relocated at the end, as reveng expects them in this format. But this gave no results.
I have tried comparing these checksums to most if not all common crc algorithms using online calculators but none of them give even close outputs to those above.
Honestly, I don't know where else to look.
Any hints/help or anything at all is much appreciated.
EDIT:
I managed to capture some more samples, however they are slightly different in terms of structure:
Example 1:
0e ed76 00 312e362e37544553540000000000000000000000000000000000000000 00
Here the first byte 0E
represents a sort of index, that I still think doesn't take part in generating checksum.
Then comes two byte checksum ED76
followed by 00
sort of separator (newline?) byte that I also think doesn't take part in computing checksum.
Afterwards follows data sequence: 312e362e37544553540000000000000000000000000000000000000000
which finally is proceeded by 00
terminating character that I also think has nothing to do with checksum.
I can manipulate with the data part of this sequence of bytes so here are some more examples:
Example 2:
HEX: 0E109D00414141414141414141414141414141414141414141414141414141414100
ASCII: ....AAAAAAAAAAAAAAAAAAAAAAAAAAAAA.
Example 3:
HEX: 0E8DC300424242424242424242424242424242424242424242424242424242424200
ASCII: ....BBBBBBBBBBBBBBBBBBBBBBBBBBBBB.
Example 4:
HEX: 0E403500313131313131313131313131313131313131313131313131313131313100
ASCII: [email protected].
Example 5:
HEX: 0E34CF00353535353535353535353535353535353535353535353535353535353500
ASCII: .4..55555555555555555555555555555.
Example 6:
HEX: 0E3E0C00313233343536373839304142434445464748494A4B4C4D4E4F5051525300
ASCII: .>..1234567890ABCDEFGHIJKLMNOPQRS.
EDIT 2: More samples added, checksum bytes reversed to show the actual 16 bit int (little endian)
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
EDIT 3: More samples that might make it easier to see the pattern:
Checksum Data (ASCII)
3540 11111111111111111111111111111
3561 11111111111111111111111111112
3582 11111111111111111111111111113
3981 11111111111111111111111111121
39A2 11111111111111111111111111122
c1a1 11111111111111111111111111211
4DC1 11111111111111111111111112111
5de1 11111111111111111111111121111
7201 11111111111111111111111211111
EDIT 4:
There was a typo in one of EDIT 3 samples - correct checksum for 11111111111111111111111112111
is 4DC1
instead of C10E
. Edited original sample. Apologies to everyone who lost their time because of this.
EDIT 5:
It turns out, the index byte does play a role in calculating checksum, here is one particular example proving it:
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)
Some more samples:
INDEX CHECKSUM PAYLOAD
0x3E 0x72C0 0x7D
0x1F 0x6E45 0x01
0x2B 0x704F 0x7F
Epilogue
Please see the accepted answer for the exact algorithm. Special thanks to Edward, nrz and Guntram Blohm; solving this would take a lifetime without your help guys!
1f f4 1b bc 00
. Is that correct?