Trying to reverse engineer a packet checksum/CRC/hash
Asked Answered
C

2

25

I have an old, no longer manufactured electronic device with a serial port. I am trying to reverse engineer the data packet CRC/checksum/hash used in this device.

Anyone with keen eyes, sharp math skills out there who might be able to crack this thing ?

Here is what I know so far ...

  • Every packet is always 21 bytes. 19 bytes of data plus 2 bytes at end for CRC/checksum/hash
  • Hence, there are here are no length or header bytes. All 19 bytes are involved in the hash calculation.
  • I have ability to generate certain amounts of data packets with the device
  • My first thoughts is that the data packets have some sort of CRC-16 calculation
  • So I followed reversing hints in www.cosc.canterbury.ac.nz/greg.ewing/essays/CRC-Reverse-Engineering.html
  • Verified that my data packet samples observed the "superposition principle" outlined in above web link. This indicates that they have a mathematical XOR relationship.

  • Started to feel good ... but then stumped after that. Have not been able to determine a CRC-16 polynomial. There is a strong possibility that these data packets hashes are not CRC-related, but rather some home brew scheme.

  • Read thru “A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS” by Ross N. Williams

  • See http://www.ross.net/crc/download/crc_v3.txt
  • Also used application: CRC Reveng – a reverse engineering application
  • See reveng.sourceforge.net
  • Still no luck ...
  • Unfortunately, I do not have access to any of the devices source/binary code

  • Also ran tests to see if used other hashes such as Fletcher's checksum

Here are various samples of my data packets.

0x47366B2EE00000000000751CEB5F3469543B585E2D
0x47366B2ED00000000000751CEB5F3469543B582A2C
0x47366B2EC80000000000751CEB5F3469543B580B2B
0x47366B2EC40000000000751CEB5F3469543B58BB2A
0x47366B2EC20040000000751CEB5F3469543B58DFE7
0x47366B2EC10000000000751CEB5F3469543B58A328
0x47366B2EC08000000000751CEB5F3469543B584127
0x47366B2EC04000000000751CEB5F3469543B588126
0x47366B2EC02000000000751CEB5F3469543B580525
0x47366B2EC01000000000751CEB5F3469543B580124

Please note the following about these data packets ...

  • CRC is found on the last 2 bytes of the data packet.
  • If I look at the bits on a logic analyzer, I have expressed the bytes as MSB-first
  • Hence, packet 0x47366B2EE00000000000751CEB5F3469543B585E2D is seen in binary as:
  • 01000111 .............................................................00101101
  • (0x47).....................................................................(0x2D)

  • I do not know if my system is big or little endian, but quite certain bytes are LSB-first

  • Note that for the above 10 data packet samples, each packet differs by 1 bit shifting thru 10 bit positions. Except for 5th packet, where I had to change 2 bits
  • See data bytes that follows 0x47366B2E portion of the data packet.

  • Only pattern I see that emerged is the last byte decrements by one (2D, 2C, ...) on each data packet. (Except the 5th packet, where I had to change 2 bits)

  • This last byte is NOT some sort of sequence number, since I can generate them at any time with same value.
  • But it possibly gives a hint on the mathematical hash used.

Any help is appreciated !

Cora answered 4/4, 2014 at 1:58 Comment(5)
How do you know that all 19 bytes are involved in the hash calculation?Denominative
Thru the LCD interface of the unit, I can send messages. This allows me to change any of the 19 "data" bytes. I don't have full control over every bit in the bytes, but pretty close.Cora
It does not appear to be a 16-bit CRC. The check value does appear to be a linear function over GF(2) of the data. It might be something like the low two bytes of a 32-bit CRC.Denominative
Thanks Mark. I'll do some more snooping and look into the truncated CRC-32 possibility.Cora
I can't see anywhere in the text where you say what the device is apologies if it's there as clear as day but if not it could help to know the make and model of the device or any chip markings - simply from the point of view that someone might remember working on or with the device and can give a hint or might even have an old data sheet - it's a long shot but it looks like you need all the help you can get.Tammara
S
1

IF it follows the simple XOR relationship that (checksum(A ^ B) == checksum(A) ^ checksum(B)) then there is a simple brute force solution!

Illustration. Suppose you have a 1-byte value with a K-bit checksum - where K doesn't actually matter, so we just represent checksums as c(i).

Step 1. Experiment: observe the checksum c(-1) of the all zeros packet.

0b0000000 => c(-1)

Step 2. Experiment: observe the checksums c(i) of all binary sequence with a single 1 in them at position i

0b00000001 => c(0)
0b00000010 => c(1)
0b00000100 => c(2)
0b00001000 => c(3)
0b00010000 => c(4)
0b00100000 => c(5)
0b01000000 => c(6)
0b10000000 => c(7)

The values you observed the checksums for form a linear basis for GF(2), and the XOR relationship now allows you to compute any checksum.

Now you can compute checksums by adding the checksums for each bit position with a 1, e.g. suppose you want the checksum of 0XF3 which in binary is 0b11110011. Since

0b11110011 = (0) + 0x80 + 0x40 + 0x20 + 0x10 + 0x02 + 0x01

then by XOR relationship,

checksum(0b11110011) = c(7) + c(6) + c(5) + c(4) + c(1) + c(0) + c(-1)

i.e. for every bit you are going to output, just XOR-accumulate the known checksum for that bit.

If you do this exercise and experimentally write out all 152 checksums of the basis vectors, it's possible you will also in the process spot a simple pattern that explains how the checksums come from the basis vectors. :) If so it would be nice to post that back here! (And maybe tell us what we're reversing?)

Smaragd answered 3/12, 2014 at 8:4 Comment(0)
Z
0

I have run some packets through an application called "SRP16", which searches for and displays CRC16 Rocksoft parameters. The output follows:

===== Result parameter sets =====
CRC=$2a2c  Poly=$2817  init=$3141  xorout=$ffff  refin=true   refout=true 
 *** Second data set verified
CRC=$2a2c  Poly=$2817  init=$70f4  xorout=$0000  refin=true   refout=true 
 *** Second data set verified
CRC=$2a2c  Poly=$2817  init=$9bf3  xorout=$0000  refin=false  refout=true 
 *** Second data set verified
CRC=$2a2c  Poly=$2817  init=$da46  xorout=$ffff  refin=false  refout=true 
 *** Second data set verified
CRC=$2a2c  Poly=$4777  init=$1263  xorout=$0000  refin=false  refout=true 
 *** Second data set verified
CRC=$2a2c  Poly=$4777  init=$6f2d  xorout=$0000  refin=true   refout=true 
 *** Second data set verified
CRC=$2a2c  Poly=$4777  init=$a127  xorout=$ffff  refin=true   refout=true 
 *** Second data set verified
CRC=$2a2c  Poly=$4777  init=$dc69  xorout=$ffff  refin=false  refout=true 
 *** Second data set verified
CRC=$2c2a  Poly=$7354  init=$1dab  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$7354  init=$417e  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$7354  init=$a401  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$7354  init=$f8d4  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$8a23  init=$0fa0  xorout=$0000  refin=false  refout=true 
 *** Second data set verified
CRC=$2c2a  Poly=$8a23  init=$3f6a  xorout=$ffff  refin=false  refout=true 
 *** Second data set verified
CRC=$2c2a  Poly=$8a23  init=$cc70  xorout=$0000  refin=true   refout=true 
 *** Second data set verified
CRC=$2c2a  Poly=$8a23  init=$fcba  xorout=$ffff  refin=true   refout=true 
 *** Second data set verified
CRC=$2c2a  Poly=$9656  init=$3460  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$9656  init=$ff4b  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$a644  init=$195b  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$a644  init=$70ca  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$a644  init=$a3e8  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$a644  init=$ca79  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
===== done =====

Maybe give these a try and see if they work for you?

Good luck!

Zoie answered 10/11, 2015 at 4:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.