导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页

    wifimanager-v2 ble配网协议分析

    T Series
    1
    1
    229
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • J
      jetpack LV 4 最后由 编辑

      配网请求部分协议解析

      分析目标:
      ssid =12345
      password =12345678
      数据包:
      Hex= 5A 6E 3C 6F 10 01 0B 01 FF 05 31 32 33 34 35 08 31 32 33 34 35 36 37 38
      String= Zn<o 1234512345678


      ble gatt接受参数函数 (234行)

      // out/t113-100ask/compile_dir/target/wifimanager-v2.0-0.1/core/src/os/linux/linkd/linkd_ble/linkd_ble.c
      void bt_blink_gatt_char_write_request_cb(gatts_char_write_req_t *char_write)
      {
      	blink_priv_t *priv = blink;
      
      	WMG_DEBUG("enter_func %d\n", __LINE__);
      	int ret = 0;
      
      	if(char_write) {
      		WMG_DEBUG("attr_handle: %d,tran_id: %d\n",char_write->attr_handle,
      			char_write->trans_id);
      		WMG_DEBUG("Value:");
      		bt_manager_hex_dump(" ", 20, (unsigned char *)char_write->value, char_write->value_len);
      	}
      
      	WMG_DEBUG("char_write->need_rsp: %d\n", char_write->need_rsp);
      	if (char_write->need_rsp) {
      		gatts_write_rsp_t data;
      		data.trans_id = char_write->trans_id;
      		data.attr_handle = char_write->attr_handle;
      		data.state = BT_GATT_SUCCESS;
      		ret = bt_manager_gatt_server_send_write_response(&data);
      		if (ret != 0)
      			WMG_DEBUG("send write response failed!\n");
      		else
      			WMG_DEBUG("send write response success!\n");
      	}
      
      	if (char_write->value_len > BLINK_MSG_LEN_MAX) {
      		WMG_DEBUG("exec blink buffer!\n");
      		return;
      	}
      
      	blink_parse_message((uint8_t *)priv->message, (uint8_t *)char_write->value, char_write->value_len, 0);
      }
      

      配网数据解析函数(471行)

      static int blink_parse_message(uint8_t *value, uint8_t *buf, uint16_t len, uint16_t offset)
      value指针,buf配网数据, len 数据长度,offset 0

      static int blink_parse_message(uint8_t *value, uint8_t *buf, uint16_t len, uint16_t offset)
      {
      	blink_priv_t *priv = blink;
      	uint8_t *message = buf;
      	uint32_t sync = (uint32_t)message[0] << 24 | (uint32_t)message[1] << 16 |
      					(uint32_t)message[2] << 8 | message[3];
      	uint8_t version = message[BLINK_MSG_VERSION_INDEX];
      
      	if (priv->status != BLINK_STATUS_COMPLETE &&
      		sync == BLINK_MSG_SYNC && version == BLINK_MSG_VERSION) {
      		WMG_DEBUG("%s %d\n", __func__, __LINE__);
      		if (message[BLINK_MSG_FMT_INDEX] == BLINK_MSG_FMT_SUBC) {
      			/* TO DO.. */
      			return -1;
      		}
      		memset(value, 0, BLINK_MSG_LEN_MAX);
      		memcpy(value + offset, buf, len);
      		*(value + offset + len) = '\0';
      
      		priv->status = BLINK_STATUS_COMPLETE;
      		sem_post(&priv->sem);
      	}
      
      	return 0;
      }
      

      uint32_t sync = (uint32_t)message[0] << 24 | (uint32_t)message[1] << 16 | (uint32_t)message[2] << 8 | message[3];

      #define BLINK_MSG_SYNC (0x5A6E3C6F)
      同步标识[0-3]:5A 6E 3C 6F

      uint8_t version = message[BLINK_MSG_VERSION_INDEX]; //BLINK_MSG_VERSION_INDEX=4
      版本号[4]:10

      FMT[5]:不为0

      未知字段[6-9]:0B 01 FF 05(ssid长度)

      bt_blink_gatt_char_write_request_cb分析结果:
      函数是用来匹配gatt特征的
      msg[0-3]: 同步标识,必须和预设相同
      msg[4]: 版本号,必须和预设相同
      msg[5]: FMT,不能为0,默认01
      msg[6-9]: 未知


      配网响应(590行)

      blink_ret_t blink_get_result(blink_result_t *result)
      {
      	blink_priv_t *priv = blink;
      	if (!priv || !result) {
      		WMG_ERROR("invalid state or param\n");
      		return BLINK_ERROR;
      	}
      	if (priv->status != BLINK_STATUS_COMPLETE) {
      		WMG_WARNG("blink not completed\n");
      		return BLINK_ERROR;
      	}
      
      	result->ssid_len = priv->message[BLINK_MSG_SSID_INDEX];
      	result->passphrase_len = priv->message[priv->message[BLINK_MSG_SSID_INDEX] + BLINK_MSG_SSID_INDEX + 1];
      
      	if (result->ssid_len > SSID_MAX_LEN || result->ssid_len == 0 ||
      		result->passphrase_len > PSK_MAX_LEN || result->passphrase_len == 0) {
      		WMG_WARNG("invalid len\n");
      		return BLINK_ERROR;
      	}
      	memcpy(result->ssid, priv->message + BLINK_MSG_SSID_INDEX + 1, result->ssid_len);
      	memcpy(result->passphrase, priv->message + priv->message[BLINK_MSG_SSID_INDEX] + BLINK_MSG_SSID_INDEX + 2, result->passphrase_len);
      	result->ssid[result->ssid_len] = '\0';
      	result->passphrase[result->passphrase_len] = '\0';
      
      	return BLINK_OK;
      }
      

      #define BLINK_MSG_SSID_INDEX (9)
      //ssid长度索引 9
      result->ssid_len = priv->message[BLINK_MSG_SSID_INDEX];
      //ssid长度

      result->passphrase_len = priv->message[priv->message[BLINK_MSG_SSID_INDEX] + BLINK_MSG_SSID_INDEX + 1];
      //密码长度=ssid长度+ssid索引+1,ssid的后一位是密码长度

      Blink逆向关键代码

      /bleService/BleDeviceAPProfile.java

      public static byte[] getAPProfile(byte b, String str, String str2) {
              byte[] bytes = str.getBytes();
              SSIDLength = (byte) bytes.length;
              if (b != (byte) 0) {
                  PasswordLength = (byte) str2.getBytes().length;
              }
              byte[] bArr = new byte[(((SSIDLength + 10) + 1) + PasswordLength)];
              System.arraycopy(syncTr, 0, bArr, 0, 4);
              bArr[4] = version;
              bArr[5] = GeneralConfig.APP_PROFILE_SEND_POLICY;
              bArr[6] = ServiceID;
              bArr[7] = GeneralConfig.APP_PROFILE_SECURITY_POLICY;
              bArr[8] = b;
              byte b2 = SSIDLength;
              bArr[9] = b2;
              System.arraycopy(bytes, 0, bArr, 10, b2);
              if (b != (byte) 0) {
                  bytes = str2.getBytes();
                  b2 = SSIDLength;
                  byte b3 = PasswordLength;
                  bArr[b2 + 10] = b3;
                  System.arraycopy(bytes, 0, bArr, b2 + 11, b3);
              }
              Log.d(TAG, "getAPProfile: ");
              return bArr;
          }
      

      /config/GeneralConfig.java

      package com.example.android.config;
      public class GeneralConfig {
          public static byte APP_BLE_DEVICE_BOND = (byte) 1;
          public static byte APP_BLE_DEVICE_FILTER = (byte) 1;
          public static String APP_BLE_DEVICE_FILTER_NAME = "Xradio Ble";
          public static byte APP_DEV_VERSION = (byte) 16;
          public static byte APP_PROFILE_SECURITY_POLICY = (byte) 1;
          public static byte APP_PROFILE_SEND_POLICY = (byte) 1;
      }
      

      配网响应部分协议解析

      在发送配网信息后客户端(手机端)会接收到如下通知数据
      分析目标:<0A0B1112>

      设置配网状态(618行)

      // out/t113-100ask/compile_dir/target/wifimanager-v2.0-0.1/core/src/os/linux/linkd/linkd_ble/linkd_ble.c
      
      #define BLINK_IND_SYNC                (0x0A)
      #define BLINK_MSG_SERVICE_ID          (0x0B)
      #define BLINK_IND_STATUS_DEFAULT      (0x10)
      #define BLINK_IND_STATUS_COMPLETE     (0x11)
      #define BLINK_IND_STATUS_CONNECT      (0x12)
      
      //(以下为618行)
      
      blink_ret_t blink_set_state(blink_state_t state)
      {
      	blink_priv_t *priv = blink;
      	WMG_WARNG("blink_set_state\n");
      	if (priv == NULL) {
      		WMG_WARNG("not init\n");
      		return BLINK_ERROR;
      	}
      
      	if (priv->indicate > 0) {
      		priv->indValue[0] = BLINK_IND_SYNC;
      		priv->indValue[1] = BLINK_MSG_SERVICE_ID;
      		priv->indValue[2] = (priv->status == BLINK_STATUS_COMPLETE) ?
      							BLINK_IND_STATUS_COMPLETE : BLINK_IND_STATUS_DEFAULT;
      		priv->indValue[3] = (state == BLINK_STATE_SUCCESS) ?
      							BLINK_IND_STATUS_CONNECT : BLINK_IND_STATUS_DEFAULT;
      
      		bt_blink_send_indication(tx_handle, &(priv->indValue[0]), sizeof(priv->indValue));
      		return BLINK_OK;
      	}
      
      	return BLINK_ERROR;
      }
      
      

      安卓逆向代码

      public static int getAPStatus(byte[] bArr) {
              if (bArr[0] == syncRe && bArr[1] == ServiceID) {
                  if (bArr[2] == 17 && bArr[3] == 18) {
                      Log.d(TAG, "getAPStatus: ok");
                      return 1;
                  }
                  Log.d(TAG, "getAPStatus: fail");
                  return 0;
              }
              Log.d(TAG, "getAPStatus: fail");
              return 0;
          }
      

      wifimanager-v2 ble配网协议

      // 发送数据
      Hex:5A 6E 3C 6F 10 01 0B 01 FF 05 31 32 33 34 35 08 31 32 33 34 35 36 37 38
      完整协议分析结果:
      5A 6E 3C 6F		// [0-3] 发送同步标识,必须和预设相同
      10			 // [4] 协议版本
      01			// [5] FMT,不能为0,默认01
      0B			// [6] ServiceID固定值
      01 			// [7] APP_PROFILE_SEND_POLICY固定值
      FF			// [8] 0xff
      05			// ssid长度
      31 32 33 34 35		// 12345 ssid
      08			// password长度
      31 32 33 34 35 36 37 38	// 12345678 password
      
      // 响应数据
      Hex:0A 0B 11 12
      0A			 [0] 通知同步标识,固定值
      0B			 [1] SERVICE_ID固定值,需要和发送数据的SERVICE_ID相同
      11			 [2] 配网完成状态,完成:0x11,失败:0x10
      12			 [3] 配网成功状态,成功:0x12,失败:0x10
      判断配网成功可以参考getAPStatus(byte[] bArr)函数
      

      验证:

      安卓app,BLE调试助手
      如果失败了,请查看底部FAQ
      e4828a5cf6f8d8b3a0ab6c51014a81c.png
      微信小程序,科名BLE
      2abc5a80531d2f8d9af0e926581a432.png

      FAQ:

      如果默认使用配网工具会遇到发送密码不完整,发现发送的数据被截断
      这是因为没有修改包大小(默认长度20左右)
      使用科名BLE调试可以直接调整包大小为一个比较大的值
      使用BLE调试助手,需要在连接ble后,修改mtu大小
      42b47303-8837-4f29-80b5-844269dc7e74-image.png

      1 条回复 最后回复 回复 引用 分享 0
      • 1 / 1
      • First post
        Last post

      Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

      行为准则 | 用户协议 | 隐私权政策