# 果加智能门锁的全面分析（上）

## **简介**

在本专题将对果加门锁进行分析。

果加的智能门锁大体分为两个系列，其一是家用版智能门锁，其二是公寓版智能门锁。家用版智能门锁通过BLE与手机通信，并通过手机间接与果加云端通信；公寓版门锁通过433MHz与其对应的网关通信，网关与果加云端通信。尽管通信方式不同，但是家用版和公寓版门锁的架构和用到的芯片都是类似的，因此本篇及下一篇文章中，重点对家用版门锁的固件进行分析，偶尔提及公寓版门锁。

## **固件分析**

固件，通常是指驱动底层硬件的软件程序，固件直接与硬件打交道，控制硬件实现各种逻辑功能。而在IoT设备中，固件通常包含了RTOS(Real Time Operating System, 实时操作系统)和应用软件，提供了从底层驱动到高层应用的所有功能。

大部分IoT设备的固件存储在Flash中，在进行分析之前，首先需要设法获取设备固件。

### 2.1 固件获取

家庭版果加智能门锁需要通过使用者的手机间接连接到果加的云端服务器，只要监听app的通信数据，就可以发现门锁更新时的固件下载地址，如下图2-1所示。

![图2-1 抓取果加家庭版门锁下载地址](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdAu7wU02DMhZscUnXA%2F-MdAuU8mRTAFezhUAa7h%2Fimage.png?alt=media\&token=6c4f4ce1-555e-4355-a1ea-f7386728c0fa)

上图中的抓包工具是fiddler，鉴于该软件是本专题中第一次出现，所以这里做个简短的介绍。Fiddler是一款由Progress公司开发的免费抓包工具，官网是：<https://www.telerik.com/fiddler。在众多的抓包工具中，认为fiddler的界面比较好看。使用fiddler抓取手机通信时，需要对fiddler进行两处设置，同时对手机也做两处设置，fiddler的两处设置截图如下：>

![图2-2 fiddler设置](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdAu7wU02DMhZscUnXA%2F-MdAuZBDpYcwH9TLhtjb%2Fimage.png?alt=media\&token=631063c3-fd0c-4f08-8ca7-5777b4fa3ee7)

上图中，左侧设置为解密HTTPS通信，右侧设置为允许局域网其他设备连接代理。手机的两处设置截图如下：

![图2-3 抓包时手机设置](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdAu7wU02DMhZscUnXA%2F-MdAub-LAzfGdqw7nC1c%2Fimage.png?alt=media\&token=942d18c2-7602-467d-bdc8-8fe97259be92)

上图中，左侧设置为添加fiddler的根证书，右侧设置为通过fiddler代理转发通信数据。图中10.0.0.16是运行fiddler的计算机ip，8888是fiddler默认的监听端口。设置完毕之后，就可以抓取手机通信。在本专题的后续文章中，可能涉及到一些证书校验而导致无法抓包的情况，到时会更深入地讨论。&#x20;

相对来讲，公寓版的果加智能门锁要麻烦一些。公寓版的果加智能门锁在433MHz信道与其网关进行无线通信，网关通过有线连接到互联网，进而访问果加云端。在交换机上做了一次端口监控，通过分析镜像而来的通信数据找到了固件的下载地址。

![图2-4 交换机端口监控](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdAu7wU02DMhZscUnXA%2F-MdAueyVRY87j-QZCVqO%2Fimage.png?alt=media\&token=54856291-2f40-48e7-ac3d-a98abfbbf844)

### 2.2 分析准备&#x20;

通常情况下，选择IDA作为固件分析工具，IDA是一款非常卓越的反汇编工具，相信很多人都曾使用过，这里就不做过多的介绍了。不同于Windows程序或者Android程序，IoT设备的固件在开始逆向之前要做一些准备。如果要分析Windows程序，一般都是直接拖到IDA中，IDA会自动识别为PE格式文件，并帮助选择好处理器型号等信息(MetaPC)，如下图：

![图2-5 IDA自动解析PE文件](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdAu7wU02DMhZscUnXA%2F-MdAuj1ZBdIZQOaIRU7B%2Fimage.png?alt=media\&token=c4ee6840-0431-49a9-8b7c-2c939be8193f)

而对于IoT设备，IDA无法自动完成上述分析，因为固件往往与IoT设备的底层硬件直接相关，而在底层硬件中MCU(Microcontroller Unit, 微控制单元)是最为关键的一部分，不同MCU会使用不同的指令集、文件系统等。因此，要使用IDA分析固件，必须先确定MCU的相关信息。&#x20;

正如在第二章开头所述，固件一般要包含一个实时操作系统，设备上电后就会引导启动这个RTOS。如果设备是基于嵌入式Linux操作系统运行的，那么就会引导Linux kernel程序。此时，在固件中还可以发现Linux文件系统，而文件系统中的各个程序将是分析重点。如下图所示：

![图2-6 海康威视门锁网关固件](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdAu7wU02DMhZscUnXA%2F-MdAumwpWapC31-1A_1E%2Fimage.png?alt=media\&token=44b1c78b-953c-4937-abcc-c3fa468eaa78)

上图中可以看到海康威视智能门锁网关有Squashfs文件系统和JFFS2文件系统，还有U-Boot引导程序等。&#x20;

如果设备是运行其他RTOS，如FreeRTOS等，那么，此时的固件文件可能就完全是一段编译好的包含代码和数据的可执行文件。这次要分析果加智能门锁的固件，就是单纯的一个可执行文件，如下图所示：

![图2-7 果加门锁固件内容](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdAu7wU02DMhZscUnXA%2F-MdAusEoyc0Xw6jNfeTY%2Fimage.png?alt=media\&token=5565c770-e568-4546-be41-f68d1ef0c5da)

为了帮助快速辨别固件文件中都有什么，binwalk是个非常好用的工具，其官方的下载地址为：<https://github.com/ReFirmLabs/binwalk。在整理本篇时，发现binwalk的开发团队出了一个商业版binwalk> pro，可以在线分析和提取固件，好像还挺有意思。在图2-6和图2-7中，已经展示了binwalk对于固件的分析输出，其中图2-6是海康智能门锁网关的固件内容；在图2-7中，binwalk没有任何输出，说明binwalk无法辨别此固件的内容，实际上这个固件完全是个可执行文件。除此之外，binwalk还可以直接解压提取固件中的内容，但果加智能门锁的固件并没有什么可以提取的内容。&#x20;

此时，如果是嵌入式Linux操作系统，那么就可以开始分析他文件系统中的关键程序了。IDA可以自动解析出ELF文件格式，然后开始反汇编工作。但是果加智能门锁的固件完全是个单片机程序，那么IDA不能完成自动解析工作，所以需要手动指定一些解析信息。&#x20;

首先需要确定MCU使用的指令集，首先通过MCU上刻印的芯片型号(STM32L071)，找到对应的Reference Manual或Datasheet，通过这些文档可以确定MCU使用了Arm Cortex-M0+内核，该内核采用Armv6-M架构，如下图所示。

![图2-8 果加智能门锁的MCU信息](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdAu7wU02DMhZscUnXA%2F-MdAv-8pefVpnV8pLwAU%2Fimage.png?alt=media\&token=c9864fb0-ce1a-4961-9d5e-297557b7fae0)

IDA中已经内置了Armv6-M架构的指令集，只需要载入文件时做出如下图的配置即可：

![图2-9 IDA解析配置](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdAu7wU02DMhZscUnXA%2F-MdAv2W761Gr9Fzt527j%2Fimage.png?alt=media\&token=4a97f889-f6be-4786-bb0e-a5fd827fc84b)

确定了指令集之后，还需要设置固件加载地址。熟悉PE结构的读者，肯定知道PE头中有个重定位表。当PE文件的加载地址并非其默认地址时，就需要根据重定位表对PE文件中的全局变量、绝对跳转地址等进行重定位修复。但果加智能门锁这种固件程序，是没有这些复杂的格式，所以如果不能确定代码的加载地址，IDA加载的时候就会出现很多不能解析的跳转和全局变量。通常MCU都会有一块固定的存储区域用于存储代码，这个区域的起始地址就是固件的加载地址，这些信息同样可以在References Manual或Datasheet中找到。果加智能门锁使用的STM32L071的相关信息如下图所示：

![图2-10 STM32L071RZT6内存映射图](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdAu7wU02DMhZscUnXA%2F-MdAwCAccADA6QWAlBSf%2Fimage.png?alt=media\&token=eeef84a8-355c-417e-95ab-c502b5372834)

上图中显示固件代码会加载到Flash System Memory区域，即0x0800 0000地址之后的内存。那么在IDA加载过程中设置ROM起始地址为0x0800 0000，如下图：

![图2-11 设置IDA的ROM加载地址](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdAu7wU02DMhZscUnXA%2F-MdAwFeU9y6kYhAMfwP2%2Fimage.png?alt=media\&token=f21b114c-04d5-4297-80c6-0a142e6c9dea)

### 2.3 程序分析&#x20;

上文中已经给IDA指定了解析固件所需要的部分信息，等IDA加载完毕之后，发现IDA依旧将其当成一个binary文件，并未解析出任何代码，这是因为IDA不知道该从哪里开始解析。此时可以翻看programming mannual，查到与中断向量表有关的内容，如下图：

![图2-12 中断向量表](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdAu7wU02DMhZscUnXA%2F-MdAwLKDp4fRKdAxwsMb%2Fimage.png?alt=media\&token=1be35e92-9805-4660-945b-9a7e9eaa1ffa)

由上图可知，固件的起始部分应是中断向量表。设备上电之后执行的代码，即Reset复位中断，位于中断描述表中第二项所指的位置，偏移0x4，截图如下：

![2-13图 IDA解析中断向量表](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdAu7wU02DMhZscUnXA%2F-MdAwPD9iJF6sQ5TApS9%2Fimage.png?alt=media\&token=67e6b49a-428e-47cd-8c70-7740080e299b)

跳转到此位置(0x8001BD)，然后按’c’令IDA将此处解析为代码，IDA将解析出大量的代码段和函数。之后，就可以开始固件的逆向分析工作了。

![图2-14 IDA解析代码](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdAu7wU02DMhZscUnXA%2F-MdAwSsurhf6pFMcN4Pz%2Fimage.png?alt=media\&token=3fbcf404-c95c-4e48-810d-af66a1ad4a30)

到此，已经完成了固件中的指令解析，那么接下来的工作就是理解这些代码的逻辑。这部分内容将会在本专题的下一篇文章中介绍。

本篇中提到的Datasheet、References Manual、Programming Mannual均可从st官网下载到，地址如下：

[https://www.st.com/zh/microcontrollers-microprocessors/stm32l071rz.html。](https://www.st.com/zh/microcontrollers-microprocessors/stm32l071rz.html%E3%80%82)
