首页 > 解决方案 > 对这些数据包使用什么校验和算法?

问题描述

我正在构建一个 python 库来操作我便宜的中文 iGK64 机械键盘的照明和可编程性功能,因为 Windows 驱动程序应用程序在 Linux 上不起作用。

我在 Windows VM 中运行了制造商的驱动程序应用程序并捕获了 USB 数据包以进行分析。在我空闲时间的最后几天里,我一直在分解这些数据包的内容,以确定不同的部分是什么,以及它们的作用。

到目前为止,我已经确定了这些事实:

这是一个数据包的示例:

生的:

0x220200003800E670FFFFFFFFFFFFFFFF010000020200000204000002080000021000000220000002FFFFFFFFFFFFFFFF00040002000500020006000200070002

解构:

reg: 0x22 instr: 0x02 addr: 0x0000 len: 56 (0x3800) sum: 0xE670
payload: 0xFFFFFFFFFFFFFFFF010000020200000204000002080000021000000220000002FFFFFFFFFFFFFFFF00040002000500020006000200070002

我一直在确定用于计算校验和的算法。我尝试了一些基本的异或序列和一些加/减方法,但没有一个是正确的。

他是两个几乎相同的数据包的示例,都发送到相同的寄存器,有效负载长度为零,唯一的区别是指令和地址。但是看到校验和是不同的。

原始1:

0x210201000000B63D0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

解构1:

reg: 0x21 instr: 0x02 addr: 0x0100 len: 00 (0x0000) sum: 0xB63D
payload: 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

原始2:

0x21000000000092610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

解构2:

reg: 0x21 instr: 0x00 addr: 0x0000 len: 00 (0x0000) sum: 0x9261
payload: 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

在这种情况下,这是从主机到外设的通信(写入 tr 寄存器 0x​​21,地址 0x100,零负载),然后从外设到主机(寄存器 0x​​21“ack”)。

我很确定数据包的每个属性都用于计算校验和,包括 reg id、instr、addr、len 和整个有效负载。

这里还有一些示例可能有助于阐明校验和的计算方式:

Raw3(这是一个 PING 或“活动”数据包,每秒在主机和外围设备之间发送数次):

0x0C0000000000A70D0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

解构3:

reg: 0x0C instr: 0x00 addr: 0x0000 len: 00 (0x0000) sum: 0xA70D
payload: 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Raw4(一个负载全为 0xFF):

0x220288013800BC74FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

解构4:

reg: 0x22 instr: 0x02 addr: 0x8801 len: 56 (0x3800) sum: 0xBC74 
payload 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

我有几个更大的原始通信转储,但它们对于确定校验和算法可能不再有用,而不是此处提供的示例。

任何帮助将不胜感激!

标签: pythonalgorithmusbdriverchecksum

解决方案


为了帮助其他人,我在这里添加了 Ashley 如何为原始数据提出正确的校验和

2202880138000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

Came up with 0x74BC

2202000038000000FFFFFFFFFFFFFFFF010000020200000204000002080000021000000220000002FFFFFFFFFFFFFFFF00040002000500020006000200070002

Came up with 0x70E6 on CRC-CCITT (0xFFFF)   0x70E6

现场https://www.lammertbies.nl/comm/info/crc-calculation.html

要在原始数据包中获得正确的校验和,只需从原始数据包中删除校验和,然后将其输入到 crc-calculation 站点以查找校验和类型。

这是确定校验和的代码,由stackoverflow的falsetru提供:(您需要(pip)或pip3安装crc16)

import binascii
import crc16

def crccitt(hex_string):
    byte_seq = binascii.unhexlify(hex_string)
    crc = crc16.crc16xmodem(byte_seq, 0xffff)
    return '{:04X}'.format(crc & 0xffff)

#In [387]: #crccitt('21020100000000000000000000000000000000000000000000000000000000000#000000000000000000000000000000000000000000000000000000000000000')                                                       
#Out[387]: '3DB6'

推荐阅读