jtag引脚定义_从逆向分析的角度学习硬件调试技巧JTAG,SSD和固件提取
我想從逆向的角度做了深入了解JTAG,JTAG是許多嵌入式CPU使用的硬件級(jí)別調(diào)試機(jī)制,我希望通過這篇文章從逆向工程師的角度解釋如何使用JTAG,并在此過程中提供一些實(shí)際示例。
0x01 研究目標(biāo)
通過這篇文章,我希望做到以下幾點(diǎn):
1. 解釋JTAG的工作原理;
2. 演示如何發(fā)現(xiàn)和利用未知目標(biāo)上的JTAG端口/接口;
3. 提供一些當(dāng)前可用于與JTAG接口交互的OSS工具的概述;
4. 利用JTAG提取固件并調(diào)試目標(biāo)。
另外,在概述之前,我列出一些學(xué)習(xí)JTAG的資源
·?Cyphunk’s Embedded Analysis Page
·?FPGA4Fun JTAG Overview
·?Blackbox JTAG Reverse Engineering
0x02 JTAG概述
JTAG是一種硬件接口,旨在幫助開發(fā)人員和測(cè)試人員進(jìn)行調(diào)試。JTAG最初是為了測(cè)試集成電路而開發(fā)的,更具體地說,是對(duì)被測(cè)目標(biāo)上的IO引腳進(jìn)行采樣。這種類型的調(diào)試接口使工程師可以在不需要物理引腳本身的情況下測(cè)試PCB上的連接。JTAG接口通過以下概述的狀態(tài)機(jī)進(jìn)行控制:
關(guān)于此級(jí)別的JTAG,要記住的重要事情之一是它涉及兩個(gè)寄存器,即指令寄存器和數(shù)據(jù)寄存器。要使用這些寄存器,必須使用以下接口信號(hào)輸入上述狀態(tài)機(jī)中的正確狀態(tài):
使用TMS和TCK線瀏覽狀態(tài)機(jī),同時(shí)分別通過TDI和TDO寫入或讀取數(shù)據(jù)。在TCK的上升沿對(duì)TMS進(jìn)行采樣,這意味著必須先聲明TMS線,然后才能將TCK切換為在狀態(tài)機(jī)中導(dǎo)航。然后根據(jù)JTAG狀態(tài)機(jī)的狀態(tài)將數(shù)據(jù)移入指令寄存器(IR)或數(shù)據(jù)寄存器(DR)。當(dāng)完成一個(gè)操作(或更新DR / IR相后)所得到的數(shù)據(jù)可以被移位通過輸入DR的Shift-DR狀態(tài)。有了這些原語,制造商可以實(shí)現(xiàn)他們希望通過JTAG實(shí)現(xiàn)的任何功能。
JTAG標(biāo)準(zhǔn)將IR和DR視為移位寄存器,因此,可以將多個(gè)目標(biāo)鏈在一起。
簡(jiǎn)而言之,JTAG定義了一個(gè)狀態(tài)機(jī),該狀態(tài)機(jī)至少使用4個(gè)信號(hào)進(jìn)行導(dǎo)航。有了此狀態(tài)機(jī),最終用戶可以從兩個(gè)移位寄存器IR和DR進(jìn)行寫入和讀取。
JTAG寄存器
JTAG利用兩個(gè)主要寄存器,指令寄存器和數(shù)據(jù)寄存器。指令寄存器用于確定JTAG控制器將要執(zhí)行的功能,例如存儲(chǔ)器讀取或存儲(chǔ)器寫入。數(shù)據(jù)寄存器然后用作指令寄存器的附加輸入,對(duì)于前面的示例,它們可以用于提供要讀取或?qū)懭氲牡刂贰_@些寄存器的大小可以根據(jù)其功能而有所不同。
要寫入寄存器,將執(zhí)行以下步驟,我們以IR為例:
1. 輸入Test Logic Reset狀態(tài)(TLR)(可以通過斷言TMS線路并循環(huán)CLK5次來完成此操作);
2. 進(jìn)入Select IR Scan狀態(tài);
3. 進(jìn)入Capture IR狀態(tài);
4. Enter Shift IR–這是我們將數(shù)據(jù)從TDI加載到IR的地方;
5. 進(jìn)入Exit IR狀態(tài);
6. 進(jìn)入U(xiǎn)pdate IR狀態(tài)–此階段將值“鎖存”到IR中。
此后,如果不需要數(shù)據(jù)寄存器,則將執(zhí)行該操作,并將結(jié)果(如果有)加載到數(shù)據(jù)寄存器中以移出。但是,許多指令也需要在操作之前填寫數(shù)據(jù)寄存器。在這種情況下,一旦數(shù)據(jù)寄存器被寫入并更新,就將執(zhí)行該操作,并且結(jié)果可以移出數(shù)據(jù)寄存器。
某些指令不需要加載DR,例如,如果我們已將IDCODE指令加載到IR(1110b)中,則會(huì)將處理器的IDCODE值加載到數(shù)據(jù)寄存器中,以便我們計(jì)時(shí)并繼續(xù)讀取TDO。要從中讀取結(jié)果TDO,將導(dǎo)航到該Shift-DR狀態(tài),并在上輸入32位TDI,這將導(dǎo)致數(shù)據(jù)寄存器中的數(shù)據(jù)TDO在線上移出。請(qǐng)參見下圖,直觀地了解如果向IR加載IDCODE指令后會(huì)發(fā)生什么情況。
重要的是要記住,IR并且DR可以將其視為移位寄存器,這意味著當(dāng)我們使用新值更新它們時(shí),舊值隨后會(huì)移出TDO。
JTAG標(biāo)準(zhǔn)定義了以下指令寄存器:
·??BYPASS
·?該指令連接TDI并TDO
·?在此Shift DR狀態(tài)下,數(shù)據(jù)從傳輸TDI到TDO的延遲為一個(gè)TCK周期
·?Capture DR狀態(tài)期間將0裝入數(shù)據(jù)寄存器
·?這可用于確定掃描鏈中有多少個(gè)設(shè)備
·??IDCODE
·?加載時(shí),將設(shè)備代碼ID寄存器選擇為TDI和TDO之間的串行路徑
·?在Capture-DR狀態(tài)下,將32位設(shè)備ID代碼加載到此移位部分中
·?在Shift-DR狀態(tài)下,此數(shù)據(jù)被移出,最低有效位在前
·?核心JTAG概念:
·?該狀態(tài)機(jī)被導(dǎo)航用4個(gè)信號(hào):TCK,TMS,TDO和TDI
·?TDI用于提供輸入,TDO用于輸出
·?使用此狀態(tài)機(jī),可以將數(shù)據(jù)移到IR(Shift IR)和DR(Shift DR)中
·?可以將指令寄存器(IR)視為函數(shù),而將數(shù)據(jù)寄存器(DR)視為該函數(shù)的參數(shù)
·?隨著數(shù)據(jù)移入DR和IR,先前的內(nèi)容移出TDO
·?一旦將數(shù)據(jù)移入這些寄存器,就可以執(zhí)行操作(除少數(shù)保留指令外,完全取決于主機(jī)實(shí)現(xiàn))
·?數(shù)據(jù)被讀出通過將其移動(dòng)到目標(biāo)的出TDO從數(shù)據(jù)在寄存器Shift DR狀態(tài)。
因此,既然我們已經(jīng)研究了JTAG的底層工作原理,那么我們應(yīng)該討論為什么我們會(huì)關(guān)心它,以及該接口如何為逆向工程師授予對(duì)有用功能的訪問權(quán)限。JTAG接口最常用的應(yīng)用程序之一是硬件級(jí)調(diào)試(因此,本文的標(biāo)題)。這是由芯片制造商實(shí)現(xiàn)的,并且可能因芯片而異,但是,針對(duì)ARM目標(biāo)的硬件級(jí)調(diào)試的最常見實(shí)現(xiàn)之一是ARM的CoreSight調(diào)試接口。這與我在上一篇文章中通過SWD進(jìn)行通信的實(shí)現(xiàn)相同,只是在這種情況下,調(diào)試訪問端口是通過JTAG進(jìn)行通信的。JTAG實(shí)現(xiàn)的細(xì)節(jié)可以在這里找到。對(duì)我們來說幸運(yùn)的是,可以使用一些出色的OSS工具與這些端口進(jìn)行通信-這篇文章將重點(diǎn)介紹使用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負(fù)責(zé)利用JTAG或SWD接口向最終用戶授予通過CoreSight DAP公開的調(diào)試接口提供的各種原語。Coresight / DAP體系結(jié)構(gòu)相當(dāng)復(fù)雜,在本篇文章(已經(jīng)很長(zhǎng)時(shí)間)中無法涵蓋,因此我有可能將其保存在另一篇文章中。
0x03 逆向工程師和JTAG
從逆向工程師的角度進(jìn)行此類操作時(shí),對(duì)協(xié)議基礎(chǔ)知識(shí)有扎實(shí)的了解非常重要。當(dāng)進(jìn)行逆向硬件(或軟件)時(shí),由于總是存在無限的未知數(shù),因此你希望掩蓋自己的基本事實(shí)。接下來的幾節(jié)將討論如何利用我們對(duì)這些協(xié)議的低級(jí)知識(shí)來幫助我們走上通過JTAG進(jìn)行硬件級(jí)調(diào)試的途徑。我們需要做的第一件事是確定引腳排列,以及是否暴露的引腳允許訪問JTAG接口。
確定引腳排列
JTAG信號(hào)線通常組合在一起,有時(shí)(如果非常幸運(yùn)的話),你將看到以下標(biāo)頭之一:
但是,如果你發(fā)現(xiàn)類似的內(nèi)容,則可能沒有確切的信號(hào)分組,因此,我們將討論如果假設(shè)某個(gè)引腳用于JTAG,則如何確定引腳。在進(jìn)行類似這樣的逆向工程時(shí),你想從已知的知識(shí)開始。因?yàn)槲覀冎来蠖鄶?shù)制造商至少會(huì)進(jìn)行IDCODE,所以BYPASS我們看看如何利用這兩個(gè)說明。
如果你確定自己認(rèn)為是潛在的JTAG標(biāo)頭或引腳,但不知道引腳,則可以使用這兩個(gè)寄存器的行為來確定引腳。
由于該IDCODE寄存器通常作為默認(rèn)IR加載,因此可以通過執(zhí)行以下操作來測(cè)試假定的引腳排列:
1. 將角色分配給潛在的輸出引腳(TMS,TCK等);
2. 輸入Test Logic Reset狀態(tài);
3. 輸入Select DR Scan,Capture DR,Shift DR;
4. 時(shí)鐘32點(diǎn)的值TDI,并監(jiān)測(cè)TDO一個(gè)有效的IDCODE值;
5. IDCODE如果看起來有效,請(qǐng)檢查移出的值!否則,請(qǐng)重新分配引腳并重復(fù)!
除了利用IDCODE默認(rèn)情況下經(jīng)常將寄存器加載到IR中這一事實(shí)外,我們還可以利用IR和DR都充當(dāng)移位寄存器這一事實(shí),因此,如果我們假設(shè)一個(gè)通用的寄存器長(zhǎng)度(32位通常有效),我們可以嘗試執(zhí)行以下操作以強(qiáng)行設(shè)置插腳:
1. 將角色分配給潛在的輸出引腳(TMS,TCK等);
2. 使用這些假定值輸入Test Logic Reset狀態(tài);
3. 輸入Shift IR狀態(tài);
4. 移入一個(gè)唯一的32位值 TDI;
5. TDI在監(jiān)視你在TDO上的唯一模式時(shí),繼續(xù)將1切換為開(請(qǐng)確保至少進(jìn)行32次操作!)。
6. 如果發(fā)現(xiàn)了模式,那就恭喜!否則,為引腳選擇新的分配并重復(fù)!
這兩種方法是通過前面提到的使用JTAGEnum腳本,還有JTAGULATOR。
確定指令長(zhǎng)度
一旦確定了目標(biāo)的引腳排列,即可開始真正的分析。下一步是確定IR / DR的長(zhǎng)度。為此,從IR開始,進(jìn)入Shift IR狀態(tài),并TDI使用1024或4096之類的大數(shù)字以1的on填充鏈,然后以0 TDI計(jì)數(shù)。一旦完成,只需繼續(xù)以1的on 計(jì)數(shù),計(jì)數(shù)即可在出現(xiàn)0之前花費(fèi)的時(shí)鐘周期數(shù)TDO。這將告訴你IR的長(zhǎng)度。有了該名稱后,就可以輸入Shift DR狀態(tài)并重復(fù)此過程以確定DR的狀態(tài)。
http://urjtag.org/
0x04 實(shí)際示例:三星M.2 SSD
本文的目標(biāo)將是我最近從一臺(tái)較舊的筆記本電腦中恢復(fù)的三星M.2 SSD,在查看了PCB并找出可能是JTAG接頭的地方之后,我想從頭到尾概述一下該過程。
實(shí)際示例:查找JTAG標(biāo)頭/確定引腳排列
如前所述,JTAG線路經(jīng)常被分組-因此,從硬件角度看一個(gè)新平臺(tái)時(shí),尋找大于5的引腳分組總是一個(gè)好的開始。幸運(yùn)的是,在這個(gè)目標(biāo)上,PCB外側(cè)有9個(gè)過孔。讓我們開始檢查驅(qū)動(dòng)器在正常操作狀態(tài)下這些引腳的電壓電平。
從最初開始-這些電壓值不會(huì)告訴我們?nèi)魏涡畔?#xff0c;那么我們可以根據(jù)已有的信息確定什么?首先,我們有一個(gè)GND,通過在萬用表上使用連續(xù)性模式并針對(duì)USB連接器的屏蔽層(當(dāng)然要拔掉目標(biāo)!)進(jìn)行測(cè)試,很容易確定GND。接下來,我們有一條1.8V的線,通常會(huì)期望它是TMS,因?yàn)樵诖蠖鄶?shù)文檔中建議將其保持在高電平。
為了確定引腳排列,我們將使用Raspberry Pi和JTAGEnum項(xiàng)目。該腳本使用上述方法來嘗試識(shí)別JTAG引腳。同樣重要的是,這里的邏輯電平為1.8V,因此,如果要與該目標(biāo)接口,我們將需要使用邏輯電平轉(zhuǎn)換器。JTAGEnum.sh使用Raspberry Pi的GPIO線來激活目標(biāo)接口,在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
使用上表,我們將以下GPIO連接到未知頭:
JTAGenum.sh我們將pins變量修改如下:
pins=(9 11 25 2 3 10)?
pinnames=(pin1 pin2 pin3 pin4 pin5 pin6)
現(xiàn)在將引腳連接好,并且邏輯電平轉(zhuǎn)換器就位,我們可以運(yùn)行了JTAGenum.sh。
運(yùn)行如下所示連接的腳本會(huì)產(chǎn)生大量結(jié)果,可以在此處看到輸出。對(duì)我們來說幸運(yùn)的是,它正確地標(biāo)識(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
接下來,腳本運(yùn)行ID掃描。你可能會(huì)注意到為此生成了很多結(jié)果,我們?nèi)绾芜^濾這些結(jié)果?你可以執(zhí)行一些操作來篩選結(jié)果,例如,掃描鏈上可能只有1-2個(gè)設(shè)備(CPU和閃存),因此我們可以立即忽略那些具有2-3個(gè)以上條目的設(shè)備。接下來,你可以排除序列長(zhǎng)(大于4-5)為1或0的序列。幸運(yùn)的是,在此列表中,有一個(gè)我之前見過的ID:0x4ba00477 -該ID用于ARM Cortex內(nèi)核,在嘗試訪問Beaglebone Black時(shí),我已經(jīng)見過它。
?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
你會(huì)注意到,在進(jìn)行IDCODE掃描時(shí),for的值會(huì)TDI有所不同,這是因?yàn)榇朔椒ㄍ耆灰蕾?#xff0c;TDI因此只是一種猜測(cè)。
幸運(yùn)的是,其中一些結(jié)果與模式掃描非常吻合,因此我們現(xiàn)在可以假設(shè)我們知道JTAG接口的引腳排列!
實(shí)際示例:使用UrJtag確定指令長(zhǎng)度
盡管OpenOCD非常適合與DAP控制器接口和連接到調(diào)試內(nèi)核,但是UrJTAG項(xiàng)目非常適合與底層JTAG接口。我們可以使用它們通過有用的discover命令來檢測(cè)各種DR長(zhǎng)度。此方法使用前面提到的相同原理來選擇,IR然后將大量的1移入DR,然后移入0,然后對(duì)多個(gè)1進(jìn)行計(jì)時(shí),直到在TDO上讀取0!
UrJTAG可以使用位于~/.jtag/rc我的rc文件如下
?pi@raspberrypi:~ $ cat .jtag/rc?
?cable gpio tck=10 tms=9 tdi=11 tdo=25
?detect
?discover
下面我們可以看到使用這些命令運(yùn)行UrJTAG的結(jié)果:
?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
我想在這篇文章中重點(diǎn)介紹UrJTAG,因?yàn)樵诓榭淳哂型耆粗膾呙桄溁駾AP架構(gòu)的目標(biāo)時(shí),它非常有用。對(duì)我們來說幸運(yùn)的是IDCODE,此目標(biāo)的告訴我們它是ARM架構(gòu),我們很可能將能夠使用CoreSight DAP,為此,我們將使用OpenOCD。如果你正在尋找一無所知的掃描鏈,那么我通常從UrJtag開始,只是要獲取所有寄存器的映射。UrJTAG的python綁定也可以很好地工作,并且可以用于與JTAG進(jìn)行低級(jí)接口。
0x05 通過OpenOCD進(jìn)行JTAG調(diào)試
由于我們知道目標(biāo)上JTAG接口的引腳排列,因此我們現(xiàn)在可以繼續(xù)使用OpenOCD與之通信。我之所以選擇OpenOCD是因?yàn)樗哂袑?duì)ARM MCU的出色調(diào)試支持,尤其是使用CoreSight的Cortex系列。我們需要做的第一件事是選擇一個(gè)硬件適配器,我們將使用FT2232H中斷模塊。
通過FT2232H進(jìn)行JTAG調(diào)試
了解了引腳排列后,我們現(xiàn)在可以嘗試使用OpenOCD與DAP進(jìn)行通信。為此,我們將使用FT2232H適配器,在本文中,我將使用標(biāo)準(zhǔn)的FT2232H分支板。這些板可用于與多個(gè)硬件級(jí)別的接口交互,并具有出色的軟件支持。你可能還記得我曾經(jīng)將它們用于SWD以及轉(zhuǎn)儲(chǔ)SPI閃存。使用該板,以及3.3V至1.8V邏輯電平轉(zhuǎn)換器,我們可以將其連接到目標(biāo),如下所示:
接下來,我們將從關(guān)于目標(biāo)的已知變量開始編寫配置文件。
?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
當(dāng)我們使用此配置文件運(yùn)行openocd時(shí),結(jié)果如下:
?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
現(xiàn)在讓我們看一下DAP,看看那里是否還有其他相關(guān)信息:
?> 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,有了這些附加信息,我們可以在配置文件中創(chuàng)建目標(biāo),該目標(biāo)應(yīng)授予對(duì)MEM-AP的訪問權(quán)限,以便進(jìn)行調(diào)試。這可以通過添加以下行來完成:
target create $_TARGETNAME.1 cortex_r4 -endian $_ENDIAN -dap $_CHIPNAME.dap
在這一行中,我們可以嘗試通過halt命令暫停目標(biāo)并通過mdwOpenOCD提示符讀取內(nèi)存:
?> 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
在這里,我們測(cè)試逐步運(yùn)行的固件:
?> 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
成功運(yùn)行,我們可以單步調(diào)試固件。接下來,讓我們使用此功能獲取一些RAM轉(zhuǎn)儲(chǔ),此頁面概述了內(nèi)存模型,因此我們可以將其用作參考。可以使用OpenOCD通過dump_image命令將內(nèi)存轉(zhuǎn)儲(chǔ)到文件中。
?> 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轉(zhuǎn)儲(chǔ)并將它們加載到GHIDRA中,看它們是否有意義:
太好了,我們有一些外部參照,并且init代碼看起來還不錯(cuò)。看起來還好像在UART上提供了某種調(diào)試菜單,這很可能是我們引腳上的8/9引腳!可以肯定地說這是一個(gè)有效的RAM轉(zhuǎn)儲(chǔ),并以此結(jié)束本文。
0x06 分析總結(jié)
這是一篇很長(zhǎng)的文章,實(shí)際上,它可能應(yīng)該分成2-3個(gè)部分。通過這篇文章,我們學(xué)習(xí)了JTAG的底層功能,以及如何使JTAG成為逆向工程師的利器。我們還能夠通過JTAG訪問未記錄的目標(biāo),提取內(nèi)存并單步運(yùn)行固件。這里還有很多事情要做,例如確定閃存芯片本身是否可以通過JTAG轉(zhuǎn)儲(chǔ),RE固件以尋找有趣的方式來從驅(qū)動(dòng)器中恢復(fù)數(shù)據(jù)。
http://www2.futureware.at/~philipp/ssd/TheMissingManual.pdf
0x07 參考資料
·?https://github.com/thesourcerer8/SSDdiag
·?http://www2.futureware.at/~philipp/ssd/TheMissingManual.pdf
參考及來源:https://wrongbaud.github.io/jtag-hdd/
總結(jié)
以上是生活随笔為你收集整理的jtag引脚定义_从逆向分析的角度学习硬件调试技巧JTAG,SSD和固件提取的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 卡与卡之间怎么转账
- 下一篇: java mongodb 插入数据_mo