逆向工程"checksum"代
Reverse engineering "checksum" generation
我一直在分析一些 230V 通信并试图找出协议的校验和算法。据我了解,通信结构如下:
- 第一个块始终相同,必须是某种起始结构 (910hex)
- 那么嵌套5块(每块4bit)就是实际数据
- 最后8bit必须是校验和
我不确定校验和是否仅针对数据或起始结构(十六进制为 910h)计算
我附上了一些通讯信息,每一行都是一条信息。
我尝试过 CheckSum8 Xor
、CheckSum8 Modulo 256
和 CheckSum8 2s Complement
等算法;不幸的是没有任何运气。
| Start structure | Data | ChkSum |
00000100100010000 1010 1010 1010 1010 1011 10001100
00000100100010000 1010 1010 1010 1010 1001 01111100
00000100100010000 1010 1010 1010 1010 1101 01110010
00000100100010000 1010 1010 1010 1010 0101 01101110
00000100100010000 1010 1010 1010 1011 0101 01010110
00000100100010000 1010 1010 1010 1001 0101 00100110
00000100100010000 1010 1010 1010 1101 0101 11000110
00000100100010000 1010 1010 1010 0101 0101 11101000
00000100100010000 1010 1010 1011 0101 0101 10110100
00000100100010000 1010 1010 1001 0101 0101 00001100
00000100100010000 1010 1010 1101 0101 0101 10010010
00000100100010000 1010 1010 0101 0101 0101 01000000
00000100100010000 1010 1011 0101 0101 0101 00001010
00000100100010000 1010 1001 0101 0101 0101 10011110
00000100100010000 1010 1101 0101 0101 0101 01011000
00000100100010000 1010 0101 0101 0101 0101 00111010
00000100100010000 1011 0101 0101 0101 0101 11111110
00000100100010000 1001 0101 0101 0101 0101 10011000
00000100100010000 1101 0101 0101 0101 0101 01010100
00000100100010000 0101 0101 0101 0101 0101 00100010
更新:
我现在取得了更大的进步,目前我不再确定它是校验和还是 CRC。我已经生成并发送了从 0 到 34 的数据值,系统生成了以下“校验和”
到目前为止我学到了什么:
- 高半字节(上半字节)仅第二次变化
- 低半字节与 1010 异或,因此第 3 位和第 1 位发生变化(并非总是如此)
- 高半字节每隔一秒反转一次(不总是)
- “校验和”的位 0 总是 0
最后的HEX-Column是HEX中的Checksum值
| Start structure | Data | ?ChkSum? | HEX |
00 00000100100010000 0000 0000 0000 0000 0000 1011 1000 B8
01 00000100100010000 0000 0000 0000 0000 0001 1011 0010 B2
02 00000100100010000 0000 0000 0000 0000 0010 0100 1000 48
03 00000100100010000 0000 0000 0000 0000 0011 0100 0010 42
04 00000100100010000 0000 0000 0000 0000 0100 1011 0110 B6
05 00000100100010000 0000 0000 0000 0000 0101 1011 1100 BC
06 00000100100010000 0000 0000 0000 0000 0110 0100 0110 46
07 00000100100010000 0000 0000 0000 0000 0111 0100 1100 4C
08 00000100100010000 0000 0000 0000 0000 1000 1010 0100 A4
09 00000100100010000 0000 0000 0000 0000 1001 1010 1110 AE
10 00000100100010000 0000 0000 0000 0000 1010 0101 0100 54
11 00000100100010000 0000 0000 0000 0000 1011 0101 1110 5E
12 00000100100010000 0000 0000 0000 0000 1100 1010 1010 AA
13 00000100100010000 0000 0000 0000 0000 1101 1010 0000 A0
14 00000100100010000 0000 0000 0000 0000 1110 0101 1010 5A
15 00000100100010000 0000 0000 0000 0000 1111 0101 0000 50
16 00000100100010000 0000 0000 0000 0001 0000 1000 0000 80
17 00000100100010000 0000 0000 0000 0001 0001 1000 1010 8A
18 00000100100010000 0000 0000 0000 0001 0010 0111 0000 70
19 00000100100010000 0000 0000 0000 0001 0011 0111 1010 7A
20 00000100100010000 0000 0000 0000 0001 0100 1000 1110 8E
21 00000100100010000 0000 0000 0000 0001 0101 1000 0100 84
22 00000100100010000 0000 0000 0000 0001 0110 0111 1110 7E
23 00000100100010000 0000 0000 0000 0001 0111 0111 0100 74
24 00000100100010000 0000 0000 0000 0001 1000 1001 1100 9C
25 00000100100010000 0000 0000 0000 0001 1001 1001 0110 96
26 00000100100010000 0000 0000 0000 0001 1010 0110 1100 6C
27 00000100100010000 0000 0000 0000 0001 1011 0110 0110 66
28 00000100100010000 0000 0000 0000 0001 1100 1001 0010 92
29 00000100100010000 0000 0000 0000 0001 1101 1001 1000 98
30 00000100100010000 0000 0000 0000 0001 1110 0110 0010 62
31 00000100100010000 0000 0000 0000 0001 1111 0110 1000 68
32 00000100100010000 0000 0000 0000 0010 0000 1100 1000 C8
33 00000100100010000 0000 0000 0000 0010 0001 1100 0010 C2
34 00000100100010000 0000 0000 0000 0010 0010 0011 1000 38
更新 2:
我现在已经生成了数据,其中只有一位数据结构是 1
| Dec | Start structure | Data | ?ChkSum? | HEX |
00 00000100100010000 0000 0000 0000 0000 0000 1011 1000 B8
01 00000100100010000 0000 0000 0000 0000 0001 1011 0010 B2
02 00000100100010000 0000 0000 0000 0000 0010 0100 1000 48
04 00000100100010000 0000 0000 0000 0000 0100 1011 0110 B6
08 00000100100010000 0000 0000 0000 0000 1000 1010 0100 A4
16 00000100100010000 0000 0000 0000 0001 0000 1000 0000 80
32 00000100100010000 0000 0000 0000 0010 0000 1100 1000 C8
64 00000100100010000 0000 0000 0000 0100 0000 0101 1000 58
128 00000100100010000 0000 0000 0000 1000 0000 1001 0110 96
256 00000100100010000 0000 0000 0001 0000 0000 1110 0100 E4
512 00000100100010000 0000 0000 0010 0000 0000 0000 0000 00
1024 00000100100010000 0000 0000 0100 0000 0000 0010 0110 26
2048 00000100100010000 0000 0000 1000 0000 0000 0110 1010 6A
4096 00000100100010000 0000 0001 0000 0000 0000 1111 0010 F2
8192 00000100100010000 0000 0010 0000 0000 0000 0010 1100 2C
16384 00000100100010000 0000 0100 0000 0000 0000 0111 1110 7E
32768 00000100100010000 0000 1000 0000 0000 0000 1101 1010 DA
65536 00000100100010000 0001 0000 0000 0000 0000 0111 1100 7C
131072 00000100100010000 0010 0000 0000 0000 0000 1101 1110 DE
262144 00000100100010000 0100 0000 0000 0000 0000 0111 0100 74
524288 00000100100010000 1000 0000 0000 0000 0000 1100 1110 CE
我想我已经破解了这个。它是这样工作的:
从您的 20 个输入位和 运行ning 0b10111000
(0x8B) 的初始结果开始。
20 个输入位中的每一个都有一个恒定的 8 位掩码。对于每个具有 1
值的输入位,您希望将当前 运行ning 结果与该位的 8 位掩码进行异或。
C中的解决方案:
const UINT8 bitMasks[20] = {
0b00001010,
0b11110000,
0b00001110,
0b00011100,
0b00111000,
0b01110000,
0b11100000,
0b00101110,
0b01011100,
0b10111000,
0b10011110,
0b11010010,
0b01001010,
0b10010100,
0b11000110,
0b01100010,
0b11000100,
0b01100110,
0b11011100,
0b01110110
};
UINT8 ComputeWeirdHash(UINT32 inBits)
{
UINT8 result = 0b10111000;
for (i=0; i<20; i++)
{
if (inBits & (1L << i))
result ^= bitMasks[i];
}
return result;
}
现在,要找到每个 bitMask
值,请使用只有一位 1
的输入。然后运行它通过你的测试系统找到8位校验和。将结果与我们的初始 运行ning 结果值异或:0b10111000
,以找到 bitMask
值。
我一直在分析一些 230V 通信并试图找出协议的校验和算法。据我了解,通信结构如下:
- 第一个块始终相同,必须是某种起始结构 (910hex)
- 那么嵌套5块(每块4bit)就是实际数据
- 最后8bit必须是校验和
我不确定校验和是否仅针对数据或起始结构(十六进制为 910h)计算
我附上了一些通讯信息,每一行都是一条信息。
我尝试过 CheckSum8 Xor
、CheckSum8 Modulo 256
和 CheckSum8 2s Complement
等算法;不幸的是没有任何运气。
| Start structure | Data | ChkSum |
00000100100010000 1010 1010 1010 1010 1011 10001100
00000100100010000 1010 1010 1010 1010 1001 01111100
00000100100010000 1010 1010 1010 1010 1101 01110010
00000100100010000 1010 1010 1010 1010 0101 01101110
00000100100010000 1010 1010 1010 1011 0101 01010110
00000100100010000 1010 1010 1010 1001 0101 00100110
00000100100010000 1010 1010 1010 1101 0101 11000110
00000100100010000 1010 1010 1010 0101 0101 11101000
00000100100010000 1010 1010 1011 0101 0101 10110100
00000100100010000 1010 1010 1001 0101 0101 00001100
00000100100010000 1010 1010 1101 0101 0101 10010010
00000100100010000 1010 1010 0101 0101 0101 01000000
00000100100010000 1010 1011 0101 0101 0101 00001010
00000100100010000 1010 1001 0101 0101 0101 10011110
00000100100010000 1010 1101 0101 0101 0101 01011000
00000100100010000 1010 0101 0101 0101 0101 00111010
00000100100010000 1011 0101 0101 0101 0101 11111110
00000100100010000 1001 0101 0101 0101 0101 10011000
00000100100010000 1101 0101 0101 0101 0101 01010100
00000100100010000 0101 0101 0101 0101 0101 00100010
更新: 我现在取得了更大的进步,目前我不再确定它是校验和还是 CRC。我已经生成并发送了从 0 到 34 的数据值,系统生成了以下“校验和”
到目前为止我学到了什么:
- 高半字节(上半字节)仅第二次变化
- 低半字节与 1010 异或,因此第 3 位和第 1 位发生变化(并非总是如此)
- 高半字节每隔一秒反转一次(不总是)
- “校验和”的位 0 总是 0
最后的HEX-Column是HEX中的Checksum值
| Start structure | Data | ?ChkSum? | HEX |
00 00000100100010000 0000 0000 0000 0000 0000 1011 1000 B8
01 00000100100010000 0000 0000 0000 0000 0001 1011 0010 B2
02 00000100100010000 0000 0000 0000 0000 0010 0100 1000 48
03 00000100100010000 0000 0000 0000 0000 0011 0100 0010 42
04 00000100100010000 0000 0000 0000 0000 0100 1011 0110 B6
05 00000100100010000 0000 0000 0000 0000 0101 1011 1100 BC
06 00000100100010000 0000 0000 0000 0000 0110 0100 0110 46
07 00000100100010000 0000 0000 0000 0000 0111 0100 1100 4C
08 00000100100010000 0000 0000 0000 0000 1000 1010 0100 A4
09 00000100100010000 0000 0000 0000 0000 1001 1010 1110 AE
10 00000100100010000 0000 0000 0000 0000 1010 0101 0100 54
11 00000100100010000 0000 0000 0000 0000 1011 0101 1110 5E
12 00000100100010000 0000 0000 0000 0000 1100 1010 1010 AA
13 00000100100010000 0000 0000 0000 0000 1101 1010 0000 A0
14 00000100100010000 0000 0000 0000 0000 1110 0101 1010 5A
15 00000100100010000 0000 0000 0000 0000 1111 0101 0000 50
16 00000100100010000 0000 0000 0000 0001 0000 1000 0000 80
17 00000100100010000 0000 0000 0000 0001 0001 1000 1010 8A
18 00000100100010000 0000 0000 0000 0001 0010 0111 0000 70
19 00000100100010000 0000 0000 0000 0001 0011 0111 1010 7A
20 00000100100010000 0000 0000 0000 0001 0100 1000 1110 8E
21 00000100100010000 0000 0000 0000 0001 0101 1000 0100 84
22 00000100100010000 0000 0000 0000 0001 0110 0111 1110 7E
23 00000100100010000 0000 0000 0000 0001 0111 0111 0100 74
24 00000100100010000 0000 0000 0000 0001 1000 1001 1100 9C
25 00000100100010000 0000 0000 0000 0001 1001 1001 0110 96
26 00000100100010000 0000 0000 0000 0001 1010 0110 1100 6C
27 00000100100010000 0000 0000 0000 0001 1011 0110 0110 66
28 00000100100010000 0000 0000 0000 0001 1100 1001 0010 92
29 00000100100010000 0000 0000 0000 0001 1101 1001 1000 98
30 00000100100010000 0000 0000 0000 0001 1110 0110 0010 62
31 00000100100010000 0000 0000 0000 0001 1111 0110 1000 68
32 00000100100010000 0000 0000 0000 0010 0000 1100 1000 C8
33 00000100100010000 0000 0000 0000 0010 0001 1100 0010 C2
34 00000100100010000 0000 0000 0000 0010 0010 0011 1000 38
更新 2: 我现在已经生成了数据,其中只有一位数据结构是 1
| Dec | Start structure | Data | ?ChkSum? | HEX |
00 00000100100010000 0000 0000 0000 0000 0000 1011 1000 B8
01 00000100100010000 0000 0000 0000 0000 0001 1011 0010 B2
02 00000100100010000 0000 0000 0000 0000 0010 0100 1000 48
04 00000100100010000 0000 0000 0000 0000 0100 1011 0110 B6
08 00000100100010000 0000 0000 0000 0000 1000 1010 0100 A4
16 00000100100010000 0000 0000 0000 0001 0000 1000 0000 80
32 00000100100010000 0000 0000 0000 0010 0000 1100 1000 C8
64 00000100100010000 0000 0000 0000 0100 0000 0101 1000 58
128 00000100100010000 0000 0000 0000 1000 0000 1001 0110 96
256 00000100100010000 0000 0000 0001 0000 0000 1110 0100 E4
512 00000100100010000 0000 0000 0010 0000 0000 0000 0000 00
1024 00000100100010000 0000 0000 0100 0000 0000 0010 0110 26
2048 00000100100010000 0000 0000 1000 0000 0000 0110 1010 6A
4096 00000100100010000 0000 0001 0000 0000 0000 1111 0010 F2
8192 00000100100010000 0000 0010 0000 0000 0000 0010 1100 2C
16384 00000100100010000 0000 0100 0000 0000 0000 0111 1110 7E
32768 00000100100010000 0000 1000 0000 0000 0000 1101 1010 DA
65536 00000100100010000 0001 0000 0000 0000 0000 0111 1100 7C
131072 00000100100010000 0010 0000 0000 0000 0000 1101 1110 DE
262144 00000100100010000 0100 0000 0000 0000 0000 0111 0100 74
524288 00000100100010000 1000 0000 0000 0000 0000 1100 1110 CE
我想我已经破解了这个。它是这样工作的:
从您的 20 个输入位和 运行ning
0b10111000
(0x8B) 的初始结果开始。20 个输入位中的每一个都有一个恒定的 8 位掩码。对于每个具有
1
值的输入位,您希望将当前 运行ning 结果与该位的 8 位掩码进行异或。
C中的解决方案:
const UINT8 bitMasks[20] = {
0b00001010,
0b11110000,
0b00001110,
0b00011100,
0b00111000,
0b01110000,
0b11100000,
0b00101110,
0b01011100,
0b10111000,
0b10011110,
0b11010010,
0b01001010,
0b10010100,
0b11000110,
0b01100010,
0b11000100,
0b01100110,
0b11011100,
0b01110110
};
UINT8 ComputeWeirdHash(UINT32 inBits)
{
UINT8 result = 0b10111000;
for (i=0; i<20; i++)
{
if (inBits & (1L << i))
result ^= bitMasks[i];
}
return result;
}
现在,要找到每个 bitMask
值,请使用只有一位 1
的输入。然后运行它通过你的测试系统找到8位校验和。将结果与我们的初始 运行ning 结果值异或:0b10111000
,以找到 bitMask
值。