配网请求部分协议解析
分析目标:
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<o1234512345678
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
微信小程序,科名BLE
FAQ:
如果默认使用配网工具会遇到发送密码不完整,发现发送的数据被截断
这是因为没有修改包大小(默认长度20左右)
使用科名BLE
调试可以直接调整包大小为一个比较大的值
使用BLE调试助手
,需要在连接ble后,修改mtu大小