需要帮助逆向工程CRC16

时间:2014-09-29 07:53:35

标签: reverse-engineering network-protocols crc crc16

我正在尝试连接到Safecom TA-810(徽章/注册系统),以自动计算员工每天工作的时间。目前,这是通过以下方式完成的:

  1. 将数据拉入官方应用程序
  2. 打印所有“注册”的列表
  3. 将打印列表中的值手动输入人力资源应用程序
  4. 这项工作可能需要多个小时,我们希望自动化。到目前为止,官方技术支持一直令人失望,并拒绝分享任何细节。

    使用wireshark我一直在捕获UDP传输,并且已经成功地理解了协议是如何构建的。我只是遇到了我认为是CRC字段的问题。我不知道它是如何计算的(CRC类型和参数)以及使用哪些字段...

    这是邮件标题的样子:

    D0 07 71 BC BE 3B 00 00
    
    D0 07 - Message type
    71 BC - This i believe is the CRC
    BE 3B - Some kind of session identifier. Stays the same for every message after the initial message (initial message has '00 00' as value)
    00 00 - Message number. '01 00', '02 00', '03 00'
    

    一些例子:

    Header only examples
    E8 03 17 FC 00 00 00 00 -> initial request (#0, no session nr)
    D0 07 71 BC BE 3B 00 00 -> Initial response (#0, device sends a session nr)
    4C 04 EF BF BE 3B 06 00 -> Message #6, still using the same session # as the initial response
    
    Larger example, which has data
    0B 00 07 E1 BE 3B 01 00 7E 45 78 74 65 6E 64 46 6D 74
    

    我也一直试图通过阅读原始应用程序中的反汇编代码来解决这个问题。下面的截图发生在socket.sendto之前,似乎是相关的。

    original application code

    非常感谢任何帮助。

    编辑:使用ollydbg调试应用程序取得了一些成功。在下面的屏幕截图中,CRC出现在所选行的寄存器(反向)EDX中。

    crc showing up

2 个答案:

答案 0 :(得分:0)

看看CRC RevEng。如果能够正确识别CRC正在运行的数据以及CRC的位置,则应该能够确定CRC参数。如果是CRC。

答案 1 :(得分:0)

我设法创建了一个php脚本,通过使用OllyDbg调试应用程序来进行CRC计算。

通过每2个字节(每个短字节)加起来计算CRC。如果结果大于空头,那么最重要的短期'被添加到“最不重要的短”'直到结果适合短期。最后,CRC(短)被反转。

我将添加我的php脚本以获得完整性:

<?php
function CompareHash($telegram)
{
  $telegram = str_replace(" ", "", $telegram);
  $telegram_crc = substr($telegram, 4, 4);
  $telegram = str_replace($telegram_crc, "0000", $telegram);

  echo "Telegram: ", $telegram, ', Crc: ', $telegram_crc, ' (', hexdec($telegram_crc), ')<br />';

  $crc = 0; 
  $i = 0;

  while ($i < strlen($telegram)) 
  {
    $short = substr($telegram, $i, 4);

    if (strlen($short) < 4) $short = $short . '00';

    $crc += hexdec($short);
    $i += 4;
  }

  echo "Crc: ", $crc, ', inverse: ', ~$crc;

  // Region "truncate CRC to Int16"
  while($crc > hexdec('FFFF'))
  {
    $short = $crc & hexdec ('FFFF');

    // Region "unsigned shift right by 16 bits"
    $crc = $crc >> 16;
    $crc = $crc & hexdec ('FFFF');
    // End region

    $crc =  $short + $crc;
  }
  // End region

  // Region "invert Int16"
  $crc = ~$crc;
  $crc = $crc & hexdec ('FFFF');
  // End region

  echo ', shifted ', $crc;

  if (hexdec($telegram_crc) == $crc)
  {
    echo "<br />MATCH!!! <br />";
  }
  else
  {
    echo "<br />failed .... <br />";
  }
}

$s1_full = "E8 03 17 FC 00 00 00 00";
$s2_full = "D0 07 71 BC BE 3B 00 00";
$s3_full = "D0 07 4E D4 E1 23 00 00";
$s4_full = "D0 07 35 32 BE 3B 07 00   7E 44 65 76 69 63 65  4E    61 6D 65 3D 54 41 38 31 30 00";
$s5_full = "0B 00 39 6C BE 3B 05 00   7E 52 46 43 61 72 64  4F    6E";

CompareHash($s1_full);
CompareHash($s2_full);
CompareHash($s3_full);
CompareHash($s4_full);
CompareHash($s5_full);
?>

感谢您的反馈!