6

I give up.... I've tried for two years to determine which CRC algorithm is being using over an RS-232 serial connection between two pieces of equipment. The equipment dates from about 2002. I'm only assuming that its CRC protected but I might be wrong.

I've built an RS-232 monitor which I've connected to the data line.

I can clearly see on my oscope that it is standard RS-232 with a start bit, 8 data bits and a stop bit. I can tell that it is sent LSbit first. Its 9600 baud.

I can control parts of the data in the message but not all of it from the transmitting equipment. I've been able to determine what each of the bytes in the message mean. By turning knobs on the transmitter, I can see particular bytes increment by one. So I am fairly certain that I know what each of the data bytes of the message mean. They are all a simple binary encoding of knob positions and sometimes an ASCII character encoding of switch positions. The data bytes in the message all makes sense in the context of what the equipment does.

Here is a long sequence of messages over the serial line. I've been able to make the 4th byte sequence through all 256 values. The transmitting equipment is constructing these messages, I've just captured them. The first 6 bytes are the message.

The last two bytes appear to me to be a CRC rather than a checksum. From this list, its possible to gather up many message pairs that differ by one bit in that 4th byte. I know that can be useful.



   0x00 0x09 0x69 0x31 0x97 0x03 0x54 0x67
   0x00 0x09 0x69 0x31 0x98 0x03 0xAD 0xD5
   0x00 0x09 0x69 0x31 0x99 0x03 0x16 0xC9
   0x00 0x09 0x69 0x31 0x9A 0x03 0xDB 0xEC
   0x00 0x09 0x69 0x31 0x9B 0x03 0x60 0xF0
   0x00 0x09 0x69 0x31 0x9C 0x03 0x41 0xA7
   0x00 0x09 0x69 0x31 0x9D 0x03 0xFA 0xBB
   0x00 0x09 0x69 0x31 0x9E 0x03 0x37 0x9E
   0x00 0x09 0x69 0x31 0x9F 0x03 0x8C 0x82
   0x00 0x09 0x69 0x31 0xA0 0x03 0x87 0x7C
   0x00 0x09 0x69 0x31 0xA1 0x03 0x3C 0x60
   0x00 0x09 0x69 0x31 0xA2 0x03 0xF1 0x45
   0x00 0x09 0x69 0x31 0xA3 0x03 0x4A 0x59
   0x00 0x09 0x69 0x31 0xA4 0x03 0x6B 0x0E
   0x00 0x09 0x69 0x31 0xA5 0x03 0xD0 0x12
   0x00 0x09 0x69 0x31 0xA6 0x03 0x1D 0x37
   0x00 0x09 0x69 0x31 0xA7 0x03 0xA6 0x2B
   0x00 0x09 0x69 0x31 0xA8 0x03 0x5F 0x99
   0x00 0x09 0x69 0x31 0xA9 0x03 0xE4 0x85
   0x00 0x09 0x69 0x31 0xAA 0x03 0x29 0xA0
   0x00 0x09 0x69 0x31 0xAB 0x03 0x92 0xBC
   0x00 0x09 0x69 0x31 0xAC 0x03 0xB3 0xEB
   0x00 0x09 0x69 0x31 0xAD 0x03 0x08 0xF7
   0x00 0x09 0x69 0x31 0xAE 0x03 0xC5 0xD2
   0x00 0x09 0x69 0x31 0xAF 0x03 0x7E 0xCE
   0x00 0x09 0x69 0x31 0xB0 0x03 0x26 0xBF
   0x00 0x09 0x69 0x31 0xB1 0x03 0x9D 0xA3
   0x00 0x09 0x69 0x31 0xB2 0x03 0x50 0x86
   0x00 0x09 0x69 0x31 0xB3 0x03 0xEB 0x9A
   0x00 0x09 0x69 0x31 0xB4 0x03 0xCA 0xCD
   0x00 0x09 0x69 0x31 0xB5 0x03 0x71 0xD1
   0x00 0x09 0x69 0x31 0xB6 0x03 0xBC 0xF4
   0x00 0x09 0x69 0x31 0xB7 0x03 0x07 0xE8
   0x00 0x09 0x69 0x31 0xB8 0x03 0xFE 0x5A
   0x00 0x09 0x69 0x31 0xB9 0x03 0x45 0x46
   0x00 0x09 0x69 0x31 0xBA 0x03 0x88 0x63
   0x00 0x09 0x69 0x31 0xBB 0x03 0x33 0x7F
   0x00 0x09 0x69 0x31 0xBC 0x03 0x12 0x28
   0x00 0x09 0x69 0x31 0xBD 0x03 0xA9 0x34
   0x00 0x09 0x69 0x31 0xBE 0x03 0x64 0x11
   0x00 0x09 0x69 0x31 0xBF 0x03 0xDF 0x0D
   0x00 0x09 0x69 0x31 0xC0 0x03 0x63 0xE5
   0x00 0x09 0x69 0x31 0xC1 0x03 0xD8 0xF9
   0x00 0x09 0x69 0x31 0xC2 0x03 0x15 0xDC
   0x00 0x09 0x69 0x31 0xC3 0x03 0xAE 0xC0
   0x00 0x09 0x69 0x31 0xC4 0x03 0x8F 0x97
   0x00 0x09 0x69 0x31 0xC5 0x03 0x34 0x8B
   0x00 0x09 0x69 0x31 0xC6 0x03 0xF9 0xAE
   0x00 0x09 0x69 0x31 0xC7 0x03 0x42 0xB2
   0x00 0x09 0x69 0x31 0xC8 0x03 0xBB 0x00
   0x00 0x09 0x69 0x31 0xC9 0x03 0x00 0x1C
   0x00 0x09 0x69 0x31 0xCA 0x03 0xCD 0x39
   0x00 0x09 0x69 0x31 0xCB 0x03 0x76 0x25
   0x00 0x09 0x69 0x31 0xCC 0x03 0x57 0x72
   0x00 0x09 0x69 0x31 0xCD 0x03 0xEC 0x6E
   0x00 0x09 0x69 0x31 0xCE 0x03 0x21 0x4B
   0x00 0x09 0x69 0x31 0xCF 0x03 0x9A 0x57
   0x00 0x09 0x69 0x31 0xD0 0x03 0xC2 0x26
   0x00 0x09 0x69 0x31 0xD1 0x03 0x79 0x3A
   0x00 0x09 0x69 0x31 0xD2 0x03 0xB4 0x1F
   0x00 0x09 0x69 0x31 0xD3 0x03 0x0F 0x03
   0x00 0x09 0x69 0x31 0xD4 0x03 0x2E 0x54
   0x00 0x09 0x69 0x31 0xD5 0x03 0x95 0x48
   0x00 0x09 0x69 0x31 0xD6 0x03 0x58 0x6D
   0x00 0x09 0x69 0x31 0xD7 0x03 0xE3 0x71
   0x00 0x09 0x69 0x31 0xD8 0x03 0x1A 0xC3
   0x00 0x09 0x69 0x31 0xD9 0x03 0xA1 0xDF
   0x00 0x09 0x69 0x31 0xDA 0x03 0x6C 0xFA
   0x00 0x09 0x69 0x31 0xDB 0x03 0xD7 0xE6
   0x00 0x09 0x69 0x31 0xDC 0x03 0xF6 0xB1
   0x00 0x09 0x69 0x31 0xDD 0x03 0x4D 0xAD
   0x00 0x09 0x69 0x31 0xDE 0x03 0x80 0x88
   0x00 0x09 0x69 0x31 0xDF 0x03 0x3B 0x94
   0x00 0x09 0x69 0x31 0xE0 0x03 0x30 0x6A
   0x00 0x09 0x69 0x31 0xE1 0x03 0x8B 0x76
   0x00 0x09 0x69 0x31 0xE2 0x03 0x46 0x53
   0x00 0x09 0x69 0x31 0xE3 0x03 0xFD 0x4F
   0x00 0x09 0x69 0x31 0xE4 0x03 0xDC 0x18
   0x00 0x09 0x69 0x31 0xE5 0x03 0x67 0x04
   0x00 0x09 0x69 0x31 0xE6 0x03 0xAA 0x21
   0x00 0x09 0x69 0x31 0xE7 0x03 0x11 0x3D
   0x00 0x09 0x69 0x31 0xE8 0x03 0xE8 0x8F
   0x00 0x09 0x69 0x31 0xE9 0x03 0x53 0x93
   0x00 0x09 0x69 0x31 0xEA 0x03 0x9E 0xB6
   0x00 0x09 0x69 0x31 0xEB 0x03 0x25 0xAA
   0x00 0x09 0x69 0x31 0xEC 0x03 0x04 0xFD
   0x00 0x09 0x69 0x31 0xED 0x03 0xBF 0xE1
   0x00 0x09 0x69 0x31 0xEE 0x03 0x72 0xC4
   0x00 0x09 0x69 0x31 0xEF 0x03 0xC9 0xD8
   0x00 0x09 0x69 0x31 0xF0 0x03 0x91 0xA9
   0x00 0x09 0x69 0x31 0xF1 0x03 0x2A 0xB5
   0x00 0x09 0x69 0x31 0xF2 0x03 0xE7 0x90
   0x00 0x09 0x69 0x31 0xF3 0x03 0x5C 0x8C
   0x00 0x09 0x69 0x31 0xF4 0x03 0x7D 0xDB
   0x00 0x09 0x69 0x31 0xF5 0x03 0xC6 0xC7
   0x00 0x09 0x69 0x31 0xF6 0x03 0x0B 0xE2
   0x00 0x09 0x69 0x31 0xF7 0x03 0xB0 0xFE
   0x00 0x09 0x69 0x31 0xF8 0x03 0x49 0x4C
   0x00 0x09 0x69 0x31 0xF9 0x03 0xF2 0x50
   0x00 0x09 0x69 0x31 0xFA 0x03 0x3F 0x75
   0x00 0x09 0x69 0x31 0xFB 0x03 0x84 0x69
   0x00 0x09 0x69 0x31 0xFC 0x03 0xA5 0x3E
   0x00 0x09 0x69 0x31 0xFD 0x03 0x1E 0x22
   0x00 0x09 0x69 0x31 0xFE 0x03 0xD3 0x07
   0x00 0x09 0x69 0x31 0xFF 0x03 0x68 0x1B
   0x00 0x09 0x69 0x31 0x00 0x03 0xBA 0xDE
   0x00 0x09 0x69 0x31 0x01 0x03 0x01 0xC2
   0x00 0x09 0x69 0x31 0x02 0x03 0xCC 0xE7
   0x00 0x09 0x69 0x31 0x03 0x03 0x77 0xFB
   0x00 0x09 0x69 0x31 0x04 0x03 0x56 0xAC
   0x00 0x09 0x69 0x31 0x05 0x03 0xED 0xB0
   0x00 0x09 0x69 0x31 0x06 0x03 0x20 0x95
   0x00 0x09 0x69 0x31 0x07 0x03 0x9B 0x89
   0x00 0x09 0x69 0x31 0x08 0x03 0x62 0x3B
   0x00 0x09 0x69 0x31 0x09 0x03 0xD9 0x27
   0x00 0x09 0x69 0x31 0x0A 0x03 0x14 0x02
   0x00 0x09 0x69 0x31 0x0B 0x03 0xAF 0x1E
   0x00 0x09 0x69 0x31 0x0C 0x03 0x8E 0x49
   0x00 0x09 0x69 0x31 0x0D 0x03 0x35 0x55
   0x00 0x09 0x69 0x31 0x0E 0x03 0xF8 0x70
   0x00 0x09 0x69 0x31 0x0F 0x03 0x43 0x6C
   0x00 0x09 0x69 0x31 0x10 0x03 0x1B 0x1D
   0x00 0x09 0x69 0x31 0x11 0x03 0xA0 0x01
   0x00 0x09 0x69 0x31 0x12 0x03 0x6D 0x24
   0x00 0x09 0x69 0x31 0x13 0x03 0xD6 0x38
   0x00 0x09 0x69 0x31 0x14 0x03 0xF7 0x6F
   0x00 0x09 0x69 0x31 0x15 0x03 0x4C 0x73
   0x00 0x09 0x69 0x31 0x16 0x03 0x81 0x56
   0x00 0x09 0x69 0x31 0x17 0x03 0x3A 0x4A
   0x00 0x09 0x69 0x31 0x18 0x03 0xC3 0xF8
   0x00 0x09 0x69 0x31 0x19 0x03 0x78 0xE4
   0x00 0x09 0x69 0x31 0x1A 0x03 0xB5 0xC1
   0x00 0x09 0x69 0x31 0x1B 0x03 0x0E 0xDD
   0x00 0x09 0x69 0x31 0x1C 0x03 0x2F 0x8A
   0x00 0x09 0x69 0x31 0x1D 0x03 0x94 0x96
   0x00 0x09 0x69 0x31 0x1E 0x03 0x59 0xB3
   0x00 0x09 0x69 0x31 0x1F 0x03 0xE2 0xAF
   0x00 0x09 0x69 0x31 0x20 0x03 0xE9 0x51
   0x00 0x09 0x69 0x31 0x21 0x03 0x52 0x4D
   0x00 0x09 0x69 0x31 0x22 0x03 0x9F 0x68
   0x00 0x09 0x69 0x31 0x23 0x03 0x24 0x74
   0x00 0x09 0x69 0x31 0x24 0x03 0x05 0x23
   0x00 0x09 0x69 0x31 0x25 0x03 0xBE 0x3F
   0x00 0x09 0x69 0x31 0x26 0x03 0x73 0x1A
   0x00 0x09 0x69 0x31 0x27 0x03 0xC8 0x06
   0x00 0x09 0x69 0x31 0x28 0x03 0x31 0xB4
   0x00 0x09 0x69 0x31 0x29 0x03 0x8A 0xA8
   0x00 0x09 0x69 0x31 0x2A 0x03 0x47 0x8D
   0x00 0x09 0x69 0x31 0x2B 0x03 0xFC 0x91
   0x00 0x09 0x69 0x31 0x2C 0x03 0xDD 0xC6
   0x00 0x09 0x69 0x31 0x2D 0x03 0x66 0xDA
   0x00 0x09 0x69 0x31 0x2E 0x03 0xAB 0xFF
   0x00 0x09 0x69 0x31 0x2F 0x03 0x10 0xE3
   0x00 0x09 0x69 0x31 0x30 0x03 0x48 0x92
   0x00 0x09 0x69 0x31 0x31 0x03 0xF3 0x8E
   0x00 0x09 0x69 0x31 0x32 0x03 0x3E 0xAB
   0x00 0x09 0x69 0x31 0x33 0x03 0x85 0xB7
   0x00 0x09 0x69 0x31 0x34 0x03 0xA4 0xE0
   0x00 0x09 0x69 0x31 0x35 0x03 0x1F 0xFC
   0x00 0x09 0x69 0x31 0x36 0x03 0xD2 0xD9
   0x00 0x09 0x69 0x31 0x37 0x03 0x69 0xC5
   0x00 0x09 0x69 0x31 0x38 0x03 0x90 0x77
   0x00 0x09 0x69 0x31 0x39 0x03 0x2B 0x6B
   0x00 0x09 0x69 0x31 0x3A 0x03 0xE6 0x4E
   0x00 0x09 0x69 0x31 0x3B 0x03 0x5D 0x52
   0x00 0x09 0x69 0x31 0x3C 0x03 0x7C 0x05
   0x00 0x09 0x69 0x31 0x3D 0x03 0xC7 0x19
   0x00 0x09 0x69 0x31 0x3E 0x03 0x0A 0x3C
   0x00 0x09 0x69 0x31 0x3F 0x03 0xB1 0x20
   0x00 0x09 0x69 0x31 0x40 0x03 0x0D 0xC8
   0x00 0x09 0x69 0x31 0x41 0x03 0xB6 0xD4
   0x00 0x09 0x69 0x31 0x42 0x03 0x7B 0xF1
   0x00 0x09 0x69 0x31 0x43 0x03 0xC0 0xED
   0x00 0x09 0x69 0x31 0x44 0x03 0xE1 0xBA
   0x00 0x09 0x69 0x31 0x45 0x03 0x5A 0xA6
   0x00 0x09 0x69 0x31 0x46 0x03 0x97 0x83
   0x00 0x09 0x69 0x31 0x47 0x03 0x2C 0x9F
   0x00 0x09 0x69 0x31 0x48 0x03 0xD5 0x2D
   0x00 0x09 0x69 0x31 0x49 0x03 0x6E 0x31
   0x00 0x09 0x69 0x31 0x4A 0x03 0xA3 0x14
   0x00 0x09 0x69 0x31 0x4B 0x03 0x18 0x08
   0x00 0x09 0x69 0x31 0x4C 0x03 0x39 0x5F
   0x00 0x09 0x69 0x31 0x4D 0x03 0x82 0x43
   0x00 0x09 0x69 0x31 0x4E 0x03 0x4F 0x66
   0x00 0x09 0x69 0x31 0x4F 0x03 0xF4 0x7A
   0x00 0x09 0x69 0x31 0x50 0x03 0xAC 0x0B
   0x00 0x09 0x69 0x31 0x51 0x03 0x17 0x17
   0x00 0x09 0x69 0x31 0x52 0x03 0xDA 0x32
   0x00 0x09 0x69 0x31 0x53 0x03 0x61 0x2E
   0x00 0x09 0x69 0x31 0x54 0x03 0x40 0x79
   0x00 0x09 0x69 0x31 0x55 0x03 0xFB 0x65
   0x00 0x09 0x69 0x31 0x56 0x03 0x36 0x40
   0x00 0x09 0x69 0x31 0x57 0x03 0x8D 0x5C
   0x00 0x09 0x69 0x31 0x58 0x03 0x74 0xEE
   0x00 0x09 0x69 0x31 0x59 0x03 0xCF 0xF2
   0x00 0x09 0x69 0x31 0x5A 0x03 0x02 0xD7
   0x00 0x09 0x69 0x31 0x5B 0x03 0xB9 0xCB
   0x00 0x09 0x69 0x31 0x5C 0x03 0x98 0x9C
   0x00 0x09 0x69 0x31 0x5D 0x03 0x23 0x80
   0x00 0x09 0x69 0x31 0x5E 0x03 0xEE 0xA5
   0x00 0x09 0x69 0x31 0x5F 0x03 0x55 0xB9
   0x00 0x09 0x69 0x31 0x60 0x03 0x5E 0x47
   0x00 0x09 0x69 0x31 0x61 0x03 0xE5 0x5B
   0x00 0x09 0x69 0x31 0x62 0x03 0x28 0x7E
   0x00 0x09 0x69 0x31 0x63 0x03 0x93 0x62
   0x00 0x09 0x69 0x31 0x64 0x03 0xB2 0x35
   0x00 0x09 0x69 0x31 0x65 0x03 0x09 0x29
   0x00 0x09 0x69 0x31 0x66 0x03 0xC4 0x0C
   0x00 0x09 0x69 0x31 0x67 0x03 0x7F 0x10
   0x00 0x09 0x69 0x31 0x68 0x03 0x86 0xA2
   0x00 0x09 0x69 0x31 0x69 0x03 0x3D 0xBE
   0x00 0x09 0x69 0x31 0x6A 0x03 0xF0 0x9B
   0x00 0x09 0x69 0x31 0x6B 0x03 0x4B 0x87
   0x00 0x09 0x69 0x31 0x6C 0x03 0x6A 0xD0
   0x00 0x09 0x69 0x31 0x6D 0x03 0xD1 0xCC
   0x00 0x09 0x69 0x31 0x6E 0x03 0x1C 0xE9
   0x00 0x09 0x69 0x31 0x6F 0x03 0xA7 0xF5
   0x00 0x09 0x69 0x31 0x70 0x03 0xFF 0x84
   0x00 0x09 0x69 0x31 0x71 0x03 0x44 0x98
   0x00 0x09 0x69 0x31 0x72 0x03 0x89 0xBD
   0x00 0x09 0x69 0x31 0x73 0x03 0x32 0xA1
   0x00 0x09 0x69 0x31 0x74 0x03 0x13 0xF6
   0x00 0x09 0x69 0x31 0x75 0x03 0xA8 0xEA
   0x00 0x09 0x69 0x31 0x76 0x03 0x65 0xCF
   0x00 0x09 0x69 0x31 0x76 0x03 0x65 0xCF
   0x00 0x09 0x69 0x31 0x77 0x03 0xDE 0xD3
   0x00 0x09 0x69 0x31 0x78 0x03 0x27 0x61
   0x00 0x09 0x69 0x31 0x79 0x03 0x9C 0x7D
   0x00 0x09 0x69 0x31 0x7A 0x03 0x51 0x58
   0x00 0x09 0x69 0x31 0x7B 0x03 0xEA 0x44
   0x00 0x09 0x69 0x31 0x7C 0x03 0xCB 0x13
   0x00 0x09 0x69 0x31 0x7D 0x03 0x70 0x0F
   0x00 0x09 0x69 0x31 0x7E 0x03 0xBD 0x2A
   0x00 0x09 0x69 0x31 0x7F 0x03 0x06 0x36
   0x00 0x09 0x69 0x31 0x80 0x03 0xD4 0xF3
   0x00 0x09 0x69 0x31 0x81 0x03 0x6F 0xEF
   0x00 0x09 0x69 0x31 0x82 0x03 0xA2 0xCA
   0x00 0x09 0x69 0x31 0x83 0x03 0x19 0xD6
   0x00 0x09 0x69 0x31 0x84 0x03 0x38 0x81
   0x00 0x09 0x69 0x31 0x85 0x03 0x83 0x9D
   0x00 0x09 0x69 0x31 0x86 0x03 0x4E 0xB8
   0x00 0x09 0x69 0x31 0x87 0x03 0xF5 0xA4
   0x00 0x09 0x69 0x31 0x88 0x03 0x0C 0x16
   0x00 0x09 0x69 0x31 0x89 0x03 0xB7 0x0A
   0x00 0x09 0x69 0x31 0x8A 0x03 0x7A 0x2F
   0x00 0x09 0x69 0x31 0x8B 0x03 0xC1 0x33
   0x00 0x09 0x69 0x31 0x8C 0x03 0xE0 0x64
   0x00 0x09 0x69 0x31 0x8D 0x03 0x5B 0x78
   0x00 0x09 0x69 0x31 0x8E 0x03 0x96 0x5D
   0x00 0x09 0x69 0x31 0x8F 0x03 0x2D 0x41
   0x00 0x09 0x69 0x31 0x90 0x03 0x75 0x30
   0x00 0x09 0x69 0x31 0x91 0x03 0xCE 0x2C
   0x00 0x09 0x69 0x31 0x92 0x03 0x03 0x09
   0x00 0x09 0x69 0x31 0x93 0x03 0xB8 0x15
   0x00 0x09 0x69 0x31 0x94 0x03 0x99 0x42
   0x00 0x09 0x69 0x31 0x95 0x03 0x22 0x5E
   0x00 0x09 0x69 0x31 0x96 0x03 0xEF 0x7B
   0x00 0x09 0x69 0x31 0x97 0x03 0x54 0x67
   0x00 0x09 0x69 0x31 0x98 0x03 0xAD 0xD5
   0x00 0x09 0x69 0x31 0x99 0x03 0x16 0xC9
   0x00 0x09 0x69 0x31 0x9A 0x03 0xDB 0xEC
   0x00 0x09 0x69 0x31 0x9B 0x03 0x60 0xF0
   0x00 0x09 0x69 0x31 0x9C 0x03 0x41 0xA7
   0x00 0x09 0x69 0x31 0x9D 0x03 0xFA 0xBB
   0x00 0x09 0x69 0x31 0x9E 0x03 0x37 0x9E
   0x00 0x09 0x69 0x31 0x9F 0x03 0x8C 0x82
   0x00 0x09 0x69 0x31 0xA0 0x03 0x87 0x7C
   0x00 0x09 0x69 0x31 0xA1 0x03 0x3C 0x60
   0x00 0x09 0x69 0x31 0xA2 0x03 0xF1 0x45
   0x00 0x09 0x69 0x31 0xA3 0x03 0x4A 0x59
   0x00 0x09 0x69 0x31 0xA4 0x03 0x6B 0x0E
   0x00 0x09 0x69 0x31 0xA5 0x03 0xD0 0x12
   0x00 0x09 0x69 0x31 0xA6 0x03 0x1D 0x37
   0x00 0x09 0x69 0x31 0xA7 0x03 0xA6 0x2B
   0x00 0x09 0x69 0x31 0xA8 0x03 0x5F 0x99
   0x00 0x09 0x69 0x31 0xA9 0x03 0xE4 0x85
   0x00 0x09 0x69 0x31 0xAA 0x03 0x29 0xA0
   0x00 0x09 0x69 0x31 0xAB 0x03 0x92 0xBC
   0x00 0x09 0x69 0x31 0xAC 0x03 0xB3 0xEB
   0x00 0x09 0x69 0x31 0xAD 0x03 0x08 0xF7
   0x00 0x09 0x69 0x31 0xAE 0x03 0xC5 0xD2
   0x00 0x09 0x69 0x31 0xAF 0x03 0x7E 0xCE

I've tried "reveng" on these messages with no luck. This equipment was designed to work with a PC so I think we are working with little endian bytes.

On my PC, I can duplicate these messages to mimic the transmitting equipment and the receiving equipment accepts them. I can prefix the messages with any number of 0x00 bytes and the receiving equipment accepts them. If I change any bit in the message including the possible CRC bytes, the receiving equipment rejects them (the receiver sends a simple OK message if it accepts the message, otherwise it does not respond at all.)

On my PC, I have taken one of the messages and sent it to the receiver with every possible two bytes at the end. The receiver rejects every message except the message with the last two bytes which are the same as the original message.

Those two bytes are important. Maybe they are somekind of checksum rather an CRC.

I've spent two years going through the reverse enginerring document written by Greg Ewing http://www.cosc.canterbury.ac.nz/greg.ewing/essays/CRC-Reverse-Engineering.html and I can make some progress following his method but my progress eventually stalls.

I don't want to say anything about what Greg's method helped me find because I might have done it all wrong. If anyone thinks that it might be useful, I will post it here.

If I turn off the equipment and then turn it back on and have it send the same message again, the last two bytes are the same each time I do this.

So I'm hoping that I can get more hints here on Reverse Engineering Stack Exchange.

Enrico

1
  • Is there any kind of documentation for your transmitter? Does it has upgradable firmware, or an eprom chip that could be taken out and read? Reversing the firmware of the transmitter might be difficult, but not that difficult compared to your two years (though i assume that wasn't 2 years of an 8-hours-per day job ...) Nov 17, 2014 at 10:02

2 Answers 2

6

I figured it out! Some of the comments on this web site made me go back and think harder - actually to think differently.

I thought that I should post the analysis that I did on these messages to try to determine the CRC algorighm.

My analysis is based on a paper written by Greg Ewing http://www.cosc.canterbury.ac.nz/greg.ewing/essays/CRC-Reverse-Engineering.html . He presented a lot of insights in that paper. I won't repeat what he wrote except to summarize and explain my results using his method. So follow along with his paper as I present my data.

He showed that CRC's "obey a kind of superposition principle. You can think of the CRC as being made up of the exclusive-or of a set of component CRCs, each of which depends on just one bit in the message.

He showed where, for the case of XorIn = XorOut = 0x0000, that:

C1 xor C2 = M1 xor M2 where: Cx = CRC Mx = equal length messages

He called "M1 xor M2" a difference message.

Greg wrote: "Then I got into a conversation with Patrick Maupin, who suggested a test that might help to clarify whether it was a true CRC or not. Due to the superposition principle, if changing a message by xoring it with a bit pattern B1 causes its CRC to change by C1, and another bit pattern B2 causes the CRC to change by C2, then xoring the message with (B1 xor B2) should change the CRC by (C1 xor C2). If that doesn't happen, the algorithm can't be an ordinary CRC algorithm."

Using these 4 message from the transmitter to receiver bit stream:


                                    CRC
                                  LSB  MSB
   ---- ---- ---- ---- ---- ---- ---- ----
M0 0x00 0x09 0x69 0x31 0x00 0x03 0xBA 0xDE
M1 0x00 0x09 0x69 0x31 0x01 0x03 0x01 0xC2
M2 0x00 0x09 0x69 0x31 0x02 0x03 0xCC 0xE7
M3 0x00 0x09 0x69 0x31 0x03 0x03 0x77 0xFB
   ---- ---- ---- ---- ---- ---- ---- ----

Then,


                                    CRC
                                  LSB  MSB
   ---- ---- ---- ---- ---- ---- ---- ----
M0 0x00 0x09 0x69 0x31 0x00 0x03 0xBA 0xDE
B1 0x00 0x00 0x00 0x00 0x01 0x00
   ------------ XOR ------------
M1 0x00 0x09 0x69 0x31 0x01 0x03 0x01 0xC2   

C1 = 0xDEBA xor 0xC201 = 0x1CBB

and another bit pattern B2 causes the CRC to change by C2,


                                    CRC
                                  LSB  MSB
   ---- ---- ---- ---- ---- ---- ---- ----
M0 0x00 0x09 0x69 0x31 0x00 0x03 0xBA 0xDE
B2 0x00 0x00 0x00 0x00 0x02 0x00
   ------------ XOR ------------
M2 0x00 0x09 0x69 0x31 0x02 0x03 0xCC 0xE7

C2 = 0xDEBA xor 0xE7CC = 0x3976

C1 xor C2 = 0x1CBB xor 0x3976 = 0x25CD

then xoring the packet with B3 = (B1 xor B2) should change the CRC by C3 = (C1 xor C2). If that doesn't happen, the algorithm can't be an ordinary CRC algorithm.


                                    CRC
                                  LSB  MSB
   ---- ---- ---- ---- ---- ---- ---- ----
B1 0x00 0x00 0x00 0x00 0x01 0x00
B2 0x00 0x00 0x00 0x00 0x02 0x00
   ------------ XOR ------------

B3 0x00 0x00 0x00 0x00 0x03 0x00

M0 0x00 0x09 0x69 0x31 0x00 0x03 0xBA 0xDE
B3 0x00 0x00 0x00 0x00 0x03 0x00
   ------------ XOR ------------
M3 0x00 0x09 0x69 0x31 0x03 0x03 0x77 0xFB

C3 = 0xDEBA xor 0xFB77 = 0x25CD

Does C3 = 0x25CD == C1 XOR C2 = 0x25CD  ? Yes

In the case of the this serial stream, it happens so it must be an ordinary CRC algorithm.

Greg wrote: "Now consider two CRC values obtained from two 1-bit messages, where the 1 bits are in adjacent positions. The resulting CRCs will differ by just one shift-xor cycle. To be precise, if C1 corresponds to the message with a 1 in position i, and C2 corresponds to the message with a 1 in position i+1, then C1 is derived from applying one shift-xor cycle to C2. (If this seems backwards, it's because the further the 1 bit is from the end of the message, the more shift-xor cycles get applied to the CRC.)

There are two possibilities. If the leading bit of C2 (the one about to be shifted out) is 0, then C1 will be equal to C2 shifted by one place. If it is 1, then C2 will be equal to C1 shifted one place and xored with the polynomial."

I constructed several difference messages that differed in only one bit using the data from my first posting here.


                                     CRC
                                  LSB  MSB
    ---- ---- ---- ---- ---- ---- ---- ----
M0  0x00 0x09 0x69 0x31 0x00 0x03 0xBA 0xDE
M1  0x00 0x09 0x69 0x31 0x01 0x03 0x01 0xC2
    ---- ---- ---- ---- ---- ---- ---- ---- 
D01    0    0    0    0 0x01    0 0xBB 0x1C 

    ---- ---- ---- ---- ---- ---- ---- ----
M0  0x00 0x09 0x69 0x31 0x00 0x03 0xBA 0xDE
M2  0x00 0x09 0x69 0x31 0x02 0x03 0xCC 0xE7
    ---- ---- ---- ---- ---- ---- ---- ----  
D02    0    0    0    0 0x02    0 0x76 0x39

    ---- ---- ---- ---- ---- ---- ---- ----
M0  0x00 0x09 0x69 0x31 0x00 0x03 0xBA 0xDE
M3  0x00 0x09 0x69 0x31 0x04 0x03 0x56 0xAC
    ---- ---- ---- ---- ---- ---- ---- ---- 
D04    0    0    0    0 0x04    0 0xEC 0x72 

    ---- ---- ---- ---- ---- ---- ---- ----
M0  0x00 0x09 0x69 0x31 0x00 0x03 0xBA 0xDE
m8  0x00 0x09 0x69 0x31 0x08 0x03 0x62 0x3B
    ---- ---- ---- ---- ---- ---- ---- ---- 
D08    0    0    0    0 0x08    0 0xD8 0xE5

    ---- ---- ---- ---- ---- ---- ---- ----
M0  0x00 0x09 0x69 0x31 0x00 0x03 0xBA 0xDE
M10 0x00 0x09 0x69 0x31 0x10 0x03 0x1B 0x1D
    ---- ---- ---- ---- ---- ---- ---- ----
D10    0    0    0    0 0x10    0 0xA1 0xC3

    ---- ---- ---- ---- ---- ---- ---- ----
M0  0x00 0x09 0x69 0x31 0x00 0x03 0xBA 0xDE
M20 0x00 0x09 0x69 0x31 0x20 0x03 0xE9 0x51
    ---- ---- ---- ---- ---- ---- ---- ----
D20    0    0    0    0 0x20    0 0x53 0x8f

    ---- ---- ---- ---- ---- ---- ---- ----
M0  0x00 0x09 0x69 0x31 0x00 0x03 0xBA 0xDE
M40 0x00 0x09 0x69 0x31 0x40 0x03 0x0D 0xC8
    ---- ---- ---- ---- ---- ---- ---- ----
D40    0    0    0    0 0x40    0 0xB7 0x16

    ---- ---- ---- ---- ---- ---- ---- ----
M0  0x00 0x09 0x69 0x31 0x00 0x03 0xBA 0xDE
M80 0x00 0x09 0x69 0x31 0x80 0x03 0xD4 0xF3
    ---- ---- ---- ---- ---- ---- ---- ---- 
D80    0    0    0    0 0x80    0 0x6e 0x2d

I came up with these CRC values for the difference messages with the byte shown:


Byte    CRC (with byte swap to MSB-LSB order)
-----   ----
01  1CBB            
02  3976    LSB of CRC = 0
04  72EC    LSB of CRC = 0
08  E5D8    LSB of CRC = 0
10  C3A1    LSB of CRC = 1
20  8F53    LSB of CRC = 1
40  16b7    LSB of CRC = 1
80  2d6e    Lsb of CRC = 0

Greg explained that when the LSB is a 0, the preceding CRC is one bit right shift of this CRC. If the LSB is a 1 then the preceeding CRC is the current CRC xor'ed with the polynomial and then right shifted.


Byte    CRC shift   xor Previous CRC
-----   ----    ----    ----    ----
01  1CBB            
02  3976    1CBB    0000    1CBB
04  72EC    3976    0000    3976
08  E5D8    72EC    0000    72EC
10  C3A1    61D0    8408    E5D8
20  8F53    47A9    8408    C3A1
40  16b7    0B5B    8408    8F53
80  2d6e    16B7    0000    16b7

This told me that the polynomial was 0x8408.

The next sentence paraphrases what Greg wrote: "The shifting direction indicates that the ReflectOut parameter should be True, since shifting to the right is equivalent to using the canonical left-shifting version of the algorithm with the polynomial 0x1021 and then reflecting the resulting CRC. It is notable that 0x1021 is one of the standard 16-bit polynomials -- the one that called "CRC-16-CCITT"and also known as "KERMIT"."

So Greg has helped me get pretty far along with my analysis. It sure looks like its a CRC and its most likely CRC-16-CCITT or Kermit (at least if init = XorOut = 0x0000).

But, of course, when I tried running my messages through RevEng and asking it to use the KERMIT algorithm, the actual CRC's from the messages did not match what RevEng generated.

For example, using D01 message:

d:>reveng -c -m kermit 000000000100 returns d819

Greg's analysis of his problem indicated that there might some bytes included in the CRC calculation that are not apparent. In Greg's case, he wrote : "I came up with the following idea. Start by initialising the register with the polynomial -- this corresponds to the state just after encountering the 1 in a 1-bit difference message. Then run the algorithm and count the number of steps required before the known CRC value is reached. Assuming it was eventually reached, that would tell me how many 0 bits following the 1 were included in the CRC."

So, I said maybe this would work for me. So I added 00 bytes to the end of message D01:

d:>reveng -c -m kermit 00000000010000 returns dc5a

d:>reveng -c -m kermit 0000000001000000 returns bb1c

WOW, 0xbb1c is the CRC value that I get when I xor the two actual CRC's from M0 and M1. (I can add 0x00 bytes to the difference message if the actual bytes in the actual messages are the same and are 0x00 after they are xor'ed into the difference message. And I need to remember that this analysis still requires that init and XorOut are zero and that might not be case in the actual algorithm.

So I spent about a year (no, not full time) trying to find the value of the extra bytes. I wrote a progam which tried all combinations of extra bytes but I their values jumped all over. I'm going to leave out everything I did trying to find the extra bytes. It was a dead end.

** This is were I was when I posted my problem description on this web page. **

Maybe I still didn't have the right data bytes in the right position or maybe the assumption that init = XorOut = 0x0000 was not true.

So I decided to try more messages. I made up a bunch of messages where I could control value of the 2nd byte. Here are the messages that I was able to generate:


                                                  CRC
                                                LSB  MSB
   ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
   0x00 0x02 0x77 0x32                0x97 0x13 0x22 0x8D        
   0x00 0x04 0x77 0x32                0x97 0x13 0x14 0xE8
   0x00 0x08 0x77 0x32                0x97 0x13 0x78 0x22
   0x00 0x10 0x77 0x32                0x97 0x13 0xB1 0xBE
   0x00 0x20 0x77 0x32                0x97 0x13 0x32 0x8F
   0x00 0x40 0x77 0x32                0x97 0x13 0x34 0xEC
   0x00 0x06 0x77 0x32                0x97 0x13 0x06 0xCB
   0x00 0x0A 0x77 0x32                0x97 0x13 0x6A 0x01
   0x00 0x12 0x77 0x32                0x97 0x13 0xA3 0x9D
   0x00 0x22 0x77 0x32                0x97 0x13 0x20 0xAC
   0x00 0x42 0x77 0x32                0x97 0x13 0x26 0xCF

And here are the difference messages:


                                                  CRC
                                                LSB  MSB
     ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
M02a 0x00 0x02 0x77 0x32                0x97 0x13 0x22 0x8D
M03a 0x00 0x03 0x77 0x32                0x97 0x13 0xAB 0x9C
     ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
D01a 0x00 0x01 0x00 0x00                0x00 0x00 0x89 0x11

                                                LSB  MSB
   ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
   0x00 0x04 0x77 0x32                0x97 0x13 0x14 0xE8
   0x00 0x06 0x77 0x32                0x97 0x13 0x06 0xCB
   ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
   0x00 0x02 0x00 0x00                0x00 0x00 0x12 0x23

                                                LSB  MSB
   ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
   0x00 0x02 0x77 0x32                0x97 0x13 0x22 0x8D
   0x00 0x06 0x77 0x32                0x97 0x13 0x06 0xCB
   ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
   0x00 0x04 0x00 0x00                0x00 0x00 0x24 0x46

                                                LSB  MSB
   ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
   0x00 0x02 0x77 0x32                0x97 0x13 0x22 0x8D
   0x00 0x0A 0x77 0x32                0x97 0x13 0x6A 0x01
   ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
   0x00 0x08 0x00 0x00                0x00 0x00 0x48 0x8C

                                                LSB  MSB
   ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
   0x00 0x02 0x77 0x32                0x97 0x13 0x22 0x8D
   0x00 0x12 0x77 0x32                0x97 0x13 0xA3 0x9D
   ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
   0x00 0x10 0x00 0x00                0x00 0x00 0x81 0x10

                                                LSB  MSB
   ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
   0x00 0x02 0x77 0x32                0x97 0x13 0x22 0x8D
   0x00 0x22 0x77 0x32                0x97 0x13 0x20 0xAC
   ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
   0x00 0x20 0x00 0x00                0x00 0x00 0x02 0x21

                                                LSB  MSB
   ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
   0x00 0x02 0x77 0x32                0x97 0x13 0x22 0x8D
   0x00 0x42 0x77 0x32                0x97 0x13 0x26 0xCF
   ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
   0x00 0x40 0x00 0x00                0x00 0x00 0x04 0x42

Then I did the same analysis on the CRC words and came up with the same polynominal as before : 0x8408 or when shifted the other direction, 0x1021


Byte    CRC (with byte swap to MSB-LSB order)
-----   ----
0x01    1189
0x02    2312    LSB of CRC = 0
0x04    4624    LSB of CRC = 0
0x08    8C48    LSB of CRC = 0
0x10    1081    LSB of CRC = 1
0x20    2102    LSB of CRC = 0
0x40    4204    LSB of CRC = 0


Byte    CRC shift   xor Previous CRC
-----   ----    ----    ----    ----
0x01    1189
0x02    2312    1189    0000    1189
0x04    4624    2312    0000    2312
0x08    8C48    4624    0000    4624
0x10    1081    0840    8408    8C48    
0x20    2102    1081    0000    1081
0x40    4204    2102    0000    2102

Here are all of the RockSoft CRC models with this poly, I need to think past Kermit:


width=16  poly=0x1021  init=0x0000  refin=false  refout=false  xorout=0x0000  check=0x31c3  name="XMODEM"
width=16  poly=0x1021  init=0x0000  refin=true  refout=true  xorout=0x0000  check=0x2189  name="KERMIT"
width=16  poly=0x1021  init=0x1d0f  refin=false  refout=false  xorout=0x0000  check=0xe5cc  name="CRC-16/AUG-CCITT"
width=16  poly=0x1021  init=0x89ec  refin=true  refout=true  xorout=0x0000  check=0x26b1  name="CRC-16/TMS37157"
width=16  poly=0x1021  init=0xb2aa  refin=true  refout=true  xorout=0x0000  check=0x63d0  name="CRC-16/RIELLO"
width=16  poly=0x1021  init=0xc6c6  refin=true  refout=true  xorout=0x0000  check=0xbf05  name="CRC-A"
width=16  poly=0x1021  init=0xffff  refin=false  refout=false  xorout=0x0000  check=0x29b1  name="CRC-16/CCITT-FALSE"
width=16  poly=0x1021  init=0xffff  refin=false  refout=false  xorout=0xffff  check=0xd64e  name="CRC-16/GENIBUS"
width=16  poly=0x1021  init=0xffff  refin=true  refout=true  xorout=0x0000  check=0x6f91  name="CRC-16/MCRF4XX"
width=16  poly=0x1021  init=0xffff  refin=true  refout=true  xorout=0xffff  check=0x906e  name="X-25"

I noticed something with this newest set of messages. The two extra bytes were not needed to get the correct CRC for the difference messages if I just used the first byte and left off the other 0x00 bytes. Using RevEng on message D01a:

D:>reveng -s -w 16 018911 width=16 poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189 name="KERMIT"

Then I realized that if I feed the message into the CRC generator in reverse byte order, my original D01 message generated the correct CRC.

D:>reveng -c -m kermit 01000000 bb1c

So these bytes that I thought were extra bytes were really just bytes of the message but the message was to be processed in reverse byte order.

Could this be true?

I took M02a and M03a, and fed them into RevEng in reverse byte order:

D:>reveng -s -w 16 1397327702228d width=16 poly=0x1021 init=0xffff refin=true refout=true xorout=0x0000 check=0x6f91 name="CRC-16/MCRF4XX"

D:>reveng -s -w 16 1397327703ab9c width=16 poly=0x1021 init=0xffff refin=true refout=true xorout=0x0000 check=0x6f91 name="CRC-16/MCRF4XX"

And what fell out amazed me, init was all ones and the algorithm had the same poly that I previously found. The algorithm was from MCRF4xx communications (which now I see makes sense because the RS-232 line that I'm tracing replaced an RF connection).

MCRF4xx is an RFID protocol.

The message is taken as one long set of bits so that the last byte is processed first and the first byte is processed last. The 0x00 byte at the beginning of message is not used. With init = 0xffff, the MCRF4xx algorithm will detect extra or missing leading zeros.

I tried this algorithm on a couple dozen of the messages and it gets the correct CRC every time.

Here is a snipit of code that I found at http://www.snip2code.com/Snippet/86260/Simple-CRC-16-MCRF4XX-C-implementation-


    #include 
    #include 

    uint16_t crc16_mcrf4xx(uint16_t crc, uint8_t *data, size_t len)
    {
    if (!data || len > 1) ^ 0x8408;
            else crc = (crc >> 1);
            }
        }
    return crc;
    }

A web page on the RevEng site, points to some documents about MCRF4xx: http://reveng.sourceforge.net/crc-catalogue/16.htm.

Thanks to everyone who sent positive energy my way.

1
  • Good job. I've always said perseverance is one of the most important traits of any reverse engineer. Too many give up when they're a lot closer to the solution than they think. Nov 25, 2014 at 18:07
0

I wrote my own CRC brute-forcing program in 2004, but it is quite specialized to a specific problem. There's a much better general-purpose one available as open source at https://github.com/sitsec/bruteforce-crc

You should be able to collect a few different samples of transmitted packets and feed them through this program. For a 16-bit CRC it's reasonably fast. I haven't tried it for longer CRCs.

4
  • I have looked at that program but I don't have the boost libraries installed and I don't have a C compiler to compile them. Nov 20, 2014 at 22:44
  • I have performed what I think is the same function using RevEng. I found that there is no common algorithm among these and other messages. That is, for one message I get a algorithm like: poly=0x440b init=0xf14a refin=false refout=false xorout=0x0000 while with another message, I get: poly=0x17d3 init=0x2aa1 refin=true refout=true xorout=0x0000 Nov 20, 2014 at 22:51
  • Does RevEng try different initialization and final XOR values, normal and reflected structure, etc.? If it does, and there was no commonality, that would suggest that their check isn't a true CRC.
    – Eric Smith
    Nov 21, 2014 at 22:32
  • Yes, RevEng will try all init and XorOut values in its search. Nov 24, 2014 at 22:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.