1. 简介
上一篇文章中我们研究了Loock Touch门锁配套app中BleKey的获取流程,整个密钥分发和设备认证的流程都比较规范。接下来,我们将重点分析门锁固件对BLE通信内容的处理流程,开始分析之前,我们需要先获取门锁固件。
之前的文章我们已经介绍了两种获取固件的方法:在果加门锁的分析文章中,我们抓取了门锁向服务器请求固件更新时的数据包;在分析海康萤石网关时,我们直接读取了电路板上的Flash芯片。
但是以上两种方法都不适用于Loock Touch门锁,因为我们并没有找到鹿客门锁的固件更新接口,且门锁电路板上也没有外置的Flash芯片,固件是直接保存在MCU内置Flash存储器中的。所以我们在本篇文章中将分享一个新的方法:通过MCU的调试接口提取固件。
2. 调试接口与调试器
在此前的文章中,我们已经介绍了通过gdbserver调试海康萤石固件程序的方法,通常情况下,gdbserver是运行于Linux系统环境中的调试器程序,通过使用Linux系统提供的调试接口以完成调试工作,并不需要太多硬件上的辅助。而在某些场景中,例如,没有Linux操作系统时,gdbserver等工具就无法满足我们的调试需求了,此时需要直接使用MCU提供的硬件调试接口和功能,以完成调试工作。通过阅读MCU的芯片手册,可以找到MCU提供的调试方式、调试引脚等详细信息。
为了使用MCU的调试接口,我们还需要与之对应的硬件调试器。与IDA、GDB等调试器软件类似,通过硬件调试器,我们也可以完全掌握被调试程序的执行状况。一般情况下,硬件调试器是通过USB接口连接到PC主机的,而硬件调试器与MCU之间的通信接口则有许多种。不同的MCU,支持的接口也不尽相同,具体信息需要查阅各芯片的手册。
本篇文章要研究的Loock Touch门锁使用的MCU型号为EFM32GG280F512,通过翻阅芯片手册,可以找到其调试接口信息如下图:
图2-1 EFM32调试接口
上图中的调试接口名称为SWD接口,常见的使用SWD接口的硬件调试器有JLink、STLink等。
我们目前使用的调试器SEGGER JLink(下文简称为JLink)提供了对JTAG和SWD两种调试接口的支持,具体使用时,只需要连接到对应的引脚即可,JLink中两种接口的引脚如下图所示:
图2-2 SEGGER JLink的引脚定义
3. 通过调试接口提取固件
JLink调试器可以通过调试接口读写芯片内置的Flash,从而获取完整的固件。并不是所有芯片都可以通过调试接口提取固件,很多设备在发行版中启用了读保护(Readout Protection)机制,使得我们无法通过调试接口读到Flash内容,所幸本文中的设备并没有启用该机制。
接下来,我们就寻找并尝试用JLink连接芯片的调试接口。
3.1 连接调试接口
在门锁的电路板上,主控MCU一旁有一排过孔,我们已经在将排针焊接到这排过孔上了,如下图所示:
图3-1 MCU及其部分接口引脚
图中,左侧红框内就是我们焊上的排针,电路板上标注了排针对应的MCU引脚名称。经过万用表测量,可以确定红框中的IO和CLK引脚就是芯片的SWDIO和SWCLK两个引脚,我们在图2-1中提到这两个引脚是SWD调试接口的一部分,那么我们将这几个引脚按照如下图的方式连接到JLink调试器。
图3-2 调试接口与JLink的连接
上图左侧是图3-1中的排针,右侧是SEGGER JLink的引脚。连接完成后,将JLink连接到电脑的USB口,并打开JLink Commander命令行工具(JLink的相关工具和使用手册等都可以在SEGGER的官网下载到:https://www.segger.com/downloads/jlink/),执行下图中的命令:
图3-3 使用JLink连接SWD接口
下面逐一解释上图中6个红框的内容:
(1)命令行工具开启时,会首先对JLink的状态进行检测(SEGGER官网的JLink,无论价格还是到货时间都不理想,所以我们选择了某宝,从这里打印的JLink固件信息来看,某宝的似乎是盗版产品);
(2)输入connect指令,控制JLink开始通过调试接口连接MCU;
(3)输入?指令选择要调试的芯片型号,在弹出的对话框中,我们按照芯片的厂商和型号,选择如下图的选项;
图3-4 芯片型号选择
(4)输入s指令,选择调试接口的类型为SWD;
(5)选择接口的通信速率,一般保持默认即可;
(6)当出现第(6)步的这些内容时,说明JLink已经通过SWD接口连接到了MCU,接下来我们就可以读取固件或者进行调试了。
3.2 提取固件
上文提到,调试器可以读写芯片的内置Flash,而固件代码就存储在芯片内置Flash中,所以我们只需要将Flash中代码区域的数据读出并保存下来,就相当于拿到了固件。
按照我们分析果加门锁时的思路,翻阅芯片手册,可以确定代码存储在内存地址为0x0~0x100000的区域。我们通过JLink Commander命令行工具的savebin命令(该命令的使用方法可以去JLink的手册中查阅)将这一区域中的二进制数据保存下来。
图3-5 读取固件的二进制数据
上图中,我们拿到了固件代码,并将其命名为LoockEfm32Fw.bin。
3.3 解析固件
在拿到固件之后,我们需要解析固件并对其进行逆向分析。通过查阅手册可以知道,EFM32GG280的核心是ARM Cortex-M3,和果加门锁用到的STM32L0同属Cortex-M系列,所以我们可以按照果加门锁相关篇章中的方法配置IDA并载入固件。载入之后,继续沿用果加门锁分析时的思路,寻找Reset中断的中断服务程序,即偏移0x4地址处的数据,跳转之后按“c”键,IDA就会自动开始解析代码,如下图所示。
图3-6 从Reset中断入手解析代码
上文提到,代码存储在内存地址为0x0~0x100000的区域,所以图3-6中固件的基址为0x0。此前,我们在分析果加门锁时,将固件载入IDA时基址是0x08000000,因为在果加的案例中,代码存储区域的起始地址是0x08000000。
至此,我们成功提取并解析了Loock Touch门锁的固件,更加详细的分析工作将在下一篇文章中进行。
4. 小结
本篇文章分享了如何通过调试接口提取芯片固件,而除了这个作用外,调试接口的主要功能是对MCU正在运行的程序进行调试,在后续文章中我们将通过JLink调试器分析门锁固件是如何处理BLE通信数据的。
此外,值得一提的是,对大部分芯片来说,只有芯片的读保护机制未启用时,才能通过调试接口提取它的固件,但是也有少数芯片的读保护机制是可以绕过的,这部分内容后续可能会以番外的形式进行分享,感兴趣的读者可以关注我们的后续文章。
Light & Yimi Hu @ PwnMonkeyLabs
本文为 胖猴实验室 原创稿件,授权嘶吼独家发布,如若转载,请注明原文地址