通过 OpenOCD 的 STM32 读出保护

Posted

技术标签:

【中文标题】通过 OpenOCD 的 STM32 读出保护【英文标题】:STM32 Read-out protection via OpenOCD 【发布时间】:2015-12-07 04:55:18 【问题描述】:

STM32 系列微控制器具有读取保护功能,因此无法通过调试接口(JTAG 或 SWD)读取专有代码。

使用 OpenOCD,如何通过 SWD/JTAG 接口启用/禁用读出保护? RDP 读出保护的安全性如何?

如果可能,请给出一个对整个STM32系列都有效的答案。

【问题讨论】:

看起来不错的答案!但是,我是否可以建议不要将有关投票的 cmets 添加到问题中——它们对大多数读者没有用,他们的人数大大超过了选民。如果您必须添加此类请求,或许可以将其添加为评论? @halfer 我 100% 同意并且真的不想这样做。但是,我过去做过很多问答题,如果没有这些,我会一票接一票,一票接一票。添加这些注释。就在写这篇文章的时候,我收到了一张反对票和一张关闭的请求,要求我不要在里面写这个评论。有时我想知道一些评论者有什么问题。如果您有任何替代方法,请随时告诉我。 @halfer 最接近的投票是我跑题了,因为据说我正在寻找一个图书馆......要么我的眼睛受损,要么有些人点击了垃圾邮件关闭按钮。我会问Meta,也许有人有建议。 @halfer 这是元问题:meta.***.com/q/305794/2597135 【参考方案1】:

RDP 级别

首先,您必须知道要设置的读数保护级别(例如,请参阅STM32F4 reference manual 的第 3.7.3 节):

RDP 级别 1:此级别是可逆的。禁用后,系统内存将被大量擦除,您可以重新编程 RDP 级别 2:此级别是不可逆的,并且完全禁用调试接口。更新固件的唯一方法是通过一些引导加载程序机制。

通常您要激活 RDP 级别 1。为了避免肯定会使微控制器变砖的错误,我不会在此答案中展示如何启用 RDP 级别 2。详情请参阅参考手册。

使用 OpenOCD 激活它

激活功能实际上是使用lock 命令内置在 OpenOCD 中的。就像执行program 命令来刷固件一样,您可以使用stm32f1x lock 命令(或stm32f2x lock 用于STM32F2/F4)来激活它。

典型的 OpenOCD 配置文件如下所示(您需要在运行之前刷入正确的固件):

# Set RDP to level 1
init
reset halt
stm32f1x lock 0
reset halt
exit

请注意,只有在微控制器复位或断电后,读出保护才会生效(这就是命令序列中有第二次复位的原因)。

一个典型的 OpenOCD 调用可能如下所示:

openocd -d0  -f stlink-v2.cfg -f ocd-stm32f0.cfg -f ocd-lock.cfg

其中ocd-lock.cfg 包含上面显示的命令序列。

激活后,您可以通过尝试使用通常的编程命令序列来刷新 MCU 来验证 RDP 是否处于活动状态

停用 RDP

停用它也很简单:只需像这样使用stm32f1x unlock(或stm32f2x unlock 用于F2/F4 设备):

# Set RDP to level 0
init
reset halt
stm32f1x unlock 0
reset halt
exit

它有多安全?

这是一个很难回答的问题,如果没有其他信息的话。我可以给出的一个总结性答案是,如果您假设保护没有固有的错误并且有人只使用软件工具,那么它是非常安全的。

在不批量擦除闪存的情况下重置 RDP 位的最流行方法之一是disable the RDP with a laser。鉴于 STM32 系列不是具有特定对策的专用安全微控制器系列,如果您在该领域拥有合适的设备和足够的经验,这将相当容易。甚至一些特定的安全 MCU 也存在一些安全问题,请参见例如Security from the IC backside 谈话。但是,大多数低级别攻击者通常会避免这样做的成本。

【讨论】:

不适用于STM32F072,但在STM32F107上测试成功。 @halfer 你的文件 ocd-stm32f0.cfg 的内容是什么? @Motla:我的头像附在这个答案上,因为我编辑了它(中心的“已编辑”链接)。 Uli 是答案的所有者,一旦您发表评论,他们就会被 ping 通。 @Motla 有很多细节要做好。我怀疑您输入了错误的 TAP ID(在数据表或 Refman 中查找 F072)。仅供参考,我使用 STM32F030、STM32F042 和 STM32F407 对此进行了测试(并且我经常使用它)。这是我的ocd-stm32f0.cfg,但您确实需要设置正确的参数,例如CPUTAPID,给你的:gist.github.com/ulikoehler/6395994c623059e184971908d01c600f In ref. manual corresponding to STM32F072,在第 32.5 节,显然 IDCODE 与您的 TAP ID 很好地对应。此外,“stm32f1x options_read 0”命令似乎工作正常,但不是“stm32f1x options_write 0 ..”,因此它可能是来自 OpenOCD 的错误,它无法在此特定设备上写入选项字节,idk 为什么因为它位于同一地址。 ..【参考方案2】:

另一种解决方案是使用 Segger Jlink 6.60c(或更高版本,如果可用) 用J-Link解锁STM32软件。 只需运行它,它将通知以下内容:“如果启用了设备的读保护,则重置选项字节将导致批量擦除”。单击确定。它将询问设备系列。输入器件系列(对于 STM32L4R9ZI,我选择 12)并按 Enter。

如果一切顺利,输出将是这样的:

Please select the correct device family: 12
Connecting to J-Link via USB...O.K.
Using SWD as target interface.
Target interface speed: 1000 kHz.
VTarget = 3.396V
Reset target...O.K.
Reset option bytes to factory settings...
Resetting FLASH_OPTR...
Reset target...O.K.
Reset target...O.K.
Resetting Write protection (WRP) and PCROP...O.K.
Reset target...O.K.
Option bytes reset to factory settings.
Press any key to exit.

【讨论】:

以上是关于通过 OpenOCD 的 STM32 读出保护的主要内容,如果未能解决你的问题,请参考以下文章

STM32F2去掉读出保护

如何使用 OpenOCD 通过 JTAG 链批量刷写 STM32 微控制器?

STM32F103 闪存保护部分

STM32开发/烧录/调试环境搭建 基于:Win10+STM32Cube+openocd+cmsis-dap(dap-link)

在 Raspberry Pi 4 上使用 OpenOCD 对 STM32F4 进行编程

STM32 OpenOCD调试