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.pswp.cn/news/533989.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/533989.shtml
英文地址,請注明出處:http://en.pswp.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中的設置添加以下語句{&…

python如何導入圖片imread_OpenCV 使用imread()函數讀取圖片的六種正確姿勢

經常看到有人在網上詢問關于imread()函數讀取圖片失敗的問題。今天心血來潮,經過實驗,總結出imread()調用的四種正確姿勢。通常我要獲取一張圖片的絕對路徑是這樣做的:在圖片上右鍵——屬性——安全——對象名稱。然后復制對象名稱就得到了圖…

python2.7與3.7腳本轉換_python 2.7 - python 3.7 升級記錄

更換的模塊python 3.7 模塊名python 2.7 模塊名python 3.7 包python 2.7包pymysqlMySQLdbPyMySQLMySQL-pythonpdfminerpdfminerpdfminer.sixpdfminerurllib.parseurlparse自帶自帶htmlHTMLParser自帶HTMLparser語法變化1. print 修改為 print()2. except Exception, e 修改為 e…

遠程過程調用失敗_Java開發大型互聯網RPC遠程調用服務實現之問題處理方案

引言RPC(Remote Procedure Call Protocol)——遠程過程調用協議,它是一種通過網絡從遠程計算機程序上請求服務,而不需要了解底層網絡技術的協議。RPC協議假定某些傳輸協議的存在,如TCP或UDP,為通信程序之間攜帶信息數據。在OSI網絡…

chrome 新的session 設置_為什么還是由這么多人搞不懂Cookie、Session、Token?

作者:不學無數的程序員鏈接:https://urlify.cn/Yfm6Vr# Cookie洛:大爺,樓上322住的是馬冬梅家吧? 大爺:馬都什么? 夏洛:馬冬梅。 7大爺:什么都沒啊? 夏洛…

mysql for update用處_for update的作用和用法

一、for update定義for update是一種行級鎖,又叫排它鎖,一旦用戶對某個行施加了行級加鎖,則該用戶可以查詢也可以更新被加鎖的數據行,其它用戶只能查詢但不能更新被加鎖的數據行.如果其它用戶想更新該表中的數據行&…

python大數據零基礎_零基礎學習大數據人工智能,學習路線篇!

大數據處理技術怎么學習呢?首先我們要學習Python語言和Linux操作系統,這兩個是學習大數據的基礎,學習的順序不分前后。Python:Python 的排名從去年開始就借助人工智能持續上升,現在它已經成為了語言排行第一名。從學習難易度來看…

python刪除文件和linux刪除文件區別_使用Python批量刪除文件列表

使用Python批量刪除文件列表環境:已知要刪除的文件列表,即確定哪些文件要刪除。代碼如下:#!/usr/bin/env python#codingutf-8#目的:本程序主要為刪除給定的文件列表import osimport shutil#引入模塊,os為包含普遍的操作…

華為python有必要學嗎_【華為云技術分享】這個 Python 庫有必要好好學學

這里看一個最基本的例子,這里給到一個 User 的 Class 定義,再給到一個 data 數據,像這樣:1 class User(object):2 def __init__(self, name, age):3 self.name name4 self.age age56 data [{7 name: Germey,8 age: 239 }, {10 nam…

python求平行四邊形面積_python 已知平行四邊形三個點,求第四個點的案例

我就廢話不多說了,大家還是直接看代碼吧!import numpy as np#已知平行四邊形三個點,求第四個點#計算兩點之間的距離def CalcEuclideanDistance(point1,point2):vec1 np.array(point1)vec2 np.array(point2)distance np.linalg.norm(vec1 -…

eview面板數據之混合回歸模型_【視頻教程】Eviews系列25|面板數據回歸分析之Hausman檢驗及本章常見問題解答...

點擊上方關注我們!本期我們學習Eviews統計建模最后一部分--面板數據回歸分析Hausman檢驗及本章常見問題解答。實操:Hausman檢驗判斷是固定效應模型還是隨機效應模型上期我們講到模型判斷若選擇模型2,需進一步通過Hausman檢驗判斷固定效應還是隨機效應,接…

python打出由邊框包圍的_python opencv 圖像邊框(填充)添加及圖像混合的實現方法(末尾實現類似幻燈片漸變的效果)...

圖像邊框的實現圖像邊框設計的主要函數cv.copyMakeBorder()——實現邊框填充主要參數如下:參數一:源圖像——如:讀取的img參數二——參數五分別是:上下左右邊的寬度——單位:像素參數六:邊框類型&#xff1…

mysql5.7.21備份腳本_Shell腳本使用匯總整理——mysql數據庫5.7.8以后備份腳本

#!/bin/sh#db_backups_conf.txt文件路徑db_backups_conf"/wocloud/shell/db_backups_conf.txt"#判斷文件是否存在if [ -f "${db_backups_conf}" ];thenecho $(date %Y-%m-%d %H:%M:%S)" 數據庫配置信息文件存在,開始進行數據備份"#獲…

python嵌套列表操作_python基礎(list列表的操作,公共方法,列表嵌套,元祖)...

list 列表索引,切片與str相同。列表的操作(增刪改查)1,增加.append()  追加,增加到最后li [alex,wusir,egon,女神,taibai]li.append(ppp)print(li).insert()  中間插入,通過索引li [alex,wusir,egon,女神,taibai]li.insert(…

mybatis mysql selectkey_Mybatis示例之SelectKey的應用

SelectKey在Mybatis中是為了解決Insert數據時不支持主鍵自動生成的問題,他可以很隨意的設置生成主鍵的方式。不管SelectKey有多好,盡量不要遇到這種情況吧,畢竟很麻煩。SelectKey需要注意order屬性,像Mysql一類支持自動增長類型的…

python程序設計上機實踐第三章答案_20192419 實驗三《Python程序設計》實驗報告

學號 2019-2020-2 《Python程序設計》實驗3報告課程:《Python程序設計》班級:1924姓名: 萬騰陽學號:20192419實驗教師:王志強實驗日期:2020年5月16日必修/選修: 公選課1.實驗內容創建服務端和客…

完成數獨的算法 python_python實現數獨算法實例

本文實例講述了python實現數獨算法的方法。分享給大家供大家參考。具體如下:# -*- coding: utf-8 -*-Created on 2012-10-5author: Administratorfrom collections import defaultdictimport itertoolsa [[ 0, 7, 0, 0, 0, 0, 0, 0, 0], #0[ 5, 0, 3, 0, 0, 6, 0, …

python讀取多個文件csv_Python:讀取多個文本文件并寫入相應的csv文件

我在別處找不到這個問題的答案,所以我將繼續把它貼在這里:我有一個Python腳本,它將讀取文本文件的內容,將其內容拆分為單詞,然后輸出一個CSV文件,該文件將文本縮減為單詞頻率列表。(最后,我將插…

java treetable_在Swing中創建TreeTable | 學步園

TreeTable是Tree和Table的一個結合-就是一個即能夠展開和收起行,同時也能夠顯示多個列的組件。在Swing的標準包里沒有一個叫做JtreeTable的組件,但是我們很容易通過把Jtree做成Jtable的渲染器來創建一個這樣的組件。這篇文章就是關于如何使用…

python爬去微博十大流行語_用python重新定義【2019十大網絡流行語】-后臺/架構/數據庫-敏捷大拇指-一個敢保留真話的IT精英社區...

↑關注 置頂 ~ 有趣的不像個技術號52568040f9313098ffa367d9d9d21437.jpg (5.73 KB, 下載次數: 0)2019-12-10 04:43 上傳3f4d5fe0016d011a7a68af763314befd.jpg (1.06 KB, 下載次數: 0)2019-12-10 04:43 上傳“文明互鑒真硬核,融梗檸檬誰覺得。霸凌第一九九六&…