1. 程式人生 > >淺談資料恢復原理

淺談資料恢復原理

資料恢復是一門比較有用的技術,尤其是當硬碟、U盤、手機儲存卡等發生資料丟失時,如何找回丟失的檔案和資料則成為最關鍵的問題。能否找回資料不僅和儲存介質有關,而且和作業系統以及介質所在的檔案系統有很大的關係,基本上,分割槽表及檔案系統(File System,簡稱FS)是決定資料能否找回的關鍵,因為它決定了資料儲存的邏輯結構,一旦FS被破壞,即便物理上資料依然存在,可因為資料已經失去完整性和連續性,所以找回資料就變得相當困難。分割槽表則是決定整個磁碟的佈局,從分割槽表可以得知分割槽數量、主/擴充套件分割槽及邏輯分割槽的位置與大小等,所以分割槽表丟失對資料的破壞也是異常嚴重的。本文僅談論檔案系統的結構。

    Windows上常見的檔案系統有FAT16/32,NTFS,exFAT等,FAT目前基本只有U盤上使用,硬碟上一般都用NTFS,因為FAT32下單個檔案最大不能超4G而且檔案資訊有限,NTFS則不受這個限制,而且加入了安全描述符(Security Descriptor),也就是我們可以為檔案或目錄設定不同的許可權。但是FAT32在U盤下有時還是很方便,當然也可以格式化成NTFS,不過格成NTFS會遇到一種特殊的情況,比如到了某臺不受你控制的電腦,你可能因為當前許可權原因而無法刪除U盤上的檔案,問題就變得麻煩了。除此之外,也可格成exFAT,exFAT介於FAT和NTFS兩者之間,exFAT下檔案大小可以超過4G,所以比FAT32好用。雖然FAT32和NTFS的儲存資料方式不同,但某些原理還是相似的,所以,瞭解了FAT,也就更容易瞭解NTFS。下面以FAT32為例簡單談一下如何實現FAT下資料的讀取和恢復。

    FAT12/16由DBR(保留區)、FAT表、根目錄和資料區組成,FAT32則沒有根目錄,根目錄位於資料區和檔案放在一起。目錄(Directory)和資料夾是一樣的東西,只是不同的叫法,以下統稱目錄。DBR扇區中記錄了分割槽基本資訊,如每扇區位元組數、每簇扇區數、保留扇區數等等。DBR開頭三個位元組是彙編指令,類似於EB XX XX,意思是跳轉到引導程式碼處。如果將首位元組0xEB改成其它數字比如00,分割槽便無法訪問,雙擊分割槽會提示未格式化什麼的,不過這只是當前電腦的作業系統不識別,如果把U盤或TF卡放到其它系統中去,比如放到隨身播放器中還是能夠聽音樂的,因為播放器系統不一定會檢查這個位元組的合法性。下面說一下簇,簇是檔案系統的儲存單位,由若干扇區組成,一個檔案若存放了一個簇的前半部分,那簇的後半部分就不能再存放其它檔案,也就是說,一個簇不能同時存兩個檔案。比如假設一個簇大小是8192位元組,有個檔案大小是1位元組,那麼它會佔據某個簇的第1個位元組,實際上它所佔的空間是8192位元組,剩餘8191位元組就被浪費了,所以理論上簇是越小越好,但也不能太小,否則定址不方便。下面看FAT表的結構,FAT表中,每4個位元組也就是32位為一項,每一項中記錄著簇的編號,前兩項不記錄簇號,第三項在偏移0x8處,為第一個簇,也就是2號簇,後面是3號,依次編號,每個FAT項的內容是下一個簇的編號。如果內容是FF FF FF 0F,則說明該簇沒有下一下關聯的簇,是獨立簇,獨立簇存放的是不超過一個簇大小的檔案內容,就這樣,每個簇都指向下一個簇,如此不停地跳來跳去,最終就能找到一個檔案的所有內容,當跳到FF FF FF 0F,說明這是檔案內容的最後一個簇。檔案內容的位置在FAT表中記錄,那檔案的名字和大小等資訊儲存在哪裡呢?檔案的大小等資訊其實是另一個目錄的內容。根目錄中首先儲存著根目錄下所有檔案和目錄(以下不說明,檔案將包括目錄,目錄也是檔案)的資訊,每一項資訊大小是32個位元組,其中有檔案短名、長名、刪除標記、屬性、建立時間、大小、起始簇號等資訊,一項資訊開頭為0,說明已經到頭了,系統會認為下面沒有子目錄和檔案了,表示已經搜尋完該目錄內的所有檔案。如果將根目錄中第一個位元組改為0,那該分割槽下就成了空白,將看不到任何檔案,其實這不完全等於隱藏,因為如果系統再建立檔案時會尋找目錄項開頭為0的項,然後替換它。如果一目錄項是檔案(通過屬性判斷),項中儲存著檔案內容所在的第一個簇,如果是目錄,則項中儲存著目錄的內容,目錄的內容正是目錄內檔案和子目錄資訊,這些資訊又是一系列目錄項,甚至佔多個簇(如果目錄內檔案過多),這樣一層一層就能遍歷目錄內所有檔案。

    建立檔案時,首先在FAT中為該檔案分配簇,0大小檔案不分配。然後在根目錄一層層找到它的父目錄,然後在父目錄中為它分配目錄項,記錄檔案起始簇、檔案時間等資訊。如果檔名超過8.3或名字含有特殊字元或中文,就為它建立長檔名目錄項,短名按一定規則重新命名。刪除檔案時,一是清除檔案FAT表中的簇號,將簇標記為沒有使用,以便讓給其它檔案,二是目錄項開頭位元組被改成0xE5,表示已刪除,整個過程檔案內容沒有做任何改變。若只改刪除標記檔案也會消失,但簇未釋放,檔案暫時被隱藏,但不代表系統以後不會清理它,模擬這個過程我們可以實現強刪任意檔案,不管它是否有保護或正在執行。一個檔案被刪除,目錄項並沒有被立即清空,裡面仍記錄著檔案內容的首簇,所以我們能找到檔案內容開始一少部分位元組,假設1個簇大小為8192位元組,如果檔案大小小於1個簇,比如512位元組,那麼只要簇沒有被立即佔用,我們就能完全恢復該檔案,如果檔案為16384位元組,就要佔兩個簇,第一個簇讀完,這時我們到FAT中檢視該簇記錄的下一個簇,因為檔案被刪,檔案所有簇被清空,改為00 00 00 00,所以就不能再繼續讀取了,恢復就變得困難多了,至少不能按常規方法恢復,除非檔案是連續儲存的,這樣我們按簇順序讀取,就能把它恢復。因而,在FAT下恢復檔案具有一定概率。用過資料恢復軟體的人可能會遇到這種情況,有時已經看到一個檔案的名字,恢復出來卻是亂碼,出現這種情況正是前面說的原因。其實,看到0還不算可怕,如果看到非0,那才悲劇,說明已經被另一個檔案替換了,這樣就連首簇內容也無法恢復了。從可恢復性上看,NTFS和FAT32就不同,NTFS下如果檔案簇沒有被覆蓋,理論上檔案百分之百可以被恢復,或者說,相對而言NTFS檔案系統可恢復性更高。下面說隱藏。FAT32下能否簡單隱藏一個檔案呢?要隱藏一個檔案,可以通過改屬性標誌實現,但不是改變我們通常所說的Hidden(隱藏)屬性,而是指改卷標屬性。設定普通的隱藏屬性後,檔案還會在資源管理器中看到,但設定了卷標屬性,檔案無法再通過檔案管理器看到,不過一旦改了驅動器卷標名,檔案目錄項會丟失,所以最好只對目錄進行隱藏。可以將一個目錄增加捲標屬性,它就看不到了,從而實現了底層隱藏,就連防毒軟體也檢測不到它的存在。事實上真有這麼強大嗎?事實上確實是這樣,因為就連作業系統或許都已經檢測不到它了,因為你破壞了它的結構。檔案是邏輯上的東西,改了關鍵位元組,檔案的邏輯結構會發生改變,換句話說,作業系統已經不認為它是一個有效的檔案了,它只是磁碟上的一堆資料。其實對於物理磁碟而言,並不存在什麼檔案,只存在資料0和1,硬碟也根本不知道什麼叫檔案,就像CPU不知道什麼是作業系統一樣,它只關心暫存器指令。經過測試,通過這種方法將目錄隱藏後改卷標名並不影響目錄本身,取消屬性後仍然能看到該目錄及其下面的所有檔案,不過卷標屬性是隻讀的,不能通過SetFileAttributes函式更改,所以只能用DDM(Direct Disk Manipulation,意為“直接磁碟操作”,即直接操作磁碟來訪問檔案)技術實現。那能不能禁止檔案被複制和訪問呢?辦法是有的,還是改屬性,將屬性第6bit設為1,它就不能被執行和複製了,任何對該檔案或目錄的訪問都會提示“拒絕訪問”,有人順便會把第7bit也就是最後1位也設為1,這個其實沒有必要,7bit其實是Normal(標準)屬性,值為0x80,就是不含其它屬性的屬性,FAT中值儲存為0,兩者一樣,只是在設定屬性時加以區分。目前為止,FAT下檔案的遍歷、隱藏、保護和刪除都已講完,瞭解更多請上網。具體實現方法及程式碼請參考《自己動手寫資料恢復軟體》一文。