Safecom TA-810 协议(CRC 有问题)

逆向工程 ollydbg 协议
2021-06-18 07:07:40

(在我发现有一个用于逆向工程的特定 stackexchange 站点之前,我也在 stackoverflow 上发布了这个问题。我的不好。原始帖子在这里:https : //stackoverflow.com/questions/26095009/need-help-reverse-engineering -a-crc16 )

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

  1. 拉取数据到官方应用中
  2. 打印所有“注册”的列表
  3. 手动将打印列表中的值输入到我们的 HR 应用程序中

这是一项可能需要几个小时的工作,我们希望看到自动化。到目前为止,官方技术支持一直令人失望,并拒绝分享任何细节。

使用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 之前,似乎是相关的。

原始应用程序代码

任何帮助将不胜感激。

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

crc出现

1个回答

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

CRC 的计算方法是每 2 个字节(每短)相加。如果结果大于短路,则将“最重要的短路”添加到“最不重要的短路”,直到结果适合短路。最后,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);
?>

感谢您的反馈!