鑒于最近圍繞惡意軟件的宣傳可以在硬盤固件中保持持久性,尋求更好地了解硬盤內部實際發生的事情似乎是合理的 - 特別是對固件的理解。
標準硬盤驅動器的硬件組件眾所周知且易于理解。一目了然,驅動器的“內臟”由圓形鐵質盤片組成,數據被寫入和讀取。在盤片的中心是主軸,主軸由主軸電機驅動,主軸電機旋轉讀寫臂下方的盤片。浮動在板上方,包含微小讀寫頭的讀寫臂由致動器控制,致動器將臂移動到盤片的表面上。從驅動器“讀取”的數據從盤片,通過臂,通過柔性帶狀連接器傳播到印刷電路板(PCB)。
PCB是驅動器主控制器的所在地,通常連接到HDD外殼的外殼,使其非常容易接近。主控制器實現計算機SATA總線和盤頭之間的位置轉換和傳輸協議。它還通過控制前面提到的驅動子系統來提供整體磁盤功能。上電時,主控制器從其內部非易失性存儲器或外部存儲器芯片執行固件。在磁盤初始化過程期間,控制器還可以從HDD的盤片上的服務位置讀取附加代碼 - 傳統方法無法訪問的位置。HDD所做的所有重要且有趣的,可能未記錄的內容都被編程到主控制器固件中。
分散在Web上的大多數信息與修復或更換故障HDD的控制器板有關。很少提及固件重新刷新或檢索。通過ATA接口排除專有更新文件格式和模糊的更新協議,該過程可歸結為從外部存儲器芯片讀取固件或掛接JTAG接口并操縱主HDD控制器以通過JTAG端口移位其存儲器數據(有用)如果固件位于微控制器內部的非易失性存儲器中)。關于它的棘手問題在于,盡管大多數主控制器都是由著名的芯片制造商(如ST,LSI,三星和Marvell)制造,但要說HDD微控制器的數據表不容易采購將是輕描淡寫的。
在任何情況下,缺少適當的文檔都很難確定JTAG接口引腳。有許多技術可以讓人們根據PCB的布局或標記來推斷這些引腳的功能(即引腳排列),但這是一個艱苦的過程,可能導致電路板本身的破壞?纯唇DD控制器低級接口的其他可能方法,似乎有些硬盤板有許多專用于某種服務串口的引腳。引腳數量及其確切功能取決于制造商,但是當我開始調查時,它似乎是在芯片內部進行對等的最簡單方法。
作為一個實驗,我決定連接硬盤串行鏈接,看看我是否可以從中獲得任何有用的東西。我有一個相當古老的硬盤驅動器,可用于實驗。從圖1中可以看出,其控制器板上有許多熟悉的連接器,例如用于SATA電源和SATA數據的連接器,但也有一個跳線塊。兩個跳線塊引腳用于配置驅動器的帶寬。其中一個引腳接地(GND),另外兩個很可能是我們正在尋找的 - 串行發送和接收(Tx和Rx)接口。
圖1帶控制器板的HDD磁盤模塊
仔細觀察PCB確認了我們的觀察結果:標記為T1的跡線之一需要短接到相鄰接地以實現不同的HDD帶寬。到目前為止,剩下的最右邊的針腳沒有記錄。
圖2控制器板的組件側
查看電路板的組件(圖2)和底層(圖3),確認引腳已連接并布線在主控制器芯片下的某處。
圖3控制器板的底部
因此,我們假設Tx,Rx和接地(GND)引腳輸出并將控制器連接到串行終端程序。為此,我們需要一個電壓電平(3.3v)和協議轉換器(RS232到USB)。有很多選擇要做,所有這些都同樣有效。我有一個基于FTDI FT232RL的電路板,所以我用它作為PC和HDD控制器板之間的橋梁。我還制作了一個簡易連接器,用于將HDD串口連接到FTDI板; 最后的整個設置如圖4所示。
圖4簡易連接器和連接到HDD控制器板的USB轉COM接口板
將FTDI板連接到PC并安裝FTDI驅動程序后,它將充當COM端口,并可通過任何串行終端程序以編程方式連接。我使用了Termite,因為它很簡單并且可以在便攜模式下運行(也就是說,它不必安裝)。由于我對放在盤片上的信息不感興趣,為了方便我將它們從硬盤盒中拆卸下來。
第一次嘗試將所有接線連接起來并將電源連接到控制器板都沒有產生任何結果。有很多事情可能會出錯。這些可能包括損壞的控制器板本身,電源不足或串行連接錯誤......但大多數情況下問題是板上或控制器上的Tx和Rx線交換。FTDI板的Tx 必須連接到HDD控制器的Rx,反之亦然。有時即使引腳被標記,它們也會在預期另一個終點時被標記,因此標簽并不總是反映標記線上信號的真實性質。在硬盤驅動器控制器板上電時,在終端上交換了這個:
圖5以57600 bps連接的終端程序
傳輸似乎是亂碼,雖然它在電源周期上足夠重復,以假設它應該有一些意義。傳輸不可讀的原因有多種。它可能是原始二進制數據,但也有許多事情我們可能會嘗試確認為其他潛在問題。首先是RS232協議設置。我們進行操作時應該擔心的最重要的參數是波特率,數據位數,停止位數,奇偶校驗和流量控制,我已在圖6中指出。
圖6終端程序連接設置
假設我們獲得一致的信息,即使數據,停止,奇偶校驗和流量控制按照它們應該的方式設置,也是有點安全的。但情況并非總是如此,如果使用波特率播放不會導致任何結果,我們需要重新審視這些參數。
所以我將波特率更改為115200.結果如圖7所示。
圖7以115200 bps連接的終端程序
我完全失去了信息。這意味著完全失去同步,并表明我們的操作方式超出了預期的協議波特率?雌饋砦倚枰暂^慢的速度來看它是否有任何區別。實際上,最初將波特率降至38400,然后降至14400,逐漸增加了接收數據的復雜性,如圖8所示。
圖8以14400 bps連接的終端程序
最后,在9600 bps時有8位數據,1個停止位,沒有奇偶校驗,我收到了確認讀取,如圖9所示。
圖9以9600 bps連接的終端程序
我得到了提示!我正在連接HDD控制器內的終端程序。當然沒有手冊或幫助打印的暗示,所以為了獲得一系列可接受的命令,我開始采用傳統的“試錯法”方式。我很快就發現大多數時候命令都只包含一個字母和一些參數。例如,a被拒絕,而另一方面b將在沒有給出任何結果的情況下解析:
圖10 HDD終端的F級別
它促使我認為它可能需要b的一些參數。當然b0和b1緊隨其后:
圖11 b1命令的輸出
這表明b1產生了一些信息,而其他命令可能未實現或需要更多參數?匆幌耣1返回的數字列表,它們似乎非常熟悉。實際上,如果我們查看COM接口的標準速度值 - 9600,19200,38400,57600,115200等 - 值得注意的是,最高有效數字與b1給出的列表中的數字相似。是否有可能b命令以某種方式操縱HDD終端程序的串行通信速度?如何通過論證?它是由列表中的索引嗎?我嘗試了b2,它沒有給我任何通信速度的變化。我試過b0115它放棄了連接。我將終端程序的速度更改為115200并嘗試再次連接。連接成功,我能夠以更高的速率與HDD終端程序通信,如圖11(上圖)所示。那很整潔!
繼續以類似的方式,我設法發現了一些其他已接受的命令字符,我在下面的圖12中列出了這些字符。
圖12 F級可能的HDD終端命令列表
我在終端程序的F級找到的最有趣的命令是b,d,+, -和=。它們似乎與內存操作例程有關。例如,b和d列出了內存塊。兩個命令都接受參數; 例如,b按200h大小塊列出內存,參數反映塊編號,因此b2將給出0x400到0x600范圍內的內存塊。另一方面,命令d的形式為d <最高有效地址字節> <低地址字>。值得注意的是,這些命令指的是同一地址的不同存儲塊,如圖13所示。
圖13 b和d命令顯示的內存塊
+“, -和=似乎與字節和字地址操作有關。例如,以下命令顯示指定位置的內存。
圖14使用+, -和=命令進行內存操作
存儲器也可能被改變。這需要更多的研究; 到目前為止,我還沒有設法在命令字符串的參數部分找到一個分隔符,它允許我指定要寫入的數據?焖贋g覽一下串行接口,可以看出有多種方法可以訪問硬盤驅動器控制器的內存以及(很可能)更改它。界面也非常不方便和簡陋; 它可以自動進行數據提取,例如使用Python及其串行接口庫。該b命令呈現的格式如下信息:
圖15 b命令的控制臺輸出
使用Python和PySerial我試圖提取并將此內存表示轉換為二進制文件。在這個過程中,有一些事情需要考慮。首先,我們需要通過COM接口初始化并與控制器板建立連接,如圖16所示。
圖16 Python中的串行端口初始化示例
請注意,端口變量需要設置為特定于電路板所連接系統的COM端口。就我而言,它是COM14。
建立連接后,我們需要發出b命令并從板的內存中提取格式化信息,如圖17所示。
圖17 Python中的串行端口通信示例
輸入變量首先設置為b,然后后續讀取只返回回車符\ r。在循環中處理數據的提取。一旦讀數結束,'out'變量將填充來自電路板內存的格式化信息。為了使它有用,我們需要解析并將其轉換為二進制文件。
圖18終端程序的b命令輸出的部分
看圖18,這意味著擺脫'Addr'標題(區域'A')和實際地址(區域'B'),連接數據(區域'C'),將其從ASCII十六進制轉換為原始二進制表示,并最終將其寫入文件。這可以通過Python中的幾行代碼以及它的正則表達式庫的幫助來實現。幸運的是,數據塊的格式與地址和地址頭不同,可以通過正則表達式進行過濾,例如[0-9A-F] {8}。正則表達式獲取一個8位十六進制數字并忽略所有其余數字。圖19中顯示的Python代碼枚舉了數據塊中8位十六進制數的所有實例,并將它們存儲在raw_bytes_concat變量中。
圖19 Python中固件十六進制代碼的正則表達式過濾器
使用binascii庫處理轉換,如圖20所示。
圖20 Python中的ASCII十六進制到二進制轉換
轉換數據后,它將寫入hexfile2.bin文件。一目了然,提取的文件包含一些有趣的字符串,例如:
“SFlash Unsupported”,“BootAdaptives”,“RsvTrackDefLst”,“AppCode”,“Chksum Err”,“無效地址”,“未知扇區”,“無效條目”,“SysSecErr代碼”,“前置放大器ID”,“NIGHTHAWKPLUS” ,'旋轉不穩定','旋轉恢復','Parm Range Err','命令無效 - 未檢測到有效證書代碼','命令被拒絕'
使用ARMB處理器選擇在IDA下加載二進制文件為我們提供了可讀的代碼塊,如圖21所示。
圖21 IDA中反匯編的ARMB(Big Endian)代碼(單擊在新窗口中打開)
看起來我們可能已經觸及了負責終端程序級別F的磁盤嵌入式代碼部分。此代碼還將其余固件從串行閃存復制到RAM并執行它。來自串行閃存ROM的初始固件代碼繼續從HDD上的預定義扇區加載固件。所有這些序列和位置都特定于串行閃存和磁盤本身的固件版本。
要更全面地了解HDD固件,必須在控制器和連接的盤片模塊進行分析。