jtag引脚定义_从逆向分析的角度学习硬件调试技巧JTAG,SSD和固件提取

19228d165ad5488455cfe3c25636daf0.gif

我想从逆向的角度做了深入了解JTAG,JTAG是许多嵌入式CPU使用的硬件级别调试机制,我希望通过这篇文章从逆向工程师的角度解释如何使用JTAG,并在此过程中提供一些实际示例。

14028bb44e3a0dde4d5836fb73c33ecb.png

0x01 研究目标

通过这篇文章,我希望做到以下几点:

1. 解释JTAG的工作原理;

2. 演示如何发现和利用未知目标上的JTAG端口/接口;

3. 提供一些当前可用于与JTAG接口交互的OSS工具的概述;

4. 利用JTAG提取固件并调试目标。

另外,在概述之前,我列出一些学习JTAG的资源

· Cyphunk’s Embedded Analysis Page

· FPGA4Fun JTAG Overview

· Blackbox JTAG Reverse Engineering

14028bb44e3a0dde4d5836fb73c33ecb.png

0x02 JTAG概述

JTAG是一种硬件接口,旨在帮助开发人员和测试人员进行调试。JTAG最初是为了测试集成电路而开发的,更具体地说,是对被测目标上的IO引脚进行采样。这种类型的调试接口使工程师可以在不需要物理引脚本身的情况下测试PCB上的连接。JTAG接口通过以下概述的状态机进行控制:

7bf1f9be3d6f8fbecbdd6e1b500d6174.png

关于此级别的JTAG,要记住的重要事情之一是它涉及两个寄存器,即指令寄存器和数据寄存器。要使用这些寄存器,必须使用以下接口信号输入上述状态机中的正确状态:

705bc3c26bc05489baee72a5892c4258.png

使用TMS和TCK线浏览状态机,同时分别通过TDI和TDO写入或读取数据。在TCK的上升沿对TMS进行采样,这意味着必须先声明TMS线,然后才能将TCK切换为在状态机中导航。然后根据JTAG状态机的状态将数据移入指令寄存器(IR)或数据寄存器(DR)。当完成一个操作(或更新DR / IR相后)所得到的数据可以被移位通过输入DR的Shift-DR状态。有了这些原语,制造商可以实现他们希望通过JTAG实现的任何功能。

JTAG标准将IR和DR视为移位寄存器,因此,可以将多个目标链在一起。

9d41a97dc728f9fba6a73ac83b6a57f0.png

简而言之,JTAG定义了一个状态机,该状态机至少使用4个信号进行导航。有了此状态机,最终用户可以从两个移位寄存器IR和DR进行写入和读取。

JTAG寄存器

JTAG利用两个主要寄存器,指令寄存器和数据寄存器。指令寄存器用于确定JTAG控制器将要执行的功能,例如存储器读取或存储器写入。数据寄存器然后用作指令寄存器的附加输入,对于前面的示例,它们可以用于提供要读取或写入的地址。这些寄存器的大小可以根据其功能而有所不同。

要写入寄存器,将执行以下步骤,我们以IR为例:

1. 输入Test Logic Reset状态(TLR)(可以通过断言TMS线路并循环CLK5次来完成此操作);

2. 进入Select IR Scan状态;

3. 进入Capture IR状态;

4. Enter Shift IR–这是我们将数据从TDI加载到IR的地方;

5. 进入Exit IR状态;

6. 进入Update IR状态–此阶段将值“锁存”到IR中。

此后,如果不需要数据寄存器,则将执行该操作,并将结果(如果有)加载到数据寄存器中以移出。但是,许多指令也需要在操作之前填写数据寄存器。在这种情况下,一旦数据寄存器被写入并更新,就将执行该操作,并且结果可以移出数据寄存器。

某些指令不需要加载DR,例如,如果我们已将IDCODE指令加载到IR(1110b)中,则会将处理器的IDCODE值加载到数据寄存器中,以便我们计时并继续读取TDO。要从中读取结果TDO,将导航到该Shift-DR状态,并在上输入32位TDI,这将导致数据寄存器中的数据TDO在线上移出。请参见下图,直观地了解如果向IR加载IDCODE指令后会发生什么情况。

ef045d8ee4112e951a36875eeed0d625.png

重要的是要记住,IR并且DR可以将其视为移位寄存器,这意味着当我们使用新值更新它们时,旧值随后会移出TDO。

JTAG标准定义了以下指令寄存器:

·  BYPASS

· 该指令连接TDI并TDO

· 在此Shift DR状态下,数据从传输TDI到TDO的延迟为一个TCK周期

· Capture DR状态期间将0装入数据寄存器

· 这可用于确定扫描链中有多少个设备

·  IDCODE

· 加载时,将设备代码ID寄存器选择为TDI和TDO之间的串行路径

· 在Capture-DR状态下,将32位设备ID代码加载到此移位部分中

· 在Shift-DR状态下,此数据被移出,最低有效位在前

· 核心JTAG概念:

· 该状态机被导航用4个信号:TCK,TMS,TDO和TDI

· TDI用于提供输入,TDO用于输出

· 使用此状态机,可以将数据移到IR(Shift IR)和DR(Shift DR)中

· 可以将指令寄存器(IR)视为函数,而将数据寄存器(DR)视为该函数的参数

· 随着数据移入DR和IR,先前的内容移出TDO

· 一旦将数据移入这些寄存器,就可以执行操作(除少数保留指令外,完全取决于主机实现)

· 数据被读出通过将其移动到目标的出TDO从数据在寄存器Shift DR状态。

因此,既然我们已经研究了JTAG的底层工作原理,那么我们应该讨论为什么我们会关心它,以及该接口如何为逆向工程师授予对有用功能的访问权限。JTAG接口最常用的应用程序之一是硬件级调试(因此,本文的标题)。这是由芯片制造商实现的,并且可能因芯片而异,但是,针对ARM目标的硬件级调试的最常见实现之一是ARM的CoreSight调试接口。这与我在上一篇文章中通过SWD进行通信的实现相同,只是在这种情况下,调试访问端口是通过JTAG进行通信的。JTAG实现的细节可以在这里找到。对我们来说幸运的是,可以使用一些出色的OSS工具与这些端口进行通信-这篇文章将重点介绍使用OpenOCD。

http://infocenter.arm.com/help/topic/com.arm.doc.ddi0314h/DDI0314H_coresight_components_trm.pdf 

https://wrongbaud.github.io/stm-xbox-jtag/ 

https://static.docs.arm.com/ihi0031/c/IHI0031C_debug_interface_as.pdf

OpenOCD负责利用JTAG或SWD接口向最终用户授予通过CoreSight DAP公开的调试接口提供的各种原语。Coresight / DAP体系结构相当复杂,在本篇文章(已经很长时间)中无法涵盖,因此我有可能将其保存在另一篇文章中。

14028bb44e3a0dde4d5836fb73c33ecb.png

0x03 逆向工程师和JTAG

从逆向工程师的角度进行此类操作时,对协议基础知识有扎实的了解非常重要。当进行逆向硬件(或软件)时,由于总是存在无限的未知数,因此你希望掩盖自己的基本事实。接下来的几节将讨论如何利用我们对这些协议的低级知识来帮助我们走上通过JTAG进行硬件级调试的途径。我们需要做的第一件事是确定引脚排列,以及是否暴露的引脚允许访问JTAG接口。

确定引脚排列

JTAG信号线通常组合在一起,有时(如果非常幸运的话),你将看到以下标头之一:

d5b7dae87d14ebcf024e67ff78c38989.png

但是,如果你发现类似的内容,则可能没有确切的信号分组,因此,我们将讨论如果假设某个引脚用于JTAG,则如何确定引脚。在进行类似这样的逆向工程时,你想从已知的知识开始。因为我们知道大多数制造商至少会进行IDCODE,所以BYPASS我们看看如何利用这两个说明。

如果你确定自己认为是潜在的JTAG标头或引脚,但不知道引脚,则可以使用这两个寄存器的行为来确定引脚。

由于该IDCODE寄存器通常作为默认IR加载,因此可以通过执行以下操作来测试假定的引脚排列:

1. 将角色分配给潜在的输出引脚(TMS,TCK等);

2. 输入Test Logic Reset状态;

3. 输入Select DR Scan,Capture DR,Shift DR;

4. 时钟32点的值TDI,并监测TDO一个有效的IDCODE值;

5. IDCODE如果看起来有效,请检查移出的值!否则,请重新分配引脚并重复!

除了利用IDCODE默认情况下经常将寄存器加载到IR中这一事实外,我们还可以利用IR和DR都充当移位寄存器这一事实,因此,如果我们假设一个通用的寄存器长度(32位通常有效),我们可以尝试执行以下操作以强行设置插脚:

1. 将角色分配给潜在的输出引脚(TMS,TCK等);

2. 使用这些假定值输入Test Logic Reset状态;

3. 输入Shift IR状态;

4. 移入一个唯一的32位值 TDI;

5. TDI在监视你在TDO上的唯一模式时,继续将1切换为开(请确保至少进行32次操作!)。

6. 如果发现了模式,那就恭喜!否则,为引脚选择新的分配并重复!

这两种方法是通过前面提到的使用JTAGEnum脚本,还有JTAGULATOR。

确定指令长度

一旦确定了目标的引脚排列,即可开始真正的分析。下一步是确定IR / DR的长度。为此,从IR开始,进入Shift IR状态,并TDI使用1024或4096之类的大数字以1的on填充链,然后以0 TDI计数。一旦完成,只需继续以1的on 计数,计数即可在出现0之前花费的时钟周期数TDO。这将告诉你IR的长度。有了该名称后,就可以输入Shift DR状态并重复此过程以确定DR的状态。

http://urjtag.org/

14028bb44e3a0dde4d5836fb73c33ecb.png

0x04 实际示例:三星M.2 SSD

本文的目标将是我最近从一台较旧的笔记本电脑中恢复的三星M.2 SSD,在查看了PCB并找出可能是JTAG接头的地方之后,我想从头到尾概述一下该过程。

8f89b93c3df35f6a9bf9ca770a702395.png

772e9fe8c5b2504e522e04a97ac0027a.png

实际示例:查找JTAG标头/确定引脚排列

如前所述,JTAG线路经常被分组-因此,从硬件角度看一个新平台时,寻找大于5的引脚分组总是一个好的开始。幸运的是,在这个目标上,PCB外侧有9个过孔。让我们开始检查驱动器在正常操作状态下这些引脚的电压电平。

be1236ff73238964c237269d864fe763.png

从最初开始-这些电压值不会告诉我们任何信息,那么我们可以根据已有的信息确定什么?首先,我们有一个GND,通过在万用表上使用连续性模式并针对USB连接器的屏蔽层(当然要拔掉目标!)进行测试,很容易确定GND。接下来,我们有一条1.8V的线,通常会期望它是TMS,因为在大多数文档中建议将其保持在高电平。

为了确定引脚排列,我们将使用Raspberry Pi和JTAGEnum项目。该脚本使用上述方法来尝试识别JTAG引脚。同样重要的是,这里的逻辑电平为1.8V,因此,如果要与该目标接口,我们将需要使用逻辑电平转换器。JTAGEnum.sh使用Raspberry Pi的GPIO线来激活目标接口,在shell脚本中,它们包含GPIO值的映射,如下所示:

 # define BCM pins (mapped directly to /sys/class/gpio/gpio${pin[N]})

 # 5v 5v  g 14 15 18  g 23 24  g 25  8  7  1  g 12  g 16 20 21

 # 3v  2  3  4  g 17 27 22 3v 10  9 11  g  0  5  6 13 19 26  g

f5bf595bf4139b4ab2912b6987c630e1.png

使用上表,我们将以下GPIO连接到未知头:

62a373e994e3265c06426327fb1855df.png

JTAGenum.sh我们将pins变量修改如下:

pins=(9 11 25 2 3 10) 

pinnames=(pin1 pin2 pin3 pin4 pin5 pin6)

现在将引脚连接好,并且逻辑电平转换器就位,我们可以运行了JTAGenum.sh。

运行如下所示连接的脚本会产生大量结果,可以在此处看到输出。对我们来说幸运的是,它正确地标识了两种可能的配置,如下所示:

 FOUND!  ntrst:pin4 (RPi GPIO 2) tck:pin6 (RPi GPIO 10) tms:pin1 (RPi GPIO 9) tdo:pin3 (RPi GPIO 25) tdi:pin2 (RPi GPIO 11) IR length: 4

 FOUND!  ntrst:pin5 (RPi GPIO 3) tck:pin6 (RPi GPIO 10) tms:pin1 (RPi GPIO 9) tdo:pin3 (RPi GPIO 25) tdi:pin2 (RPi GPIO 11) IR length: 4

接下来,脚本运行ID扫描。你可能会注意到为此生成了很多结果,我们如何过滤这些结果?你可以执行一些操作来筛选结果,例如,扫描链上可能只有1-2个设备(CPU和闪存),因此我们可以立即忽略那些具有2-3个以上条目的设备。接下来,你可以排除序列长(大于4-5)为1或0的序列。幸运的是,在此列表中,有一个我之前见过的ID:0x4ba00477 -该ID用于ARM Cortex内核,在尝试访问Beaglebone Black时,我已经见过它。

 ntrst:pin4 tck:pin6 tms:pin1 tdo:pin3 tdi:pin2  devices: 1

 0x4ba00477

 ntrst:pin4 tck:pin6 tms:pin1 tdo:pin3 tdi:pin5  devices: 1

 0x4ba00477

 ntrst:pin5 tck:pin6 tms:pin1 tdo:pin3 tdi:pin2  devices: 1

 0x4ba00477

 ntrst:pin5 tck:pin6 tms:pin1 tdo:pin3 tdi:pin4  devices: 1

 0x4ba00477

你会注意到,在进行IDCODE扫描时,for的值会TDI有所不同,这是因为此方法完全不依赖,TDI因此只是一种猜测。

幸运的是,其中一些结果与模式扫描非常吻合,因此我们现在可以假设我们知道JTAG接口的引脚排列!

4e5526bda9050de6a5a042145d43961f.png

实际示例:使用UrJtag确定指令长度

尽管OpenOCD非常适合与DAP控制器接口和连接到调试内核,但是UrJTAG项目非常适合与底层JTAG接口。我们可以使用它们通过有用的discover命令来检测各种DR长度。此方法使用前面提到的相同原理来选择,IR然后将大量的1移入DR,然后移入0,然后对多个1进行计时,直到在TDO上读取0!

UrJTAG可以使用位于~/.jtag/rc我的rc文件如下

 pi@raspberrypi:~ $ cat .jtag/rc 

 cable gpio tck=10 tms=9 tdi=11 tdo=25

 detect

 discover

下面我们可以看到使用这些命令运行UrJTAG的结果:

 pi@raspberrypi:~ $ sudo -E jtag 

 UrJTAG 2019.12 #

 Copyright (C) 2002, 2003 ETC s.r.o.

 Copyright (C) 2007, 2008, 2009 Kolja Waschk and the respective authors

 UrJTAG is free software, covered by the GNU General Public License, and you are

 welcome to change it and/or distribute copies of it under certain conditions.

 There is no warranty for UrJTAG.

 warning: UrJTAG may damage your hardware!

 Type "quit" to exit, "help" for help.

 Initializing GPIO JTAG Chain

 IR length: 4

 Chain length: 1

 Device Id: 01001011101000000000010001110111 (0x4BA00477)

   Unknown manufacturer! (01000111011) (/usr/local/share/urjtag/MANUFACTURERS)

 Detecting IR length ... 4

 Detecting DR length for IR 1111 ... 1

 Detecting DR length for IR 0000 ... 1

 Detecting DR length for IR 0001 ... 1

 Detecting DR length for IR 0010 ... 1

 Detecting DR length for IR 0011 ... 1

 Detecting DR length for IR 0100 ... 1

 Detecting DR length for IR 0101 ... 1

 Detecting DR length for IR 0110 ... 1

 Detecting DR length for IR 0111 ... 1

 Detecting DR length for IR 1000 ... 35

 Detecting DR length for IR 1001 ... 1

 Detecting DR length for IR 1010 ... 35

 Detecting DR length for IR 1011 ... 35

 Detecting DR length for IR 1100 ... 1

 Detecting DR length for IR 1101 ... 1

 Detecting DR length for IR 1110 ... 32

我想在这篇文章中重点介绍UrJTAG,因为在查看具有完全未知的扫描链或DAP架构的目标时,它非常有用。对我们来说幸运的是IDCODE,此目标的告诉我们它是ARM架构,我们很可能将能够使用CoreSight DAP,为此,我们将使用OpenOCD。如果你正在寻找一无所知的扫描链,那么我通常从UrJtag开始,只是要获取所有寄存器的映射。UrJTAG的python绑定也可以很好地工作,并且可以用于与JTAG进行低级接口。

14028bb44e3a0dde4d5836fb73c33ecb.png

0x05 通过OpenOCD进行JTAG调试

由于我们知道目标上JTAG接口的引脚排列,因此我们现在可以继续使用OpenOCD与之通信。我之所以选择OpenOCD是因为它具有对ARM MCU的出色调试支持,尤其是使用CoreSight的Cortex系列。我们需要做的第一件事是选择一个硬件适配器,我们将使用FT2232H中断模块。

通过FT2232H进行JTAG调试

了解了引脚排列后,我们现在可以尝试使用OpenOCD与DAP进行通信。为此,我们将使用FT2232H适配器,在本文中,我将使用标准的FT2232H分支板。这些板可用于与多个硬件级别的接口交互,并具有出色的软件支持。你可能还记得我曾经将它们用于SWD以及转储SPI闪存。使用该板,以及3.3V至1.8V逻辑电平转换器,我们可以将其连接到目标,如下所示:

6683edf52a57eff7ee01c6112e8ad55b.png

接下来,我们将从关于目标的已知变量开始编写配置文件。

 source [find target/swj-dp.tcl]

 # This is using the name on the SoC

 if { [info exists CHIPNAME] } {

   set _CHIPNAME $CHIPNAME

 } else {

   set _CHIPNAME s4ln045x01

 }

 # This is the TAP ID that we discovered in the previous step

 if { [info exists CPUTAPID] } {

   set _CPUTAPID $CPUTAPID

 } else {

   set _CPUTAPID 0x4ba00477

 }

 # Set the speed of our adapter

 adapter_khz 200

 # We are indeed using JTAG

 transport select jtag

 # We don't have a SRST pin, only TRST it would seem

 reset_config trst_only

 # Here we create the JTAG TAP/DAP, defining the location and characteristics of our DAP

 swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID

 dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu

 set _TARGETNAME $_CHIPNAME.cpu

当我们使用此配置文件运行openocd时,结果如下:

 wrongbaud@wubuntu:~/blog/samsung-jtag$ sudo openocd -f minimodule.cfg -f config.cfg 

 Open On-Chip Debugger 0.10.0+dev-01040-ge7e681ac (2020-01-27-18:55)

 Licensed under GNU GPL v2

 For bug reports, read

         http://openocd.org/doc/doxygen/bugs.html

 Info : auto-selecting first available session transport "jtag". To override use 'transport select '.

 Warn : Transport "jtag" was already selected

 Info : clock speed 200 kHz

 Info : JTAG tap: s4ln045x01.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4)

 Info : Listening on port 6666 for tcl connections

 Info : Listening on port 4444 for telnet connections

 Info : JTAG tap: s4ln045x01.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4)

 Warn : gdb services need one or more targets defined

现在让我们看一下DAP,看看那里是否还有其他相关信息:

 > dap info 0

 DAP transaction stalled (WAIT) - slowing down

 DAP transaction stalled (WAIT) - slowing down

 AP ID register 0x24770002

         Type is MEM-AP APB

 MEM-AP BASE 0x80000000

         ROM table in legacy format

                 Component base address 0x80000000

                 Peripheral ID 0x0000080000

                 Designer is 0x080,                  Part is 0x0, Unrecognized

                 Component class is 0x1, ROM table

                 MEMTYPE system memory not present: dedicated debug bus

         ROMTABLE[0x0] = 0x1003

                 Component base address 0x80001000

                 Peripheral ID 0x04008bbc14

                 Designer is 0x4bb, ARM Ltd.

                 Part is 0xc14, Cortex-R4 Debug (Debug Unit)

                 Component class is 0x9, CoreSight component

                 Type is 0x15, Debug Logic, Processor

         ROMTABLE[0x4] = 0x2003

                 Component base address 0x80002000

                 Peripheral ID 0x04008bbc14

                 Designer is 0x4bb, ARM Ltd.

                 Part is 0xc14, Cortex-R4 Debug (Debug Unit)

                 Component class is 0x9, CoreSight component

                 Type is 0x15, Debug Logic, Processor

         ROMTABLE[0x8] = 0x3003

                 Component base address 0x80003000

                 Peripheral ID 0x04008bbc14

                 Designer is 0x4bb, ARM Ltd.

                 Part is 0xc14, Cortex-R4 Debug (Debug Unit)

                 Component class is 0x9, CoreSight component

                 Type is 0x15, Debug Logic, Processor

         ROMTABLE[0xc] = 0x4003

                 Component base address 0x80004000

                 Invalid CID 0x00000000

         ROMTABLE[0x10] = 0x5003

                 Component base address 0x80005000

                 Invalid CID 0x00000000

         ROMTABLE[0x14] = 0x6003

                 Component base address 0x80006000

                 Invalid CID 0x00000000

         ROMTABLE[0x18] = 0x7003

                 Component base address 0x80007000

                 Invalid CID 0x00000000

         ROMTABLE[0x1c] = 0x8003

                 Component base address 0x80008000

                 Invalid CID 0x00000000

         ROMTABLE[0x20] = 0x9003

                 Component base address 0x80009000

                 Invalid CID 0x00000000

         ROMTABLE[0x24] = 0xa003

                 Component base address 0x8000a000

                 Invalid CID 0x00000000

         ROMTABLE[0x28] = 0xb003

                 Component base address 0x8000b000

                 Invalid CID 0x00000000

         ROMTABLE[0x2c] = 0xc003

                 Component base address 0x8000c000

                 Invalid CID 0x00000000

         ROMTABLE[0x30] = 0xd003

                 Component base address 0x8000d000

                 Invalid CID 0x00000000

         ROMTABLE[0x34] = 0xe003

                 Component base address 0x8000e000

                 Invalid CID 0x00000000

         ROMTABLE[0x38] = 0xf003

                 Component base address 0x8000f000

                 Invalid CID 0x00000000

         ROMTABLE[0x3c] = 0x0

                 End of ROM table

首先要指出的是这是Cortex R4,有了这些附加信息,我们可以在配置文件中创建目标,该目标应授予对MEM-AP的访问权限,以便进行调试。这可以通过添加以下行来完成:

target create $_TARGETNAME.1 cortex_r4 -endian $_ENDIAN -dap $_CHIPNAME.dap

在这一行中,我们可以尝试通过halt命令暂停目标并通过mdwOpenOCD提示符读取内存:

 > halt

 MPIDR not in multiprocessor format

 target halted in Thumb state due to debug-request, current mode: Supervisor

 cpsr: 0x80000133 pc: 0x0001abfc

 D-Cache: disabled, I-Cache: disabled

 > mdw 0x800000000 10

 DAP transaction stalled (WAIT) - slowing down

 0x800000000: eafffffe ea000005 ea000006 ea000006 ea00000b e320f000 ea00000e eafffffe

 0x800000020: ea0000e3 eafffffe

在这里,我们测试逐步运行的固件:

 > halt

 MPIDR not in multiprocessor format

 target halted in ARM state due to debug-request, current mode: Supervisor

 cpsr: 0x80000113 pc: 0x0000e10c

 D-Cache: disabled, I-Cache: disabled

 > step

 target halted in ARM state due to breakpoint, current mode: Supervisor

 cpsr: 0x80000113 pc: 0x0000e110

 D-Cache: disabled, I-Cache: disabled

成功运行,我们可以单步调试固件。接下来,让我们使用此功能获取一些RAM转储,此页面概述了内存模型,因此我们可以将其用作参考。可以使用OpenOCD通过dump_image命令将内存转储到文件中。

 > halt

 MPIDR not in multiprocessor format

 target halted in ARM state due to debug-request, current mode: Abort

 cpsr: 0x200001d7 pc: 0x00000048

 D-Cache: disabled, I-Cache: disabled

 Data fault registers        DFSR: 00000008, DFAR: 9f7e3000

 Instruction fault registers IFSR: 00000000, IFAR: 00000000

 > dump_image SDRAM.bin 0x20000000 0xA0000000

 > dump_image RAM.bin 0 0xFFFFFFF

最后,让我们看一下这些RAM转储并将它们加载到GHIDRA中,看它们是否有意义:

b4a8b452437e78345a20dd317457bdb9.png

太好了,我们有一些外部参照,并且init代码看起来还不错。看起来还好像在UART上提供了某种调试菜单,这很可能是我们引脚上的8/9引脚!可以肯定地说这是一个有效的RAM转储,并以此结束本文。

14028bb44e3a0dde4d5836fb73c33ecb.png

0x06 分析总结

这是一篇很长的文章,实际上,它可能应该分成2-3个部分。通过这篇文章,我们学习了JTAG的底层功能,以及如何使JTAG成为逆向工程师的利器。我们还能够通过JTAG访问未记录的目标,提取内存并单步运行固件。这里还有很多事情要做,例如确定闪存芯片本身是否可以通过JTAG转储,RE固件以寻找有趣的方式来从驱动器中恢复数据。

http://www2.futureware.at/~philipp/ssd/TheMissingManual.pdf

14028bb44e3a0dde4d5836fb73c33ecb.png

0x07 参考资料

· https://github.com/thesourcerer8/SSDdiag

· http://www2.futureware.at/~philipp/ssd/TheMissingManual.pdf

参考及来源:https://wrongbaud.github.io/jtag-hdd/

356931ecca7e552440c42423d0f2174d.png

898b29420cba213bd84a25cfd2e9619b.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/533989.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python virtualenv conda_在vscode中启动conda虚拟环境的思路详解

问题:cudatoolkit cudnn 通过conda 虚拟环境安装,先前已经使用virtualenv安装tf,需要在conda虚拟环境中启动外部python虚拟环境思路:conda prompt即将 [虚拟环境位置] 以参数形式传入 [activate.bat]VSOCDE中的设置添加以下语句{&…

远程过程调用失败_Java开发大型互联网RPC远程调用服务实现之问题处理方案

引言RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络…

chrome 新的session 设置_为什么还是由这么多人搞不懂Cookie、Session、Token?

作者:不学无数的程序员链接:https://urlify.cn/Yfm6Vr# Cookie洛:大爷,楼上322住的是马冬梅家吧? 大爷:马都什么? 夏洛:马冬梅。 7大爷:什么都没啊? 夏洛…

eview面板数据之混合回归模型_【视频教程】Eviews系列25|面板数据回归分析之Hausman检验及本章常见问题解答...

点击上方关注我们!本期我们学习Eviews统计建模最后一部分--面板数据回归分析Hausman检验及本章常见问题解答。实操:Hausman检验判断是固定效应模型还是随机效应模型上期我们讲到模型判断若选择模型2,需进一步通过Hausman检验判断固定效应还是随机效应,接…

mybatis mysql selectkey_Mybatis示例之SelectKey的应用

SelectKey在Mybatis中是为了解决Insert数据时不支持主键自动生成的问题,他可以很随意的设置生成主键的方式。不管SelectKey有多好,尽量不要遇到这种情况吧,毕竟很麻烦。SelectKey需要注意order属性,像Mysql一类支持自动增长类型的…

java treetable_在Swing中创建TreeTable | 学步园

TreeTable是Tree和Table的一个结合-就是一个即能够展开和收起行,同时也能够显示多个列的组件。在Swing的标准包里没有一个叫做JtreeTable的组件,但是我们很容易通过把Jtree做成Jtable的渲染器来创建一个这样的组件。这篇文章就是关于如何使用…

python期末大作业_大一期末考试很重要,考得好不仅有机会有钱拿,还有机会换专业...

现阶段很多高校放寒假的时间已经公布,这也就意味着,大学期末考试即将到来。对于大一新生来说,大学的期末考试是比较新鲜的,因为大家都没有经历过。经历过大学考试的学生,都知道大学的大概学习模式,一般情况…

java http 302重定向_Java 纯HTTP请求 禁止302自动重定向

Java 纯HTTP Get请求获取响应内容,如果发生302重定向,继而模拟请求域获取重定向后的响应内容。关键点:设置conn.setInstanceFollowRedirects为false即可示例代码public static void main(String[] args) {try {StringBuffer buffer new Stri…

python 且_Pyface库:一个基于pyqt、pyside、wx且简化的python的GUI

1 说明:1.1 Pyface库由大名鼎鼎的enthought出品。1.2 介绍:1.2.1 英文:traits-capable windowing framework.The pyface project contains a toolkit-independent GUI abstraction layer, which is used to support the "visualization&…

java方法的参数类型_Java 基础 14 方法的重载 与 方法参数类型详解

1.1 方法重载的概述和特点方法重载概述在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。方法重载特点与返回值类型无关,只看方法名和参数列表在调用时,虚拟机通过参数列表的不同来区分同名方法…

crv仪表上的i是什么指示灯_汽车打不着火是怎么回事,仪表盘汽车发动机故障灯亮是什么情况故障指示灯图解大全集...

如果打不着火,那有可能是起动机坏了,有可能是电池没电了,有可能是电路出现了问题,还有可能是点火系统出现了问题。汽车发动机的点火系统主要部件是火花塞和点火线圈,火花塞是一个需要定期更换的易损件。如果火花塞长时…

restful风格_什么是RESTful风格的API设计?

随着移动互联网的兴起,RESTful风格的API设计也随之流行起来,但我们说了那么多RESTful设计,它到底是什么?本篇文章带大家来了解一下它的真实面目。RESTful概念首先,我们需要明确的是RESTful,它是一个理念&am…

zookeeper 分布式锁_关于redis分布式锁,zookeeper分布式锁原理的一些学习与思考

编辑:业余草来源:https://www.xttblog.com/?p4946首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法、变量。在一个进程中,也就是一…

网页无法调用java9_JAVA 9 (内部类,异常,包)

内部类:将一个类定义在另一个类里面,称里面那个类为内部类。举例:class Zx{public static void main(String []arr){Outer o new Outer();o.method();}}class Outer{class Inner //内部类,可以定义多个内部类{void function(){S…

spark算子_Spark篇之持久化算子

一、前述Spark中控制算子也是懒执行的,需要Action算子触发才能执行,主要是为了对数据进行缓存。控制算子有三种,cache,persist,checkpoint,以上算子都可以将RDD持久化,持久化的单位是partition。cache和persist都是懒执…

java g1 gc ref proc_深入理解垃圾收集器的G1及日志分析

尽管Hotspot 最新的垃圾回收器G1是在2006年推出的。但是G1从推行至今的市场反响来看,但现在足以证明这款垃圾收集器是经得起考验的,从java9开始,就默认为G1垃圾收集器。G1是一款面向服务端应用的垃圾收集器。HotSpot开发团队赋予它的使命是(在…

gif透明背景动画_【超实用干货! 】iPad上的动画App大推荐

作者/立夏编辑/彼方大家好,我是立夏。大概在两年前吧我为大家写过几款动画APP的评测,这一次我也想给大家推荐一些我的新宠,供大家参考。我在这里就不过多提及如Animation Desk、Procreate或是Callipeg之类知名度相对更高一些的动画App了&…

iphone如何信任软件_【手机软件】千禾影院:全新观影神器,支持安卓+iOS,最新、最全、高清、免费!...

Hello,大家好,我是春哥!每天记得打卡哦!感谢每一位小伙伴们的关注和支持!免责声明大部分资源来源于网络,仅供学习和交流使用,如有侵权请联系我们删除。每期文章末尾都会有关键词,在公众号发消息…

Java小魔女芭芭拉_沉迷蘑菇不可自拔,黏土人《小魔女学园》苏西·曼芭芭拉 图赏...

GOOD SMILE出品的黏土人系列手办新作——《小魔女学园》苏西曼芭芭拉,已经开始接受预定了。这款黏土人的原型师是来自中国上海的陈天,售价4167日元,预计2018年4月发售。苏西是主人公亚可的室友,她是从东南亚来的身份不明的魔女。热…

java int相除向上取整_java实战项目常用类,Date、Calendar、BigDecimal、Math、UUID

Java开发中经常用到的类和方法,以下主要就日期是时间处理、金融数字处理、数学计算、随机数、MD5加密等。java.util.Date类java.util 包提供了 Date 类来封装当前的日期和时间。 Date 类提供两个构造函数来实例化 Date 对象。日期时间的本质是一个long,它…