STMicroelectronics 公司的 STM32 处理器,是 IoT 设备中最常见的 ARM 微控制器之一。我们经常需要从这些设备上读取固件,检测和寻找其中的漏洞或是隐藏的功能特性。下面我们将介绍通过简单的软件工具——stlink 来实现这一目的。
我们准备用 Nucleo-F030R8 这款板子。这是一款小型开发板,只需 10英镑就能拿到。此处有 产品手册和原理图 。
为什么用开发板而不是一个真实的设备呢 ? 首先是价格便宜,技术参数一致而且有文档资料。同时,我们只是学习固件读写的工作原理而已。
这块板子上的最主要的芯片就是 STM32F0303R8 。datasheet 参考链接。这是基于 ARM Cortex-M0 内核的板子,是 ARM 的最小核。有 64KB flash 和 8KB RAM,主频 48MHz 。由于这是微控制器,它们的封装与 ARM 处理器一样。
PCB 最顶部有另一颗微控制器,是用于为主控制芯片提供 STLink SWD 编程用的。SWD(Serial Wire Debug)是一个提供类似于 JTAG 功能的调试接口。我们可以通过该接口读写内存和与处理器交互。
我们将会使用 STLink 硬件配合 stlink 软件,一同调试设备,读取和写入 flash 。
接下来我们要把 STMicroelectronics STM32 STLink 接到 Ubuntu 虚拟机上:虚拟机->可移动设备->STMicroelectronics STM32 STLink->连接 (从主机断开连接).
连接成功后,运行:
dmesg
你将看到许多 USB 设备被列出来——不仅仅是一个 STLink!
我们看一下我们在运行的设备:
lsusb
你可以看到 STMicroelectronics 设备,在 USB 总线003 上的 003 设备。
运行:
lsusb -t
将看到设备的详细信息。我们可以看到它是由 4 个不同的接口组成:
我们今天只使用 STLink 。
在前面的文章中,我们构建和安装了一个工具 st-link 。这是用于与 STLink 编程器交互的 Linux 工具。
运行:
st-info --probe
将会收到返回的关于开发板的信息,包括 flash 和 SRAM 大小。这表明,开发板与主机通信正常。
现在我们准备从 flash(非易失性存储,存储固件的地方)读取固件。在这块板子上,flash 是直接内存映射的,所以我们在读取前,不需要再对 flash 控制器做初始化操作。
读之前我们首先要弄清楚,从内存的哪个位置开始读?读多少字节?对于这个,datasheet 就派上用场了。
图片的中间部分,详细具体的标志出,Flash 位于内存 0x08000000 处.
我们知道,这款芯片的 flash 大小为 64KB - 0x10000 . 我们需要运行的命令是:
st-flash read firmware.bin 0x08000000 0x10000
现在我们得到了 firmware.bin 文件,可以用 hexdump 检查里面的内容:
hexdump -C firmware.bin | less
如果所有的数据都是 0xFF
或 0x00
,那么文件大概率是出问题了。因为擦除的空 flash 状态就是 0xFF
。
有时,我们也需要对设备的 flash 进行写入操作,比如更新设备固件。
写入命令只需明确 flash 的内存地址,写入长度将根据文件进行推算。
st-flash write firmware.bin 0x08000000
你将明显地感觉到,写入的过程比读取慢多了。对 flash 进行写入并不容易——首先需要擦除整块内容,然后进行写入。为此,st-flash 在设备的 SRAM 上引入了一块 flash loader 区域,用于进行 flash 编程。
STM32F0 flash loader 的汇编请查阅此处。如果是更复杂的 flash ——比如非内存映射的外部 SPI flash,有时你可以通过这种方法读取 flash 。
OpenOCD 也可以用于设备 flash 的读取与写入。这不是唯一的方法,只是我们选择的是 stlink 而已。
另外,STMicroelectronics 也提供了一套工具。不过,这套工具只支持 Windows 而且需要注册才能下载。
原文:
https://cybergibbons.com/hardware-hacking/reading-and-writing-firmware-on-an-stm32-using-swd/
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2020-11-19 21:52
被StrokMitream编辑
,原因: 修正图片。