嵌入式安全利器——JTAG
他是 2015年 GeekPwn大會上 TK口中的小馬,又一位亂入安全圈的鍊金術師(原是化學專業)——HyperChem。玩過幾年軟體脫殼的他,目前研究主要集中在嵌入式安全、固件逆向等方向。
這位來自騰訊安全武實驗室的研究員 HyperChem在 GeekPwn2017上海站「極客沙龍」現場為大家帶來智能硬體安全領域的分享。
「JTAG調試對於嵌入式安全研究具有非凡的威力,可以讀寫內存,可以控制 CPU運行狀態,可以調試代碼,幾乎無所不能。可是如何對一個未知的設備進行JTAG調試呢?進行JTAG調試都需要什麼步驟和準備工作呢?本次主題將一一揭示。」
大家好,我是來自騰訊安全玄武是實驗室研究員 HyperChem,也可以叫我 HC。今天和大家分享一下 JTAG調試,有做嵌入式安全的同學可能對 JTAG這個東西比較了解,如果我們可以獲得調試許可權,對我們是很有用的。
Advertisements
JTAG究竟是什麼?
JTAG其實是 Joint Test Action Group縮寫,後來成為了一個標準,成為了 IEEE的標準 1149.1。最開始 JTAG用於測試 IC晶元是否可以正常工作,DSP、FPGA等晶元同樣存在 JTAG。
JTAG可以進行晶元的調試,可以控制晶元執行任意的代碼。進行嵌入式開發的時候,用來下載固件,如果大家玩路由的時候應該是用 JTAG進行編程,當然我們也可以用 JTAG來讀寫內存。
我們先了解一下 JTAG的電氣結構。它有一個可選的引腳 TRST,還有 4個必須的引腳,TMS、TCK、TDI和 TDO。JTAG其實通過 Test Access Tort測試訪問口進行控制,JTAG控制器有 16種狀態。它的狀態切換就是由 JTAG的 TMS引腳 1和 0完成的。
Advertisements
JTAG命令。它在 1149.1中規定了幾個強制的命令,一個是 bypass命令,用於加快測試效率,還有一個外部測試指令,啟用外部電路的測試使用的。還有內部測試指令,用於對晶元內部的匯流排等部件進行測試。此外,大部分 IC晶元都有個 IDCODE,通常對應一個 IDCODE命令。
舉個栗子:一個簡單的 JTAG
我們在這 6個引腳輸出點,設置 6個移位寄存器。當你不進行 JTAG調試的時候,這 6個移位寄存器不會有任何用處,但是如果我們進行 JTAG調試的時候,我們會通過這寫移位寄存器向真實的引腳寫入值,也可以通過移位寄存器讀取當前引腳的狀態。因為 JTAG最開始設計的時候是為了監測晶元輸入輸出引腳狀態的,而這些引腳都在晶元的邊界上,因此稱之為邊界掃描鏈。
JTAG大概有 3個寄存器,一個是 IDCODE寄存器,一個 BYPASS寄存器和邊界掃描寄存器。JTAG測試的過程其實就是通過 TAP完成的。那麼,JTAG到底是如何實現這樣的一個嘗試的?現在以 ARMV9晶元的寫內存流程來做一個例子。
首先我們需要選擇一個邊界掃描鏈,我們需要控制裡面的數據,然後設置一個 JTAG的命令,這個命令是選擇內部測試模式,就是一個內部測試的命令,這個內部測試會導致我們所有操作在 CPU內部,我們進行讀和寫不會對內存和外部設備的內容給造成影響。
大家知道 CPU執行指令的時候會將它的指令會有一個階段把指令讀到數據匯流排上,這個時候我們向數據匯流排寫入一個指令,這個指令的含義是把 R0和 R1寫到 R0指向的地址,但是這個指令的意義不重要,這個操作的意義在於 R0和 R1的數值會出現在後面的執行階段。到後面的執行階段,再修改數據匯流排把 R0和 R1的值進行修改成我們需要改的樣子。
等它執行完畢,這個操作不會造成任何的影響。接著我們調整下一條指令的執行模式,這個時候設置一個標誌位,這個標誌位可以暫時掛你內部測試模式,這個意思就是說,這個指令會實際進行操作,它會真的把數據寫進去。然後我們等待執行完畢,整個寫內存的操作就完成了,讀內存的過程其實也是差不多,只需要我們把 STR換成 LDR就可以了。這就是 JTAG的一個流程。
如何利用 JTAG ?
如果我們對一個設備進行 JTAG調試,我們需要具備幾個要素,首先需要知道 4個引腳在哪裡,這樣才可以連上去;然後我們需要一個適配器,這個適配器主要完成信號的電氣轉換,這樣我們可以通過電腦上 1010對 TAP控制器進行控制;接著我們需要一個適配器的配置文件;接下來是調試軟體以及調試 CPU的信息,最後我們需要一個重置的手段。
首先尋找 JTAG的引腳,目前比較好的找 JTAG的工具就是 JTAGULATOR這,它是個自動化尋找 JTAG引腳的工具,然後接著需要一個合適的適配器。我上面列舉了一些適配器,適配器的目的主要是實現進行電氣和電平的轉換,我們講到 JTAG其實它上面就是 1010的信號,這個對於我們通過軟體實現其實很困難,我們需要適配器替我們完成這部分工作。
它大概有幾個類型,最開始的適配器通過列印口完成調試。現在比較流行的適配器是 FTDI類型的以及一些私有設備的介面,還有採用 COM口和網口進行通訊。我這裡是今天演示用到目前的適配器,這個採用的就是比較流行的 FTDI介面。
下面是調試軟體。用於 JTAG調試的軟體有很多,一些修手機用的一些軟體,都是商業軟體,開源軟體的代表就是各個平台都支持的 GDB。我們今天用到的軟體叫 OpenOCD,這個東西可以提供我們比較好的介面。
這是 CPU的配置文件,在 OpenOCD中定義不同 CPU的文件,包含 CPU中 JTAG指令的定義以及邊界掃描鏈。
接下來是適配器的配置文件,其實就是描述了我們上層軟體怎麼和適配器連接。
然後是重置條件,如果用商業軟體它會電氣層實現這樣的東西,重置條件的含義是,當你的適配器連上 JTAG的時候,TAP控制器和 CPU可以處於任何的狀態,不知道它的狀態是什麼,我們需要讓 CPU回到已知的狀態,這時候需要重置。對 CPU來講會有一個引腳,檢測到電壓過大或者過小會直接重置。
如何對未知設備進行 JTAG調試?
首先識別它的引腳,然後獲取 IDCODE,接著通過 IDCODE尋找 CPU配置文件。OpenOCD默認包含了很多 CPU的配置文件,可以嘗試在這些文件中搜索。然後選擇好合適的適配器及其配置文件就可以進行調試了。