从数据中确定CRC算法 + CRC - 嵌入式应用程序。

5
我有一组数据,其中的16位校验和需要进行校正。已知校验和所在位置,但不清楚计算它们的确切区域和算法。校验和为16位,最低有效位先传输。我怀疑这是某种16位循环冗余校验码(CRC),但我还没有找到实际计算校验和的代码。
例子:
00    4E00FFFF26EC14091E00A01830393630  
10    30313131313030393030363030313030  
20    30303131313030393030363030313030  
30    30303131313030393030363030313030  
40    3030FFFF225E363436304D313037**0CE0**  
50    64000000000000008080808080800000  
60    00000000**BE6E**FC01E001EB0013010500  

校验和存储在4E和64。我不知道它们是从每个数据部分开头的第一个字的偏移开始计算,还是在此之后开始计算,或者是整个范围上的计算。我尝试了许多常见的CRC算法和多项式,但都没有成功。该应用程序没有可用的参考或规范。

这里有另一个数据部分,为了比较而具有不同的CRC。

00    4E00FFFF26C014091600A01030393132  
10    30313131313030393030313230313030  
20    30303131313030393030313230313030  
30    30303131313030393030313230313030  
40    3030FFFF225E343231324F313044**8348**  
50    64000000000000008080808080800000  
60    00000000**72F8**E001EB00130105000E01  

我的问题是,有没有人能够识别这个算法?是否有办法从数据和CRC计算出CRC多项式和其他因素?

谢谢!

编辑:

在我的反汇编中搜索常见的CRC16多项式0xA001,发现了这个函数:

34F86 ; =============== S U B R O U T I N E =======================================
34F86
34F86
34F86 Possible_Checksum:                    ; CODE XREF: MEM_EXT_4:00034FEEP
34F86                                         ; MEM_EXT_4:0003503AP ...
34F86                 mov     [-r0], r9       ; Move Word
34F88                 mov     r4, r12         ; Move Word
34F8A                 mov     r5, r13         ; Move Word
34F8C                 shr     r4, #14         ; Shift Right
34F8E                 shl     r5, #2          ; Shift Left
34F90                 or      r5, r4          ; Logical OR
34F92                 mov     r4, r12         ; Move Word
34F94                 mov     DPP0, r5        ; Move Word
34F98                 and     r4, #3FFFh      ; Logical AND
34F9C                 movb    rl3, [r4]       ; Move Byte
34F9E                 mov     DPP0, #4        ; Move Word
34FA2                 movbz   r9, rl3         ; Move Byte Zero Extend
34FA4                 mov     r15, #0         ; Move Word
34FA6
34FA6 loc_34FA6:                              ; CODE XREF: MEM_EXT_4:00034FC8j
34FA6                 mov     r4, [r14]       ; Move Word
34FA8                 xor     r4, r9          ; Logical Exclusive OR
34FAA                 and     r4, #1          ; Logical AND
34FAC                 jmpr    cc_Z, loc_34FBA ; Relative Conditional Jump
34FAE                 mov     r4, [r14]       ; Move Word
34FB0                 shr     r4, #1          ; Shift Right
34FB2                 xor     r4, #0A001h     ; Logical Exclusive OR
34FB6                 mov     [r14], r4       ; Move Word
34FB8                 jmpr    cc_UC, loc_34FC0 ; Relative Conditional Jump
34FBA ; ---------------------------------------------------------------------------
34FBA
34FBA loc_34FBA:                              ; CODE XREF: MEM_EXT_4:00034FACj
34FBA                 mov     r4, [r14]       ; Move Word
34FBC                 shr     r4, #1          ; Shift Right
34FBE                 mov     [r14], r4       ; Move Word
34FC0
34FC0 loc_34FC0:                       

这是什么背景?作业吗?逆向工程,哪些设备? - starblue
你能提供执行校验和的可执行文件吗? - codelogic
那么,这个应用程序是什么? - starblue
@codelogic 嗯,可执行文件是一个256kB的二进制文件。如果有帮助的话,我可以提供它。我已经开始反汇编它,但还没有找到校验和是如何/在哪里计算的。 - mattbarn
@starblue 这个应用程序是一个引擎控制器(也称为ECU或DME),我需要更具体吗?固件会在闪存中存储的校准数据上计算校验和以检测错误(以及像我这样尝试修改它的人)。 - mattbarn
显示剩余6条评论
2个回答

3
你发布的代码从loc_34FA6开始,基本上是以下内容:
unsigned short
crc16_update(unsigned short crc, unsigned char nextByte)
{
    crc ^= nextByte;

    for (int i = 0; i < 8; ++i) {
        if (crc & 1)
            crc = (crc >> 1) ^ 0xA001;
        else
            crc = (crc >> 1);
    }

    return crc;
}

这是使用0xA001多项式的CRC-16。一旦确定了CRC-16适用的数据范围,您需要将CRC初始化为0xFFFF,并对序列中的每个字节调用此函数。存储返回值并在下一次通过时传回它。最后返回的值就是您的最终CRC。

我不确定前言在做什么...


非常感谢!我现在正在尝试范围的组合。既然您告诉我那部分是我想象中的东西,我会重新关注反汇编。我相信我发布的代码的第一部分正在将DPP0(数据页指针)移动到校验和范围的开头。 - mattbarn
也许我漏掉了什么,但是看起来这个部分只处理一个字节。在迭代一个字节中的8位之后,返回(rets)发生了。 - Judge Maygarden
看起来你是对的。我需要从这里开始沿着交叉引用链向上移动,以查看如何调用此函数。 - mattbarn
序言设置数据页指针(DPP0),以便访问该初始字节。r13/r12用于传递30位指针,这可能意味着该特定字节位于控制器内的另一个设备中(外部EEPROM是有道理的)。 - e.James
谢谢,詹姆斯。这个特定的CPU没有任何内部ROM,所以它正在从闪存芯片加载所有的数据和代码。 - mattbarn

1
更一般地说,CRC的概念之一是,当您计算某个数据文件的CRC,然后在末尾附加CRC时,您会得到一个文件,其CRC是某个值,该值取决于文件的长度,而不是其内容。 (对于某些CRC算法,它甚至不依赖于文件长度。)
因此,如果您怀疑您正在尝试反向工程的应用程序正在使用CRC16,并且您有一个计算CRC16的程序,并且您具有相同长度的多个样本,则只需计算这些数据文件的CRC16(其中包括校验和)。 如果每次返回相同的校验和数据(对于相同长度的文件),则它们必须包含使用相同宽度和多项式的CRC校验和。
例如,我曾经不得不反向工程一些文件,其中开发人员认为通过更改两个常量来更改CRC32算法是很聪明的。 我不必找到验证校验和的目标代码,对其进行反汇编,然后硬着头皮弄清楚它。 这个简单的测试解决了它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接