Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/191.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 反向工程可编程设备-校验和?_Android_Bluetooth Lowenergy_Checksum_Crc - Fatal编程技术网

Android 反向工程可编程设备-校验和?

Android 反向工程可编程设备-校验和?,android,bluetooth-lowenergy,checksum,crc,Android,Bluetooth Lowenergy,Checksum,Crc,我正在尝试对一个可拆卸设备(万向节)进行反向工程。在嗅探btsnoop_hci.log之后,我已经成功地复制了精确的命令,以下是其中的一些命令: * AF: a55a030232200001 00 03 bd03 * TF: a55a030232200001 00 02 9c13 * HF: a55a030232200001 00 01 ff23 * LK: a55a030232200001 00 00 de33 这些命令将操作模式更改为01到03。其中有四个,所以这是有道理的。但是,最后有四

我正在尝试对一个可拆卸设备(万向节)进行反向工程。在嗅探
btsnoop_hci.log
之后,我已经成功地复制了精确的命令,以下是其中的一些命令:

* AF: a55a030232200001 00 03 bd03
* TF: a55a030232200001 00 02 9c13
* HF: a55a030232200001 00 01 ff23
* LK: a55a030232200001 00 00 de33
这些命令将操作模式更改为
01
03
。其中有四个,所以这是有道理的。但是,最后有四个字符,这是某种校验和,但我不知道是哪一种。尝试过这个,但没有成功

为什么我需要知道如何计算校验和?因为我也想通过模拟操纵杆控制电机,我不能复制粘贴数千个值并映射它们

此外,以下是电机本身的更多值:

                      (Speed 1) (Dir 1)  (Speed 2) (Dir 2) (CRC???)
a55a03000e0000050000      6f      00        00       00     f0c8   (Goes Left)
a55a03000e0000050000      ff      00        00       00     6f0e   (Goes Left Fast)
a55a03000e0000050000      96      ff        00       00     a96b   (Goes Right)

a55a03000e0000050000      01      ff        00       00     1bfc   (Goes Right Fast)
a55a03000e0000050000      00      00        01       ff     0d68   (Goes Up)
a55a03000e0000050000      00      00        ff       00     3346   (Goes Down)
更新: 我使用Reven对POLY&INIT进行暴力攻击:

第1步: 运行命令(电机命令中的最后两个字节颠倒):

步骤1-结果:

width=16  poly=0x1021  init=0xa55a  refin=false  refout=false  xorout=0x0000  check=0x0459  residue=0x0000  name=(none)
width=16  poly=0x1021  init=0xa55a  refin=false  refout=false  xorout=0x0000  check=0x0459  residue=0x0000  name=(none)
width=16  poly=0x4dd7  init=0xd565  refin=true  refout=true  xorout=0x0000  check=0x39bd  residue=0x0000  name=(none)
第二步: 运行命令(模式命令中的最后两个字节被反转):

步骤2-结果:

width=16  poly=0x1021  init=0xa55a  refin=false  refout=false  xorout=0x0000  check=0x0459  residue=0x0000  name=(none)
width=16  poly=0x1021  init=0xa55a  refin=false  refout=false  xorout=0x0000  check=0x0459  residue=0x0000  name=(none)
width=16  poly=0x4dd7  init=0xd565  refin=true  refout=true  xorout=0x0000  check=0x39bd  residue=0x0000  name=(none)
因此,很明显,poly(0x1021)&init(0xa55a)匹配于不同类型的消息

但是,如果我使用函数:

#define POLY (0x1021)
#define INIT (0xa55a)

uint16_t crc16(uint8_t * bfr, size_t size)
{
uint16_t crc = INIT;
int i;
    while(size--){
        crc ^= *bfr++;
        for(i = 0; i < 8; i++)
            /* assumes two's complement */
            crc = (crc>>1)^((0-(crc&1))&POLY);
    }
    return(crc);
}
结果应该是
139c
(从原始版本中替换),但我得到的是:
1fb1
这是生成poly&init的实际值(
a55a030232200001 00 02 9c13

更新: 重新检查所有14字节(电机)值(最后一个字节已交换),以确保:

a55a03000e00000500006f000000c8f0
a55a03000e0000050000ff0000000e6f
a55a03000e000005000096ff00006ba9
a55a03000e000005000001ff0000fc1b
a55a03000e0000050000000001ff680d
a55a03000e00000500000000ff004633
调用的命令:

reveng -w 16 -s a55a03000e00000500006f000000c8f0 a55a03000e0000050000ff0000000e6f a55a03000e000005000096ff00006ba9 a55a03000e000005000001ff0000fc1b a55a03000e0000050000000001ff680d a55a03000e00000500000000ff004633

reveng -w 16 -s a55a030232200001000303bd a55a0302322000010002139c a55a03000e00000500006f000000c8f0 a55a03000e0000050000ff0000000e6f
结果:

width=16  poly=0x1021  init=0xa55a  refin=false  refout=false  xorout=0x0000  check=0x0459  residue=0x0000  name=(none)
相应地(两个10字节和两个14字节的值):

Poly&Init必须正确。但是,当生成第一个的CRC时:

//                 a5    5a    03    00    0e    00    00    05    00    00    6f    00   00     00     f0c8 (swapped c8f0)
uint8_t bfr[] = { 0xa5, 0x5a, 0x03, 0x00, 0x0e, 0x00, 0x00, 0x05, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00 };



uint16_t crc = crc16(bfr, 14);

我得到Hex的输出:
532
。我不明白。为什么我生成Poly&Init的代码返回了错误的十六进制?

您可以对样本进行异或以减少变量的数量,因为这会消除任何初始值或最终的异或(好像两者都是0),搜索只需要查找多项式,以及它是非反射的(左移)还是反射的(右移)。对于CRC16,左移只有64k循环,右移只有64k循环。可能会得到多个似乎有效的多项式,因此需要更多的样本来确认

* AF: a55a030232200001 00 03 bd03
* TF: a55a030232200001 00 02 9c13
      0000000000000000 00 01 2110

* HF: a55a030232200001 00 01 ff23
* LK: a55a030232200001 00 00 de33
                          01 2110
起初,我假设最后2个字节被交换,所以01 2110将是01 10 21,一种常见的左移(未反射)CRC,但由于我自己的一个错误,我没有让它工作(我在其中一个检查中的大小错误)

然后我假设最后2个字节是大端字节0x2110,对于单个数据字节0x01上的左移CRC,CRC与多项式相同。但是多项式的最低有效位(位0)需要为1,0x2110的位0为0,所以我尝试了右移CRC

对导致单个数据字节=0x01的CRC为0x2110的反射多项式执行蛮力搜索时,有3种情况,但其中只有一种情况的位为15==1,0xEBB2,因此这是假定的多项式

然后对初始值和最终xor=0x0000或0xffff进行暴力搜索,以匹配所有4个示例,初始值=0xa6ab,最终xor=0x0000

位级代码示例:

typedef unsigned char   uint8_t;
typedef unsigned short uint16_t;

#define POLY (0xebb2)    /* polynomial */
#define INIT (0xa6ab)    /* initial value */
#define FXOR (0x0000)    /* final xor == xor out */

uint16_t crc16(uint8_t * bfr, size_t size)
{
uint16_t crc = INIT;
int i;
    while(size--){
        crc ^= *bfr++;
        for(i = 0; i < 8; i++)
            /* assumes two's complement */
            crc = (crc>>1)^((0-(crc&1))&POLY);
    }
    return(crc^FXOR);
}
虽然这适用于这4种情况,但我不能确定这是否是在没有更多情况下使用的实际CRC


然后我建议交换12字节和16字节消息的最后2个字节,并使用reveng。这表明0x1021的左移和多边形可能是一个多项式,因此我重复了测试,最终得到了与reveng相同的结果:

对于左移CRC,代码不同:

#define POLY (0x1021)    /* polynomial */
#define INIT (0xa55a)    /* initial value */
#define FXOR (0x0000)    /* final xor == xor out */

uint16_t crc16(uint8_t * bfr, size_t size)
{
uint16_t crc = INIT;
int i;
    while(size--){
        crc ^= ((uint16_t)(*bfr++))<<8;
        for(i = 0; i < 8; i++)
            /* assumes two's complement */
            crc = (crc<<1)^((0-(crc>>15))&POLY);
    }
    return(crc^FXOR);
}
定义多边形(0x1021)/*多项式*/ #定义初始值(0xa55a)/*初始值*/ #定义FXOR(0x0000)/*最终xor==xor out*/ uint16\U t crc16(uint8\U t*bfr,尺寸大小) { uint16_t crc=INIT; int i; 而(大小--){
crc^=((uint16_t)(*bfr++)可能函数本身有问题,或者我调用它的方式有问题。无法弄清楚那是什么…14字节的示例已经重新检查过,同时10字节/14字节也被放在了reven中。如果我使用相同的代码(我已经放在了reven中),怎么会这样呢在crc函数中,无法返回正确的crc…?@DainiusVaičiulis-看起来最常见的crc是poly=0x1021 init=0xa55a refin=false-refout=false-xorut=false-xorut=0x0000。不知怎的,我在我的蛮力搜索尝试中错过了它。你的更新解决了它!它是左移crc!谢谢!!!@DainiusVaičiulis我把原来的搜索搞砸了或者左移0x1021,因为我得到了错误的缓冲区大小。我在进行Reven时修复了这个问题。结果是一样的。对于多边形搜索,能够对两个相同大小的缓冲区进行异或消除了INIT和XFOR(好像两者都是0x0000),只需要64k循环就可以找到多边形的潜在值。我本可以先检查0x1021,因为这很常见,但64k循环速度非常快。
typedef unsigned char   uint8_t;
typedef unsigned short uint16_t;

#define POLY (0xebb2)    /* polynomial */
#define INIT (0xa6ab)    /* initial value */
#define FXOR (0x0000)    /* final xor == xor out */

uint16_t crc16(uint8_t * bfr, size_t size)
{
uint16_t crc = INIT;
int i;
    while(size--){
        crc ^= *bfr++;
        for(i = 0; i < 8; i++)
            /* assumes two's complement */
            crc = (crc>>1)^((0-(crc&1))&POLY);
    }
    return(crc^FXOR);
}
crc = crc16(bfr, 10);
if((bfr[10] == crc>>8) && (bfr[11] == crc&0xff))
    printf("match\n");
#define POLY (0x1021)    /* polynomial */
#define INIT (0xa55a)    /* initial value */
#define FXOR (0x0000)    /* final xor == xor out */

uint16_t crc16(uint8_t * bfr, size_t size)
{
uint16_t crc = INIT;
int i;
    while(size--){
        crc ^= ((uint16_t)(*bfr++))<<8;
        for(i = 0; i < 8; i++)
            /* assumes two's complement */
            crc = (crc<<1)^((0-(crc>>15))&POLY);
    }
    return(crc^FXOR);
}
#include <stdio.h>

typedef unsigned char   uint8_t;
typedef unsigned short uint16_t;

#define POLY (0x1021)           /* polynomial */
static uint16_t INIT;           /* initial value */
static uint16_t FXOR;           /* final xor == xor out */

/* left shifting crc using POLY == 0x1021 */

uint16_t crc16(uint8_t * bfr, size_t size)
{
uint16_t crc = INIT;
int i;
    while(size--){
        crc ^= (uint16_t)(*bfr++)<<8;
        for(i = 0; i < 8; i++)
            /* assumes two's complement */
            crc = (crc<<1)^((0-(crc>>15))&POLY);
    }
    return(crc^FXOR);
}

/* assume last 2 bytes are swapped versus nomral CRC */

int main(int argc, char**argv)
{
uint16_t crc;
uint8_t bfr0[] = {0xa5,0x5a,0x03,0x02,0x32,0x20,0x00,0x01,0x00,0x00,0xde,0x33};
uint8_t bfr1[] = {0xa5,0x5a,0x03,0x02,0x32,0x20,0x00,0x01,0x00,0x01,0xff,0x23};
uint8_t bfr2[] = {0xa5,0x5a,0x03,0x02,0x32,0x20,0x00,0x01,0x00,0x02,0x9c,0x13};
uint8_t bfr3[] = {0xa5,0x5a,0x03,0x02,0x32,0x20,0x00,0x01,0x00,0x03,0xbd,0x03};
uint8_t bfr4[] = {0xa5,0x5a,0x03,0x00,0x0e,0x00,0x00,0x05,0x00,0x00,0x96,0xff,0x00,0x00,0xa9,0x6b};
uint8_t bfr5[] = {0xa5,0x5a,0x03,0x00,0x0e,0x00,0x00,0x05,0x00,0x00,0x6f,0x00,0x00,0x00,0xf0,0xc8};
uint8_t bfr6[] = {0xa5,0x5a,0x03,0x00,0x0e,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0xff,0x00,0x33,0x46};
uint8_t bfr7[] = {0xa5,0x5a,0x03,0x00,0x0e,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x01,0xff,0x0d,0x68};
    FXOR = 0;
    do{
        INIT = 0;
        do{
            crc = crc16(bfr0, 10);
            if(crc != 0x33de)
                continue;
            crc = crc16(bfr1, 10);
            if(crc != 0x23ff)
                continue;
            crc = crc16(bfr2, 10);
            if(crc != 0x139c)
                continue;
            crc = crc16(bfr3, 10);
            if(crc != 0x03bd)
                continue;
            crc = crc16(bfr4, 14);
            if(crc != 0x6ba9)
                continue;
            crc = crc16(bfr5, 14);
            if(crc != 0xc8f0)
                continue;
            crc = crc16(bfr6, 14);
            if(crc != 0x4633)
                continue;
            crc = crc16(bfr7, 14);
            if(crc != 0x680d)
                continue;
            goto match0;
        }while(++INIT != 0);
    }while(++FXOR != 0);
match0:
    printf("%04x %04x\n", INIT, FXOR);
    crc = crc16(bfr0, 10);
    printf("%04x\n", crc);
    crc = crc16(bfr1, 10);
    printf("%04x\n", crc);
    crc = crc16(bfr2, 10);
    printf("%04x\n", crc);
    crc = crc16(bfr3, 10);
    printf("%04x\n", crc);
    crc = crc16(bfr4, 14);
    printf("%04x\n", crc);
    crc = crc16(bfr5, 14);
    printf("%04x\n", crc);
    crc = crc16(bfr6, 14);
    printf("%04x\n", crc);
    crc = crc16(bfr7, 14);
    printf("%04x\n", crc);
    return(0);
}