【问题标题】:CRC Reverse Engineer (Checksum from Machine / PC)CRC 逆向工程师(来自机器/PC 的校验和)
【发布时间】:2014-04-08 19:29:27
【问题描述】:

我目前正在寻找如何确定从机器到 PC 产生的 CRC(反之亦然)。 设备正在使用串行通信或 RS232 电缆进行通信。

I do only have data to be able for us to create a program to be used for both devices.

The data given was from my boss and the program was corrupted. So we are trying for it to work out.

I hope everyone can help.

Thanks :)

【问题讨论】:

  • 您至少应该考虑,指定您认为的内容用作crc计算的src数据。您还应该检查数据的格式 - 它并不完全一致或清晰。例如,0D 0A 是什么?是 5 个 ascii 字符,还是 2 个字符,其值以十六进制表示?请注意,在您开始猜测使用的 CRC 算法和使用的种子值之前,您必须弄清楚您计算的 CRC 是什么。即 - 它是发送的任何二进制数据的 CRC,是整条线的 CRC,等等等等。摆在你面前的大任务!
  • 对不起,简短的信息,是的,带有“的字符串是字符/字符串,而十六进制数字用于 ASCII 表(例如 06 是 ACK)。我们无法预测它是整行还是特定字符。
  • 0D 0A 是 ascii 中的回车换行..
  • 好的,这是一些澄清 - 你应该编辑你的帖子以包含它。我还从你的帖子中询问你的以下 sn-p:R "RC=23947" 0D 0A 1D - 我认为@ 987654324@ 字符可供读者使用。即此代码发送 8 个 ascii 字符 RC=23497,紧随其后的是 3 个十六进制字节 0D 0A 1D。您的帖子仍然不清楚。把数据想象成一张地图——一张仍然没有键和指定符号的地图。
  • 数据怎么了?原始帖子在使用引号方面不一致。它是逐字捕获还是由人工输入(有错误和不一致)?这些字符串是实际传输的还是这些解码的消息?这些痕迹是从哪里来的?你还能运行这些程序吗?

标签: windows serial-port checksum crc


【解决方案1】:

协议中用于计算 CRC 的序列是 ASCII 字符串

  • 从第一个打印字符开始(例如 REQ 中的“R”)
  • 直到计算中包含“1E”。
  • 根据我们的CRC calculator,这是一个具有以下规格的 CRC

    CRC:16,1021,0000,0000,No,No

意思是:

CRC width: 16 bit (of course)
polynomial: 1021 HEX (truncated CRC polynomial)
init value: 0000
final Xor applied: 0000
reflectedInput: No
reflectedOutput: No`

(如果“初始值”为 FFFF,则为“CCITT 指定的 16 位宽 CRC”)。

另请参阅Docklight CRC glossaryBoost CRC library,了解 CRC 术语的含义以及示例代码。

我所做的是编写一个小脚本,在第一个简单的“REQ=INI”命令的不同部分尝试流行的 16 位 CRC,看看我最终得到的总和是否为 4255。这失败了,但是我没有全力以赴尝试各种多项式,而是认为这可能只是已知标准的古怪/有缺陷的实现,并且确实成功地通过了 CRC-CCITT 的变体。

这里有一些缓慢而简单的 C 代码(不是基于表格的!)来计算各种 CRC:

// Generic, not table-based CRC calculation 
// Based on and credits to the following:
// CRC tester v1.3 written on 4th of February 2003 by Sven Reifegerste (zorc/reflex)

unsigned long reflect (unsigned long crc, int bitnum) {

    // reflects the lower 'bitnum' bits of 'crc'
    unsigned long i, j=1, crcout=0;
    for (i=(unsigned long)1<<(bitnum-1); i; i>>=1) {
        if (crc & i) crcout|=j;
        j<<= 1;
    }
    return (crcout);
}    

calcCRC(
    const int width, const unsigned long polynominal, const unsigned long initialRemainder, 
    const unsigned long finalXOR, const int reflectedInput, const int reflectedOutput, 
    const unsigned char message[], const long startIndex, const long endIndex) 
{ 
    // Ensure the width is in range: 1-32 bits
    assert(width >= 1 && width <= 32);  
    // some constant parameters used
    const bool b_refInput = (reflectedInput > 0); 
    const bool b_refOutput = (reflectedOutput > 0); 
    const unsigned long crcmask = ((((unsigned long)1<<(width-1))-1)<<1)|1;
    const unsigned long crchighbit = (unsigned long)1<<(width-1);

    unsigned long j, c, bit;
    unsigned long crc = initialRemainder;

    for (long msgIndex = startIndex; msgIndex <= endIndex; ++msgIndex) {
        c = (unsigned long)message[msgIndex];
        if (b_refInput) c = reflect(c, 8);
        for (j=0x80; j; j>>=1) {
            bit = crc & crchighbit;
            crc<<= 1;
            if (c & j) bit^= crchighbit;
            if (bit) crc^= polynominal;
        }
    }   
    if (b_refOutput) crc=reflect(crc, width);
    crc^= finalXOR;
    crc&= crcmask;
    return(crc);
}

使用此代码和上面列出的 CRC 规范,我能够重新计算以下三个示例 CRC:

10.03.2014 22:20:57.109 [TX] - REQ=INI<CR><LF>
<RS>CRC=4255<CR><LF>
<GS>
10.03.2014 22:20:57.731 [TX] - ANS=INI<CR><LF>
STATUS=0<CR><LF>
<RS>CRC=57654<CR><LF>
<GS>
10.03.2014 22:20:59.323 [TX] - ANS=INI<CR><LF>
STATUS=0<CR><LF>
MID="CTL1"<CR><LF>
DEF="DTLREQ";1025<CR><LF>
INFO=0<CR><LF>
<RS>CRC=1683<CR><LF>
<GS>

我在非常复杂的 DEF= 部件上失败了 - 可能没有正确理解字符序列。

我用来逆向工程的 Docklight 脚本:

Sub crcReverseEngineer()
    Dim crctypes(7)

    crctypes(0) = "CRC:16,1021,FFFF,0000" ' CCITT
    crctypes(1) = "CRC:16,8005,0000,0000" ' CRC-16
    crctypes(2) = "CRC:16,8005,FFFF,0000" ' CRC-MODBUS

    ' lets try also some nonstandard variations with different init and final Xor, but stick
    ' to the known two polynoms.

    crctypes(3) = "CRC:16,1021,FFFF,FFFF"
    crctypes(4) = "CRC:16,1021,0000,FFFF"
    crctypes(5) = "CRC:16,1021,0000,0000"

    crctypes(6) = "CRC:16,8005,FFFF,FFFF"
    crctypes(7) = "CRC:16,8005,FFFF,0000"

    crcString = "06 1C 52 45 51 3D 49 4E 49 0D 0A 1E 43 52 43 3D 30 30 30 30 0D 0A 1D"

    For reflectedInOrOut = 0 To 3
        For cType = 0 To 7
            crcSpec = crctypes(cType) & "," & IIf(reflectedInOrOut Mod 2 = 1, "Yes", "No") & "," & IIf(reflectedInOrOut > 1, "Yes", "No")
            For cStart = 1 To 3
                For cEnd = 9 To (Len(crcString) + 1) / 3
                    subDataString = Mid(crcString, (cStart - 1) * 3 + 1, (cEnd - cStart + 1) * 3)
                    result = DL.CalcChecksum(crcSpec, subDataString, "H")
                    resultInt = CLng("&h" + Left(result, 2)) * 256 + CLng("&h" + Right(result, 2))
                    If resultInt = 4255 Then
                        DL.AddComment "Found it!"
                        DL.AddComment "sequence:   " & subDataString
                        DL.AddComment "CRC spec:   " & crcSpec
                        DL.AddComment "CRC result: " & result & " (Integer = " & resultInt & ")"
                        Exit Sub
                    End If
                Next
            Next
        Next
    Next
End Sub

Public Function IIf(blnExpression, vTrueResult, vFalseResult)
  If blnExpression Then
    IIf = vTrueResult
  Else
    IIf = vFalseResult
  End If
End Function

希望这会有所帮助,我很乐意提供额外信息或澄清细节。

【讨论】:

  • 很好地描述了您的方法和分析。我希望我能投票更多。
  • @OliverHeggelbacher 这太棒了..我不知道会有串行监视器和脚本程序。请问我是否需要该程序的完整许可证才能测试您提供的示例代码..
  • @OliverHeggelbacher - 关于“DEF= 部分”,机器上每次登录的数字都是递增的。但是 PC 可以确定下一个要给/发送到机器的数字。
  • @user3387293。谢谢。看,为了在你自己的代码中计算 crc,你真的只需要 C 代码(或一些类似的例子,比如来自 Boost 库)并用我找到的参数调用它。类似于 calcCRC(16, 0x1021 , 0, 0, 0, 0, , 0, )。但我也可以向您发送消息(甚至上传)Docklight 脚本/项目作为文件。任何预定义的脚本/项目都可以在 Docklight 中免费运行(评估),没有时间限制。你只是不能修改脚本。
  • @user3387293。或者使用online CRC calculator,我只是不确定它是否可以处理 ASCII 控制字符。
猜你喜欢
  • 2015-10-24
  • 2020-02-28
  • 2016-11-23
  • 1970-01-01
  • 2014-05-16
  • 2012-03-12
  • 2017-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多