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:
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.
01 byte represents data.
Here are few more examples of packets with various data values:
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.
I managed to capture some more samples, however they are slightly different in terms of structure:
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:
ASCII: [email protected].
EDIT 2: More samples added, checksum bytes reversed to show the actual 16 bit int (little endian)
EDIT 3: More samples that might make it easier to see the pattern:
Checksum Data (ASCII)
There was a typo in one of EDIT 3 samples - correct checksum for
4DC1 instead of
C10E. Edited original sample. Apologies to everyone who lost their time because of this.
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
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!