查找 hash/crc32 已知哈希值和原始值的算法
Find hash/crc32 algorithm with known hash value and original value
如果此类问题在这里不被允许或不合适,我深表歉意,在这种情况下请删除我的问题。
我正在尝试对两个嵌入式设备之间的协议进行逆向工程。他们发送多播 UDP 数据包。
UDP 数据包中的有效负载部分如下所示:
00000000: 00 00 00 01 5d 28 52 c5 26 30 30 3a 30 32 3a 39 |....](R.&00:02:9|
00000010: 42 3a 39 33 3a 34 41 3a 38 34 26 31 32 39 26 31 |B:93:4A:84&129&1|
我发现有效载荷部分包括
- 前 4 个二进制字节总是:00 00 00 01
- 接下来的 4 个二进制字节是某种类型的 hash/crc32(我猜)[上面:5d 28 52 c5]
- 纯文本中的下一个 1+17 字节是一个 MAC-地址 [以上:&00:02:9B:93:4A:84]
- 纯文本中接下来的 1+3 个字节是值为 128-136 的命令[以上:&129]
- 纯文本中接下来的 1+(1-3) 个字节是 0-254 之间的序列号[以上:&1]
MAC-address 可以是如上所示的始终不变的地址(即多播 UDP 数据包接收设备的 MAC-address)或 &FF:FF:FF: FF:FF:FF 在接收设备未知时用作广播。
广播 MAC 地址(和另一个命令值)的另一个示例如下所示:
00000000: 00 00 00 01 95 46 84 1e 26 46 46 3a 46 46 3a 46 |.....F..&FF:FF:F|
00000010: 46 3a 46 46 3a 46 46 3a 46 46 26 31 32 38 26 31 |F:FF:FF:FF&128&1|
这里的hash/crc是:95 46 84 1e
相同的 MAC 地址、相同的命令值和相同的序列号的组合在不同的 UDP 数据包中以一定的时间间隔重复,并且总是会产生相同的 hash/crc。
所以我的猜测是 hash/crc 在某种程度上只取决于 MAC 地址的值、命令值和序列号。
我试过 Slavesoft 的免费 windows hash/crc 计算器 HashCalc,但我无法获得相同的计算器 hash/crc,甚至删除了符号和冒号的任何组合。
我还尝试了一种名为 djb2 的哈希算法,发现 here and here。
但是我无法弄清楚hash/crc算法,因此我需要更多知识的人的帮助。
我需要帮助才能首先找到如何根据 mac 地址、命令和序列号计算 4 字节 hash/crc 的算法。
其次,找到算法后我还需要一个实现,最好是在Python。
任何帮助将不胜感激,如果您能为我指出正确的方向以寻找和了解更多信息,我们将不胜感激。
我还有一个包含更多示例的小文件 (19 kB),但我不知道如何附加它以及是否需要它。
如果能得到所有帮助,我将不胜感激。
您可以使用 CRC RevEng 来搜索 CRC。这个结果很简单,因为它是标准的 CRC:
% ./reveng -w 32 -s 2630303a30323a39423a39333a34413a38342631323926315d2852c5
width=32 poly=0x04c11db7 init=0xffffffff refin=false refout=false xorout=0x00000000 check=0x0376e6e7 name="CRC-32/MPEG-2"
% ./reveng -w 32 -s 2646463a46463a46463a46463a46463a46462631323826319546841e
width=32 poly=0x04c11db7 init=0xffffffff refin=false refout=false xorout=0x00000000 check=0x0376e6e7 name="CRC-32/MPEG-2"
这将计算 CRC:
#include <stddef.h>
#include <stdint.h>
#define POLY 0x04c11db7
/* Compute CRC of buf[0..len-1] with initial CRC crc. This permits the
computation of a CRC by feeding this routine a chunk of the input data at a
time. The value of crc for the first chunk should be 0xffffffff. */
uint32_t crc32c(uint32_t crc, const unsigned char *buf, size_t len)
{
int k;
while (len--) {
crc ^= (uint32_t)(*buf++) << 24;
for (k = 0; k < 8; k++)
crc = crc & 0x80000000 ? (crc << 1) ^ POLY : crc << 1;
}
return crc;
}
如果此类问题在这里不被允许或不合适,我深表歉意,在这种情况下请删除我的问题。
我正在尝试对两个嵌入式设备之间的协议进行逆向工程。他们发送多播 UDP 数据包。
UDP 数据包中的有效负载部分如下所示:
00000000: 00 00 00 01 5d 28 52 c5 26 30 30 3a 30 32 3a 39 |....](R.&00:02:9|
00000010: 42 3a 39 33 3a 34 41 3a 38 34 26 31 32 39 26 31 |B:93:4A:84&129&1|
我发现有效载荷部分包括
- 前 4 个二进制字节总是:00 00 00 01
- 接下来的 4 个二进制字节是某种类型的 hash/crc32(我猜)[上面:5d 28 52 c5]
- 纯文本中的下一个 1+17 字节是一个 MAC-地址 [以上:&00:02:9B:93:4A:84]
- 纯文本中接下来的 1+3 个字节是值为 128-136 的命令[以上:&129]
- 纯文本中接下来的 1+(1-3) 个字节是 0-254 之间的序列号[以上:&1]
MAC-address 可以是如上所示的始终不变的地址(即多播 UDP 数据包接收设备的 MAC-address)或 &FF:FF:FF: FF:FF:FF 在接收设备未知时用作广播。
广播 MAC 地址(和另一个命令值)的另一个示例如下所示:
00000000: 00 00 00 01 95 46 84 1e 26 46 46 3a 46 46 3a 46 |.....F..&FF:FF:F|
00000010: 46 3a 46 46 3a 46 46 3a 46 46 26 31 32 38 26 31 |F:FF:FF:FF&128&1|
这里的hash/crc是:95 46 84 1e
相同的 MAC 地址、相同的命令值和相同的序列号的组合在不同的 UDP 数据包中以一定的时间间隔重复,并且总是会产生相同的 hash/crc。 所以我的猜测是 hash/crc 在某种程度上只取决于 MAC 地址的值、命令值和序列号。
我试过 Slavesoft 的免费 windows hash/crc 计算器 HashCalc,但我无法获得相同的计算器 hash/crc,甚至删除了符号和冒号的任何组合。
我还尝试了一种名为 djb2 的哈希算法,发现 here and here。
但是我无法弄清楚hash/crc算法,因此我需要更多知识的人的帮助。 我需要帮助才能首先找到如何根据 mac 地址、命令和序列号计算 4 字节 hash/crc 的算法。
其次,找到算法后我还需要一个实现,最好是在Python。
任何帮助将不胜感激,如果您能为我指出正确的方向以寻找和了解更多信息,我们将不胜感激。
我还有一个包含更多示例的小文件 (19 kB),但我不知道如何附加它以及是否需要它。
如果能得到所有帮助,我将不胜感激。
您可以使用 CRC RevEng 来搜索 CRC。这个结果很简单,因为它是标准的 CRC:
% ./reveng -w 32 -s 2630303a30323a39423a39333a34413a38342631323926315d2852c5
width=32 poly=0x04c11db7 init=0xffffffff refin=false refout=false xorout=0x00000000 check=0x0376e6e7 name="CRC-32/MPEG-2"
% ./reveng -w 32 -s 2646463a46463a46463a46463a46463a46462631323826319546841e
width=32 poly=0x04c11db7 init=0xffffffff refin=false refout=false xorout=0x00000000 check=0x0376e6e7 name="CRC-32/MPEG-2"
这将计算 CRC:
#include <stddef.h>
#include <stdint.h>
#define POLY 0x04c11db7
/* Compute CRC of buf[0..len-1] with initial CRC crc. This permits the
computation of a CRC by feeding this routine a chunk of the input data at a
time. The value of crc for the first chunk should be 0xffffffff. */
uint32_t crc32c(uint32_t crc, const unsigned char *buf, size_t len)
{
int k;
while (len--) {
crc ^= (uint32_t)(*buf++) << 24;
for (k = 0; k < 8; k++)
crc = crc & 0x80000000 ? (crc << 1) ^ POLY : crc << 1;
}
return crc;
}