首页
社区
课程
招聘
[原创]一次小米手环BLE通信协议的逆向之旅
发表于: 2020-5-5 23:06 12540

[原创]一次小米手环BLE通信协议的逆向之旅

2020-5-5 23:06
12540

​ 纯逆向新手,接触逆向两个月左右。

​ 手头有一个小米手环4NFC版本,内置小爱同学,能够语音对话,进而控制智能家居,做一些操作如设置闹钟等。因对其实现原理好奇,并且想拓展其功能,遂逆向。百度只有Miband3之前的研究,到了Miband4的新功能,我应该还是第一个。

​ 首先,要想使用小米手环中的语音助手,手环必须和手机保持连接,并且小米运动APP要保持后台运行。很显然,小米手环并没有内置语音识别的功能,猜测其应该是将声音传感器的数据发送给手机,然后手机进行语音识别,自然语义处理之后再发送给手环。

​ 而在安卓中,想要实现BLE(低功耗蓝牙)通讯,必须要调用

​ 具体API可以参考Google的

​ 我们就从这里开始入手。

​ 我们使用Jadx打开小米运动APP,查看其源代码,发现大部分代码混淆得有点厉害,不过这不是问题。

​ 我们直接使用代码搜索功能搜索“writeCharacteristic”,发现了我们想要的结果。

​ 此处省略代码查找过程,最终我们找到了实际发送字节流的函数。

​ 我们继续向上查找引用,或许可以直接通过静态分析就知道它的数据包结构呢?结果...

​ Jadx反编译失败了...Emm....不管了,直接Hook吧。

​ 我们可以通过Hook发送数据包的函数,获取它到底发送了啥。当然也可以直接Hook安卓API,防止遗漏。这里我们这里选择了后者。

​ 成功了!这些包的结构都很明显,大部分都是字符串和一些整数,且没有加密,通过多次对比和猜测就能知道,就不深入讲了。接下来我们重点分析小爱同学的通讯协议和小米手环认证算法。

​ 为了抓到小爱同学的交互包,我们还需要Hook蓝牙的读取字节流的函数。在安卓里面,这个过程是通过Callback实现的,那我们需要Hook那个Callback函数。稍微一查就找到了:

​ 这样我们也能抓到从手环发到APP的包了:

​ 因为我正向开发的经验还比较多,这里直接猜测就知道,前几个包仅涉及到一些状态的交换,如开始录音,切换UI等。后面的声音数据的解密才是重点。

​ 我观察这些声音数据包,发现第一个字节代表数据包类型,第二个字节代表数据包序号,应该是防止乱序之类的(不知道BLE有没有乱序这一说)。接下来应该是声音数据,初步猜测是PCM,事实证明不是,还有一层编码。打印调用堆栈似乎是不可行的,我这里继续静态分析APP。

​ 通过搜索一些关键词,我找到一些有意思的ENUM。

​ 注意,这里向下追溯onCharacteristicChanged函数是没用的,因为大多数APP都是用Intent间接传递参数的,并不是直接调用解密函数。

​ 我们只要向上查找这个枚举的引用,就找到了解析语音数据包的代码。

​ 嗯,看来是找对了。

​ 这里是解密函数,可以看到他在遍历一个数组,先将元素写到一个文件中,接着又调用了另一个函数,我们跟进去看看。

​ 这里果然调用了一个decode函数,并且通过字符串我们知道最后的格式应该是pcm,16k。解密之前应该是opus。

​ 发现他调用了一个so,不过opus的解密代码是开源的,我们直接用开源库写一个demo试试。

​ 成功了!这样我们就完成了从声音数据的捕获到声音数据的解密。

​ 小爱同学等相关功能在未认证的情况下是不能使用的,所以有一个认证过程。

​ 这个网上也有相关的文章,静态动态结合分析就行了,不过提醒一点,那个验证包的一个参数貌似变了,跟我网上搜索的文章讲的不一样。主要就是AES算法的data和key。

​ 分析这个APP很简单,整个过程花费了一个下午,也没啥复杂的加密流程,软件本身也没保护,但还是学到很多,比如:

从软件调用的API考虑,向上回溯查找

关键词查找

动态静态结合分析

掌握一些软件设计模式(软件工程这门学问),APP正向开发思路,能更快更好的猜想。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 10
支持
分享
打赏 + 5.00雪花
打赏次数 1 雪花 + 5.00
 
赞赏  一位没有留下痕迹的看雪读者   +5.00 2020/09/01 有没有获取睡眠和运动步数的特征
最新回复 (18)
雪    币: 26205
活跃值: (63302)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
2
文章很精彩!最后的手环很有意思
2020-5-5 23:36
0
雪    币: 222
活跃值: (185)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
3
指甲该剪一下了
2020-5-6 00:46
0
雪    币: 6573
活跃值: (3893)
能力值: (RANK:200 )
在线值:
发帖
回帖
粉丝
4
有才!
2020-5-6 10:01
0
雪    币: 403
活跃值: (798)
能力值: ( LV4,RANK:58 )
在线值:
发帖
回帖
粉丝
5
大佬牛逼,学习了
2020-5-6 10:35
0
雪    币: 1790
活跃值: (3786)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
写一个DEMO直接GITHUB开源发出来呗。这样大家可以利用下。
2020-5-6 11:01
0
雪    币: 1841
活跃值: (1290)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
7
学习了,感谢分享
2020-5-6 11:18
0
雪    币: 7048
活跃值: (3527)
能力值: ( LV12,RANK:340 )
在线值:
发帖
回帖
粉丝
8
牛逼, 感谢分享~~~
2020-5-6 12:01
0
雪    币: 2314
活跃值: (2205)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
9
厉害了,学习下。
2020-5-6 14:31
0
雪    币: 2677
活跃值: (5340)
能力值: ( LV10,RANK:177 )
在线值:
发帖
回帖
粉丝
10
哈哈哈哈,最后一句神了
2020-5-6 16:56
0
雪    币: 58
活跃值: (1130)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
这个音频软件是什么工具?
2020-5-8 09:31
0
雪    币: 2719
活跃值: (1595)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
当我看到日志的那一瞬间  我发现了  什么  
2020-5-8 09:40
0
雪    币: 26205
活跃值: (63302)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
13


楼主文章一稿多投,其他平台公众号原创声明了,看雪公众号排好版,本想发送,结果没通过原创检测,今晚得加班了~




2020-5-8 18:18
0
雪    币: 1293
活跃值: (621)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
14
Editor 楼主文章一稿多投,其他平台公众号原创声明了,看雪公众号排好版,本想发送,结果没通过原创检测,今晚得加班了~
我傻了,吾爱这手速是真快。
2020-5-8 18:23
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
16
部分数据段解码出现b'corrupted stream'
2020-5-11 08:06
0
雪    币: 1293
活跃值: (621)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
17
wx_末 部分数据段解码出现b'corrupted stream'[em_2]
不要用他写的那个python代码奥,数据和代码都有bug,你试试我写的C#代码。
https://github.com/FinchZ/OpusMibandVoiceAlgo.git
2020-5-11 08:15
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
18
我用noble写的,调用他的python代码,我传输数据给python执行,后面我把strip()这个去掉就可以了,可以用手环语音控制我们的程序了
2020-5-11 10:39
0
雪    币: 59
活跃值: (283)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19

我在52刚看完这篇,赶紧翻到最后看看手环文字可换了没有

最后于 2020-5-18 16:42 被leezn编辑 ,原因:
2020-5-18 16:40
0
游客
登录 | 注册 方可回帖
返回
//