小米手环分析

    本文地址:http://tongxinmao.com/Article/Detail/id/205

    小米手环分析

    http://www.blogjava.net/baicker/archive/2015/09/05/427125.html





    小米手环主要部件:蓝牙模块Dialog DA14580,陀螺仪ADXL362,DC-DC选用的TI的TPS62736



    认证很简单,只需要在FF04的UUID中写入20字节的值并校验通过,就可以对手环进行读写指令控制。
    其实有个更简单的,只要给Immediate Alert这个属性发送0x01或者0x02即可启动“女性娱乐模式”,不需要任何认证:
    (这个属性本来是用来可穿戴设备的找回功能的)



    如果还需要闪光,变色之类的操作,就需要填对FF04中的信息,然后向手环发送指令:

    ID-ID-ID-ID-01-11-AF-4B-00-30-30-39-00-00-00-00-00-00-00-71

    前四字节:ID(小米登录后有ID号) 
    01:性别
    11:年龄
    AF:身高(cm)
    4B:体重(kg) 
    00:忘了,可能是体重的高位字节(咳~~嗯小米考虑得很周全)
    303039:昵称(009)
    71:校验

    校验是怎么来的呢?

    前19字节的CRC8^MAC最后一位(小米的MAC一般都是880F10开头的)

    网上找了段C代码,初始化参数有点不一样,FF->00,9C->8C

    #define CRC_POLYNOM 0x8c

    #define CRC_PRESET 0x00

    #include <stdio.h>
    #include <stdlib.h>     /* strtol */

    #define CRC_POLYNOM 0x8c
    #define CRC_PRESET 0x00

    int main(int argc, char* argv[]) {
        if(argc!=21 && argc!=2){
            printf("\n\tMiband userinfo checksum by 009\n");
            printf("\t  Usage: %s [arrayOfByte] <lastBleAddr>\n", argv[0]);
            printf("\t\t%s 0x88\n", argv[0]);
            printf("\t\t%s 0xA3 0xF0 0x1D 0x28 0x01 0x20 0xAA 0x3C 0x01 0x30 0x30 0x39 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x88\n\n", argv[0]);
            return 0;
        }

        unsigned char FRAME[] = {0xA3, 0xF0, 0x1D, 0x28, 0x01, 0x20, 0xAA, 0x3C, 0x01, 0x30, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};   
        unsigned char lastAddr = strtol(argv[20],NULL,0);
        unsigned int crc = CRC_PRESET;
        if(argc==21){
            for(int i = 0; i < 19; i++)FRAME[i]=strtol(argv[i+1],NULL,0);
        }
        for(int i = 0; i < sizeof(FRAME); i++) {
            crc ^= FRAME[i];
            for(int j = 0; j < 8; j++) {
                if(crc & 0x01) {
                    crc = (crc >> 1) ^ CRC_POLYNOM;
                } else {
                    crc = (crc >> 1);
                }
            }
        }
        printf("CRC8=%02X\n", crc);
        for(i = 0; i < 19; i++)printf("%02X-", FRAME[i]);
        printf("%02X\n", crc^lastAddr);    //0x3A mac地址最后一字节
        return 0;
    }


    下面是各种UUID:

    Characteristic

    Handle

    UUID



    Des

        UUID_SERVICE_MILI_SERVICE


    FEE0



    服务

        UUID_CHARACTERISTIC_DEVICE_INFO


    FF01

    R

    88-7C-XX-XX-00-00-02-B5-00-06-00-02-30-09-00-01

    设备信息

        UUID_CHARACTERISTIC_DEVICE_NAME


    FF02

    RW

    00-60-09-4D-49

    设备名称

        UUID_CHARACTERISTIC_NOTIFICATION


    FF03

    Notify,R

    15




    0x2902

    R

    01-00

    notify

        UUID_CHARACTERISTIC_USER_INFO

    19

    FF04

    RW

    XX-XX-1D-28-01-11-AF-4B-01-30-30-39-00-00-00-00-00-00-00-71


        UUID_CHARACTERISTIC_CONTROL_POINT

    1B

    FF05

    W


    控制指令

        UUID_CHARACTERISTIC_REALTIME_STEPS


    FF06

    Notify,R

    B9-14-00-00

     步数



    0x2902

    R

    01-00

    realtimedata

        UUID_CHARACTERISTIC_ACTIVITY_DATA


    FF07

    Notify,R

    01-0F-05-11-10-06-04-00-00-00-00




    0x2902

    R

    01-00

    Data

        UUID_CHARACTERISTIC_FIRMWARE_DATA


    FF08

    W


    升级数据

        UUID_CHARACTERISTIC_LE_PARAMS


    FF09

    Notify,RW

    CC-01-F4-01-00-00-F4-01-F4-01-08-08




    0x2902

    R

    6C-65-70-61-72-61-6D

    leparam

        UUID_CHARACTERISTIC_DATE_TIME

    28

    FF0A

    RW

    0F-05-11-10-05-33-0F-05-11-10-06-05


        UUID_CHARACTERISTIC_STATISTICS


    FF0B

    RW

    00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00


        UUID_CHARACTERISTIC_BATTERY


    FF0C

    Notify,R

    1C-0F-04-0D-0A-32-33-05-00-00

    电池信息



    0x2902

    R

    01-00

    Battery

        UUID_CHARACTERISTIC_TEST

    2E

    FF0D

    RW

    B7-1D




    FF0E

    Notify,RW





    0x2902

    R

    01-00

    fulldata

    PAIR,写入02解除

    33

    FF0F

    RW

    FF-FF








    补充







    0x0014

    FF02


    01 广播 00 不广播



    电池信息:1C-0F-04-0D-0A-32-33-05-00-00
    没啥大用,第一个字节电量百分比,之后上次充电的年月日时间等。
    FF05是发送控制指令用的,常用的如下:

    UUID

    作用

    FF05

    updateFirmware

    07XXXXXX ...

    SetGoal

    0500LLHH

    SetColor

    0ERRGGBB01

    StartVibrate

    0801

    StopVibrate

    0D

    Vibrate

    0802

    Vibrate + LED

    0800

    FactoryReset

    09

    Reboot

    0C

    Sync

    0B

    左右手

    0FXX

    打开实时步数提示

    0301

    关闭实时步数提示

    0300


    例如:成功写入了如下FF04之后,



    写入完成后,向FF05写入0E06000001就设置了手环发红光。。。
    点击读FF06就会获得当前步数(好像这个值不需要写FF04也可以,懒得试了)

    另:各个固件可以随便刷,不用考虑能不能降版本的问题。手机APP只是手机端做了限制。
    如果哪位大侠分析出了固件升级时候校验是怎么校验的,望赐教,ARM逆向实在搞不定。

    不会写手机端APP,否则可以搞一些比较好(wei)玩(suo)的事情。
    以上分析不一定完全正确,有错误的地方欢迎指正。


    上一篇:Printer gadget driver
    下一篇:NanoPi M2 首次启动信息