到目前為止,我需要有人來檢查我的手動 NTFS 恢復過程,因為它讓我陷入了困境。
背景:
- 我有一個 1TB NTFS 外部硬碟(WD Elements),其中主要包含照片。
- 不知何故,它已損壞並在 Windows 上顯示為原始磁碟。
- 它出現在 Linux 系統上的
/dev/disk/by-path
(和by-id
等by-uuid
)目錄中,並顯示為/dev/sdb
。 - EaseUS 能夠透過快速掃描(而不是繁重的深度掃描)找到(幾乎?)我的所有照片。
- EaseUS 找到大約 70GB 的檔案(主要是照片)。
- 我認為 NTFS 記錄已損壞,即這不是機械故障。
- 我想嘗試自己康復以獲取樂趣和利潤。
- 我沒有足夠大的另一個驅動器來製作損壞驅動器的完整映像。
我需要解析 NTFS MFT $File 記錄,因為:
- 我想恢復原始檔名和目錄結構。
- 如果圖像未寫入連續的集群中,我將無法僅通過查找圖像文件簽名來成功恢復它。
計劃是:
- 對損壞磁碟的一部分進行映像。
- 解析它以識別並讀取 MFT $File 記錄。
- 使用 $File 記錄(特別是其 $Data 屬性)來確定每個檔案的資料運行。
- 知道檔案的資料運行後,我可以從使用建立的圖像中挑選出檔案的位元組
ddrescue
。 - 沖洗並重複,直到完成。
首先——這聽起來是個合理的計畫嗎?
我做了什麼:
- 找一堆$File記錄
- 解析一個以取得資料運行
- 在資料運行指定的位置讀取原始位元組。
具體來說:
- 用於
ddrescue
對損壞磁碟的 100GB(從 0 開始)進行映像。- 我想幾乎所有我需要的實際數據都寫入前 100GB 內,因為感興趣的數據總量為 70GB。如有必要,我可以在後續 100GB 部分中重複整個過程。
- 我用來鏡像前 100GB 的指令是
ddrescue /dev/sdb ~/mydisk.img ~/mydisk.map --size=100G
. ddrescue
確實遇到了 I/O 錯誤,報告僅恢復了 99.57% 左右。- 映像的開頭(前 20MB 左右)似乎是空的,因此這可能是磁碟機故障的原因。我暫時忽略它。
- 讀取 100GB 映像並找到 ASCII 字串「FILE」的所有實例,該字串表示 MFT 中 $File 記錄的開頭。
- 這也會觸發誤報,例如任意檔案中間的“PROFILE”一詞。
- 因此,我只考慮「FILE」的一次出現與下一次出現之間的距離 <= 1024 位元組的結果,因為這是最大的 MFT 記錄大小。如果「FILE」的一次出現與下次出現之間有 3MB,那麼它不太可能是 $File 記錄。
- 迭代假定的 $File 記錄(大小 <= 1024 位元組)和提取的 $Data 屬性。
- 解析它的資料運行(忽略關於居民與非居民屬性的討論,我認為我理解,但不是我的問題的一部分)。
因此,我經歷了上述過程並選擇了 $File 記錄之一併識別了其數據運行。這是 $Data 屬性(標題和內容):
80 00 00 00 48 00 00 00 01 00 00 00 00 00 01 00
00 00 00 00 00 00 00 00 FA 03 00 00 00 00 00 00
40 00 00 00 00 00 00 00 00 B0 3F 00 00 00 00 00
F4 AC 3F 00 00 00 00 00 F4 AC 3F 00 00 00 00 00
32 FB 03 ED C8 11 00 00 FF FF FF FF 82 79 47 11
資料運行詳細資訊是最後一行的前半部分,就在FF FF FF FF
屬性標記末尾之前:
- 長度位元組:
32
- 集群運行數:
FB 03
(little endian) = 運行中的 1019 個集群 - 簇起始編號:
ED C8 11
= 1165549 是運行的第一個簇 - 下一個
00
表示不再運作。
現在,考慮到每個磁區有 512 個位元組,每個簇有 128 個磁區,我從 (1165549 * 128 * 512) 開始的 100GB 映像中讀取 (1019 * 128 * 512) 位元組。
不幸的是,這給我留下了一個 66.8MB 的文件,其中大部分是 0x00,儘管最後還有一些數據。我很確定我出了什麼問題,我只是偶然發現了一些資料(儘管我確實以 JPG 檔案結束標記 (DD F9) 結尾。
我完成整個任務的方法合理嗎?
或者我誤解了 NTFS 的一些基本知識,這是完全錯誤的想法?
答案1
首先——這聽起來是個合理的計畫嗎?
不,我的意思是我沒有深入研究解碼運行的方法,但是,啟動簇與檔案系統的啟動相關(= 當我們談論 NTFS 時,磁碟區/分區的啟動)。因此,任何指向群集號的 MFT 條目都指向相對於分割區開頭的群集號,而不是相對於磁碟區的任意 100 MB 部分。
此外,MFT 是“自引用”,因此首先要嘗試的是找到 MFT 的開頭,然後可以從中匯出全部MFT 條目。如果找不到 MFT 的開始,請嘗試尋找 MFT 的鏡像。
因此,要正確解碼 MFT 條目並獲取它引用的數據,我們需要:
- 到分區開始的偏移量。
- 正確的簇大小
因此,如果我們解碼起始簇,我們可以這樣做:(簇號*扇區/簇)+偏移分區
您如何確定每個簇有 128 個磁區?這看起來根本不對!請參閱此處的預設值:https://www.disktuna.com/default-cluster-sizes-for-fat-exfat-and-ntfs/。
答案2
將損壞的光碟暴露在您所描述的讀取負載下是不專業的。第一個要求是將該驅動器複製到穩定、健康的驅動器,以避免丟失額外的扇區,並且不再有不可讀的扇區。無法複製不可讀磁區的事實令人悲傷,但關鍵是避免您或恢復程式處理讀取錯誤。
您的恢復嘗試很可能已經對該驅動器造成了額外的損壞。
由於元資料結構和資料不一定以線性方式佈局,因此您無法透過隨後將某處的 100GB 切片讀取到其他地方的可用磁碟機儲存來彌補擁有至少一個足夠大的磁碟機的不足。您需要隨機存取。不幸的是,在您的情況下,一旦結構指向您的下一個 100GB 切片,您就必須清空您的 100GB 儲存區域。
如果您已經用您喜歡的程式語言解析結構,則無需執行 dd 等 unix 命令來執行複製作業。在復原嘗試開始時僅需要一次 ddrescue。
如果您只是想了解 NTFS 的內部結構,那很好,而且很酷,但您可以在 USB 等儲存裝置上學習。不需要大驅動器。
請考慮一下 Easeus 沒有恢復您想要的元資料(例如檔案名稱和資料夾結構)的原因。
答案3
我認為驅動器是線性的,從簇 0 的扇區 0 的位元組 0 開始,一直到實體驅動器的末端。
是和不是。儲存位址是線性的,從位元組 0 開始。
簇位址是線性的,從簇號零開始,但僅相對於它們各自的分區。沒有磁碟範圍的叢集標記,只有從零開始的分割區範圍的叢集標記。
您是說,如果我使用 ddrescue 這樣的工具讀取位元組 0 - 1000000,我不應該期望讀取描述佈局的 NTFS 元資料?
NTFS元資料不僅涉及開機磁區,還涉及主文件表和其他文件。當從磁碟機開頭讀取 1 MB 時,您將只讀取主檔案表的一小部分(前提是它位於此處)。它的位置不是固定的,並且可能會在碎片整理時發生變化。
使用該策略來試驗並了解您的檔案系統: https://forum.cgsecurity.org/phpBB3/viewtopic.php?p=31304#p31304
當嘗試解密 NTFS 時,您可以更了解預期的結果。這是一種解密過程,就像“已知明文攻擊”,你知道整個明文。
有人剛剛對我的答案投了反對票。如果是你,請解釋原因。有什麼地方有錯誤嗎?我想知道!謝謝。