ARM架构上用来替代JTAG的调试协议SWD
2019-08-29 11:34:52 Author: www.4hou.com(查看原文) 阅读量:176 收藏

lucywang Web安全 2019年8月29日发布

Favorite收藏

对于嵌入式开发人员和专门攻击硬件的黑客来说,JTAG 实际上是调试和访问微处理器寄存器的标准。该协议已使用多年,至今仍在使用,JTAG调试接口必须使用VCC、GND电源信号,以及TMS、TCK、TDI、TDO四根调试信号,另外TRST、RESET复位信号和RTCK(同步时钟)信号也在可选项里。现在,设备变得越来越小,微处理器的可用引脚数也越来越少,这些复杂的信号,已经阻碍了协议的正常使用。

为了解决这个问题,ARM创建了一个名为SWD(串行线调试)的替代调试接口。相对于JTAG接口,SWD使用了更少的信号。它只使用两个信号(SWDCLK和SWDIO),这个接口及其相关协议现在几乎可以在所有的Cortex-[A,R,M]处理器中使用。

Cortex-A:面向性能密集型系统的应用处理器内核,Cortex-A处理器为利用操作系统(例如Linux或者Android)的设备提供了一系列解决方案,这些设备被用于各类应用,从低成本手持设备到智能手机、平板电脑、机顶盒以及企业网络设备等。

Cortex-R:面向实时应用的高性能内核,Cortex-R系列是衍生产品中体积最小的ARM处理器。Cortex-R处理器针对高性能实时应用,例如硬盘控制器(或固态驱动控制器)、企业中的网络设备和打印机、消费电子设备(例如蓝光播放器和媒体播放器)、以及汽车应用(例如安全气囊、制动系统和发动机管理)。Cortex-R系列在某些方面与高端微控制器(MCU)类似,但是,针对的是比通常使用标准MCU的系统还要大型的系统。

Cortex-M:面向各类嵌入式应用的微处理器内核,Cortex-M系列是针对竞争已经非常激烈的MCU市场。Cortex-M系列基于ARMv7-M架构(用于Cortex-M3和Cortex-M4)构建,而较低的Cortex-M0+基于ARMv6-M架构构建。首款Cortex-M处理器于2004年发布,当一些主流MCU供应商选择这款内核,并开始生产MCU器件后,Cortex-M处理器迅速受到市场青睐。可以肯定的说,Cortex-M之于32位MCU就如同8051之于8位MCU,受到众多供应商支持的工业标准内核,各家供应商采用该内核加之自己特别的开发,在市场中提供差异化产品。

ARM调试接

体系结构概述

与JTAG将接口链接在一起相反,SWD使用名为DAP(调试访问端口)的总线。在这个DAP上,有一个主端口(DP – Debug端口)和一个或多个附属端口(AP – Access端口)类似于JTAG接口。DP使用包含AP地址的数据包与AP事务处理。

总而言之,外部调试器使用名为SWD的协议通过DP连接到DAP,ARM的这份介绍很好地概述了SWD架构:

1.png

SWD架构

调试端口

调试端口是主机和DAP之间的接口,它还处理主机接口,目前有三个不同的调试端口可以访问DAP:

JTAG调试端口(JTAG- dp):该端口使用标准JTAG接口和协议来访问DAP;

串行线调试端口(SW-DP):该端口使用SWD协议访问DAP;

串行线/ JTAG调试端口(SWJ-DP):该端口可以使用JTAG或SWD访问DAP,这是许多微处理器上常见的接口。它重用TMS和TCK JTAG信号,分别传输SWDIO和SWDCLK信号。为了从一个接口切换到另一个接口,必须发送特定的序列。

访问端口

可以根据需要将多个AP添加到DAP中,ARM提供了两个AP的规范:

1. 内存访问端口(MEM-AP):该AP提供对核心存储器和寄存器的访问;

2. JTAG访问端口(JTAG-AP):该AP允许将JTAG链连接到DAP。

SWD协议

信号

如前所述,SWD只使用两种信号:

· SWDCLK:主机发出的时钟信号,由于处理器时钟和SWD时钟之间没有关系,所以频率的选择取决于主机接口。在这篇文章中,最大    调试时钟频率约为60MHz。

· SWDIO:这是把数据从DP传送到DP的双向信号,数据由主机在上升沿设置,由DP在SWDCLK信号下降沿采样。数字电路中,数字电    平从低电平(数字“0”)变为高电平(数字“1”)的那一瞬间(时刻)叫作上升沿。数字电路中,数字电平从高电平(数字“1”)    变为低电平(数字“0”)的那一瞬间叫作下降沿。

事务处理过程

每个SWD交换过程分三个阶段:

1.请求阶段:从主机端口发送8位;

2.ACK阶段:从目标端口发送3位;

3.数据阶段:发向主机端口或从主机端口发送最多32位,带有奇偶校验位;

请注意,必须在数据方向发生变化时发送Trn循环(Trn cycle)。

2.png

SWD转移

请求

请求头包含以下字段:

3.jpg

ACK

ACK (Acknowledgement)即是确认字符,在数据事务处理中,接收站发给发送站的一种传输类控制字符。表示发来的数据已确认接收无误。

在TCP/IP协议中,如果接收方成功的接收到数据,那么会回复一个ACK数据。通常ACK信号有自己固定的格式,长度大小,由接收方回复给发送方。

ACK位包含请求头的ACK状态,注意,必须先读取LSB中的三个位。

4.jpg

数据

数据由主机发送或目标发送。它首先发送LSB,并以奇偶校验位结束。

协议交互

现在我们已经了解了协议的底层部分,现在是与实际目标交互的时候了。为了做到这一点,我使用了Hydrabus,但也可以使用总线海盗(Bus Pirate)或任何其他类似的工具。BusPirate 是由Dangerous prototypes 设计出品的一款硬件hacking 瑞士军刀,支持多项常见协议并可跨平台Windows/Linux/MAC,并拥有丰富的帮助文档。在本文的测试中,我使用了一个名为Blue Pill的STM32F103开发板。绰号为蓝丸(蓝色药丸(blue pill)rootkit是以管理程序身份执行来控制电脑资源的恶意软件)Joanna Rutkowska是新加坡的IT安全公司COSEIN的一名安全研究员,她在2006年的黑帽简报会议上展示了Blue Pill rootkit,它是作为概念验证型恶意软件而开发的。原始的蓝色药丸(blue pill)操作基于AMD虚拟化(AMD-V),它是X86处理器架构的一套硬件扩展。该处理器扩展从软件上卸下了重复与低效的工作。通过处理器扩展、陷阱和虚拟化仿真处理这些任务,基本上排除了经过操作系统的任务,大大地提高了物理服务器上虚拟机的性能。

ARM调试接口体系结构规范文档包含了与SWD接口交互所需的所有细节,以下就是具体过程:

SWD初始化

由于目标使用了SWJ-DP接口,因此需要将其从默认的JTAG模式切换到SWD。规范文档的第5.2.1章显示了从JTAG切换到SWD的顺序:

1. SWDIOTMS HIGH发送至少50个SWCLKTCK周期,这可确保当前接口处于重置状态。 JTAG接口仅检测从Test-Logic-Reset状态开始的16位JTAG-to-SWD序列。

2. 在SWDIOTMS上发送16位JTAG-to-SWD选择序列;

3. SWDIOTMS HIGH发送至少50个SWCLKTCK周期,这确保了如果在发送选择序列之前,如果SWJ-DP已经处于SWD操作中,则SWD接口进入线路重置状态。

0b0111 1001 1110 0111 (0x79e7) MSB序列优先,我们需要使用LSB-first格式的0x7b 0x9e。

5.jpg

现在DP处于重置状态,我们可以发出DPIDR read命令来识别调试端口。为此,我们需要读取地址0x00处的DP寄存器。

6.jpg

下一步是启动调试域。规范文档的第2.4.5章告诉我们需要在DP的CTRL/STAT(地址0x4)寄存器中设置CDBGRSTREQ和CDBGRSTACK(第28位和第29位):

7.jpg

SWD的使用

现在调试电源域已启动,DAP可完全访问。作为第一个发现过程,我们将查询AP,然后扫描DAP中的所有AP。

读取AP 

从AP中读取数据是通过DP完成的。要查询AP,主机必须告诉DP写入是由DAP上的地址指定的AP。为了从之前的事务处理中读取数据,DP使用称为RDBUFF(地址0xc)的特殊寄存器。正确的查询方法如下:

1.写入DP SELECT寄存器,设置APSEL和APBANKSEL字段;

2.读取DP RDBUFF寄存器,以“提交”最后一个事务处理;

3.再次读取RDBUFF寄存器以读取其实际值。

SELECT寄存器在2.3.9章进行了描述,关键字段如下:

8.jpg

读取的一个有趣的AP寄存器是IDR寄存器(地址0xf),它包含这个AP的标识信息,下面是读取地址0x0处AP的IDR过程的代码。

9.jpg

对AP进行扫描

使用完全相同的代码,我们可以迭代整个地址空间,看看DAP上是否还有其他AP:

10.jpg

运行脚本显示总线上只有一个AP。根据规范文档的描述,它是MEM-AP:

11.jpg

此时,你可以向MEM-AP发送命令以查询处理器内存。

发现SWD引脚

在真实的设备上,确定调试接口使用哪些引脚或测试点(testpoint)并不总是很容易的。对于JTAG也是如此,这就是为什么存在像JTAGulator这样的工具。其目的就是通过尝试每个引脚组合来发现JTAG接口,直到组合返回一个有效的IDCODE(Identity code),目前比较好的寻找 JTAG 引脚的工具就是 JTAGULATOR ,它是个自动化寻找 JTAG 引脚的工具。

既然我们已经了解了如何初始化SWD接口,那么我们就可以对SWD接口进行同样的操作。其思路是这样的:

1.在目标板上使用一些有趣的引脚;

2.把它们连接到SWD的发现设备上;

3.在SWD发现设备上选择两个引脚,分别做为SWDCLK和SWDIO;

4.发送SWD初始化序列;

5.读取状态响应和DPIDR寄存器;

6.如果结果有效,请打印解决方案;

7.如果没有有效结果,请转到步骤3并选择两个新引脚。

经过实际测试,该方法已在Hydrabus固件上实现了,并取得了良好的效果。下图是一个会话示例:

12.jpg

这项操作所需时间不到两秒,并且迄今为止在所有测试板上都能发现SWD接口。

总结

在这篇文章中,我们介绍了如何设计ARM调试接口,以及SWD协议是如何在非常基础的级别上工作的。有了这些信息,就可以使用一个简单的微处理器向MEM-AP发送查询。


文章来源: https://www.4hou.com/web/18223.html
如有侵权请联系:admin#unsafe.sh