前面在看 NTFS 時,已經碰過 Data Run,不過當時主要是知道它可以指出 File Data 所在的位置。
這篇來看 Run List 裡的 Length 和 Offset 要怎麼讀,並算出每個 Run 的 LCN 和 Byte Offset。
範例 Run List:
22 20 01 C0 5C 22 EA 00 A9 C1 22 B0 00 50 F8 00
看起來只是一串 Hex,但實際上裡面記錄了三個 Run:
Run 1:22 20 01 C0 5C
Run 2:22 EA 00 A9 C1
Run 3:22 B0 00 50 F8
00:Run List 結束
每一個 Run 的第一個 Byte 都是 Header。這個例子三個 Run 都是:22
Header 要拆成左右兩個 Nibble:
2 | 2
左邊的 2 表示 Offset 使用 2 Bytes,右邊的 2 表示 Length 使用 2 Bytes。
所以只要看到:
22 XX XX XX XX
就可以拆成:
22 Header
XX XX Length
XX XX Offset
也就是先讀 2 Bytes 的 Length,再讀 2 Bytes 的 Offset。
Run 1 是:
22 20 01 C0 5C
按照剛剛的規則拆開:
22 Header
20 01 Length
C0 5C Offset
先看 Length 20 01,因為是 Little-endian,所以反過來讀,得到 Run 1 的 Length 是 288 Clusters。
20 01
→ 01 20
→ 0x0120
→ 288
接著看 C0 5C:
C0 5C
→ 5C C0
→ 0x5CC0
→ 23,744
第一個 Run 前面沒有其他 Run,因此這裡得到的 23,744 就是 Run 1 的起始 LCN。
這個範例中,一個 Cluster 是:
512 Bytes / Sector × 8 Sectors / Cluster
= 4,096 Bytes
因此算出 LCN 之後,就可以用 Byte Offset = LCN × Cluster Size 找到這段資料在 Image 裡的位置。
Byte Offset:
23,744 × 4,096
= 97,255,424
目前可以得到:
| Run | Length | Relative Offset | LCN | Byte Offset |
|---|---|---|---|---|
| Run 1 | 288 Clusters | Start | 23,744 | 97,255,424 |
接著看 Run 2:
22 EA 00 A9 C1
同樣先拆開:
22 Header
EA 00 Length
A9 C1 Relative Offset
Length:
EA 00
→ 00 EA
→ 0x00EA
→ 234
得到 Run 2 的 Length 是 234 Clusters。
從第二個 Run 開始,A9 C1 並不是直接告訴我們 Run 2 的 LCN,而是告訴我們 Run 2 的起點和 Run 1 的起點相差多少個 Cluster。
先把 A9 C1 反過來:
A9 C1
→ C1 A9
→ 0xC1A9
如果直接把 0xC1A9 轉成十進位,會得到 49,577。
但 Relative Offset 是 Signed Value,所以要先判斷它是正數還是負數。如果最高位元是 0代表正數;如果最高位元是 1代表負數。如果是負數,就要再減去 65,536。
0xC1A9 的最高位元為 1,所以不能直接當成 +49,577,而要換成對應的負值:
49,577 - 65,536
= -15,959
Run 2 的 Relative Offset 是 -15,959,代表它的起點要從 Run 1 的 LCN 23,744 往前移 15,959 個 Cluster:
23,744 + (-15,959)
= 7,785
所以 Run 2 的起始 LCN 是 7,785。
再換成 Byte Offset:
7,785 × 4,096
= 31,887,360
目前可以先整理成:
| Run | Length | Relative Offset | LCN | Byte Offset |
|---|---|---|---|---|
| Run 1 | 288 Clusters | Start | 23,744 | 97,255,424 |
| Run 2 | 234 Clusters | -15,959 | 7,785 | 31,887,360 |
最後看 Run 3:
22 B0 00 50 F8
先算 Length:
B0 00
→ 00 B0
→ 0x00B0
→ 176
接著算 Relative Offset:
50 F8
→ F8 50
→ 0xF850
→ 63,568
0xF850 的最高位元同樣是 1,因此也是負數:
63,568 - 65,536
= -1,968
這次要注意,Run 3 是拿前一個 Run,也就是 Run 2 的 LCN 來算。
Run 2 的 LCN 是 7,785,因此:
7,785 + (-1,968)
= 5,817
所以 Run 3 的 LCN 是 5,817。
再換成 Byte Offset:
5,817 × 4,096
= 23,826,432
最後三個 Run 的結果如下:
| Run | Length | Relative Offset | LCN | Byte Offset |
|---|---|---|---|---|
| Run 1 | 288 Clusters | Start | 23,744 | 97,255,424 |
| Run 2 | 234 Clusters | -15,959 | 7,785 | 31,887,360 |
| Run 3 | 176 Clusters | -1,968 | 5,817 | 23,826,432 |
最後的 00 則是代表 Run List 到這裡結束。
