《电子技术应用》
您所在的位置:首页 > 通信与网络 > 业界动态 > 对 M6 智能健身手环进行逆向工程(上)

对 M6 智能健身手环进行逆向工程(上)

2021-08-02
来源:嘶吼专业版
关键词: 手环 逆向工程

  概述

  1、了解它的硬件

  2、弄清楚如何与它交谈

  3、转储其库存固件

  4、让它运行自定义代码,最好利用它:

  GPIO 引脚(用于输入和输出)

  彩色显示

  蓝牙低功耗 (BLE) 功能

  硬件介绍

  拆开塑料外壳,我们看到了一些有趣的东西:

  Telink TLSR8232芯片系统(SoC)

  0.96 英寸(160x80 像素)彩色显示屏

  一个约 100 mAh 的微型锂电池和 USB 充电电路

  振动电机

  一个(最有可能的)假心率传感器

  核心组件

  印刷电路板全图

  M6中的SoC是Telink TLSR8232(数据表),规格如下:

  32位中央处理器:封闭式架构(通常称为tc32,类似于ARM9,关于它的介绍并不多)和24 MHz 时钟速度;

  16kB 的 SRAM;

  512kB 内部闪存;

  用于低功耗模式的 32kHz 板载振荡器;

  用于调试和编程的 SWS(Single Wire Slave)接口;

  集成蓝牙低功耗 (BLE) 收发器;

  低功耗运行(据称在深度睡眠中约为 2 uA);

  幸运的是,就在几个月前,研究人员在其破解的小米温度计中看到了Telink芯片。此时,我用@atc1441 的替代固件重新刷了它。尽管它是不同的 SoC 模型,但这给了我一点希望和一个有价值的起点。

  焊盘

  焊盘 (Exposed-Pad),有些封装具有裸露焊盘,用来改善器件散热的焊盘。通常为非电气绝缘,可根据电连接要求将其接地或电源。

  印刷电路板底部

  印刷电路板底部

  除了万用表、数据表,我什么也没有,我试图找到这些焊盘的连接位置。这就是我想出的:

  单线(又名 SWire 或 SWS)接口

  现在我们确定了手环的核心部件,如果你之前对 ESP32 进行过编程,你可能会依赖其引导加载程序并通过 UART 与它通信。如果你之前编程或调试过 ARM 微控制器,你可能使用了 SWD(串行线调试)协议。

  在Telink-land 中,类似的接口称为Single Wire 或SWire。这就是应用程序如何加载到其闪存中、如何读取和写入内存以及如何在运行时调试的方式。

  然而,当我们尝试了解有关此界面的更多信息时,真正的挑战才刚刚开始。在现实世界中,这些芯片是使用Telink官方的调试工具进行调试的。

  研究人员在找到存储库 TlsrTools 时,其中有对 SWire 协议的两页描述。这似乎是一个旧版本的Telink数据表的一部分,已经被删除。

  从 Pascal 到 Python

  在编程/调试芯片时,通常有三个活动部分:

  我们要编程的目标板

  程序员硬件

  与程序员通信的计算机软件

  计算机软件的作用是向程序员硬件发送命令,并使其从目标板读写数据。由于研究人员手边没有Windows设备,所以我实现了一个基本的Python脚本,即 tlsr82-debugger-client.py,它作为计算机软件组件工作。

  我们现在可以使用这个 Python 脚本和 STM32 来解密 M6 手环中隐藏的信息。设置如下:

基于 STM32 的替代编程设置

  SWire 规范

  顾名思义,单线用于在两个设备之间来回传输数据。在我们的例子中,STM32 编程器(主)和目标板(附属)。没有像 SPI 或 I2C 那样单独的时钟线。单线拓扑允许两个设备通信,但它们不能同时通信。换句话说,我们可以将 SWire 称为异步、半双工接口。

  这意味着:

  异步:由于没有共享时钟,两个设备必须以某种方式采用兼容的读写速度;

  半双工:每个设备必须知道什么时候应该监听消息,什么时候允许传输消息。

  为了实现协调,SWire 协议将责任归属于主盘和附属设备。主盘负责发起通信并管理数据传输之间的总线逻辑层。从盘负责在预期的时间发送数据。下面我将一些真实世界的例子放在一起,以便更清楚地说明这一点。

  发送单个位

  首先要注意的是位是如何在线路中编码的。每个位以五个时间单位传输:

  要发送 0,请保持 1 个单元的低电压和 4 个单元的高电压;

  要发送 1,保持低电压 4 个单位时间和高电压 1 个单位;

  具体来说,这是我用逻辑分析仪捕获的真实 SWire 传输:

  SWire 中 0 和 1 的示例

  在上面的截图中,标记为 25 和 26 的标志之间有 8 位正在传输,但是很难解码。

  发送单个字节

  我们现在知道为了传输一个完整的字节,SWire 协议规定需要 9 位:

  位 1:cmd 位。0 指定消息包含数据,1 指定消息是命令;

  位 2-8:消息内容(8 位);

  低级别的一个时间单位表示消息结束;

  另外,让我们看一下 0xb0 字节的真实示例传输:

在 SWire 中发送一个字节的示例

  发送最后一个低级别后,总线被释放并恢复到其自然高电压。换句话说,SWire 数据总线被拉高。

  写入请求

  如上所述,单个位和字节是如何在线路中编码的。接下来,我们来看看SWire协议是如何指定要写入特定地址的字节的。在该示例中,主盘希望将一个字节b写入从盘内存中的地址addr。

  为此,主盘必须发送一个字节序列,每个字节都按照上一节所述进行编码:

  START字节,这个值总是 0x5a;

  目标addr的最高有效8位;

  目标addr的最低有效8位;

  RW_ID字节,最重要的位应该设置为0,用于写入操作;

  字节值 b;

  END字节,它的值始终为 0xff;

  让我们看看下面的例子:

  在 SWire 中写入数据的示例

  在这个例子中,我们可以看到字节 0x05 被写入从盘的内存地址 0x0602。

  SWire 协议的变体

  值得注意的是,至少存在一个SWire协议的变体。在另一种变体中,主盘在 START 字节之后发送 3 个字节的 addr,而不是在我们的 SWire 协议中仅发送两个字节。例如,Telink 的 TLSR8251 SoC 中采用了 3 字节变体,用于我们上面提到的小米温度计。在 ATC_MiThermometer 存储库中基于 Python 的闪光器中,我们可以看到在从主盘到从盘的读/写请求中指定了 3 个字节的 addr。

  写入多个字节

  这是写入单个字节要花费的能力,幸运的是,该协议让我们一次写入多个数据字节。为此,主盘只需发送一个字节序列,而不是像上面示例中的单个字节。




电子技术图片.png

本站内容除特别声明的原创文章之外,转载内容只为传递更多信息,并不代表本网站赞同其观点。转载的所有的文章、图片、音/视频文件等资料的版权归版权所有权人所有。本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如涉及作品内容、版权和其它问题,请及时通过电子邮件或电话通知我们,以便迅速采取适当措施,避免给双方造成不必要的经济损失。联系电话:010-82306118;邮箱:aet@chinaaet.com。