[Forensic] File System

Updated:

File System

MBR & VBR

HxD를 통해 MBR와 VBR의 구조를 살펴보자. 도구 -> 디스크 열기를 통해 조사할 물리 디스크를 선택한다.

Offset(h)   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

0000000000  33 C0 8E D0 BC 00 7C 8E C0 8E D8 BE 00 7C BF 00  3ÀŽÐ¼.|ŽÀŽØ¾.|¿.
0000000010  06 B9 00 02 FC F3 A4 50 68 1C 06 CB FB B9 04 00  .¹..üó¤Ph..Ëû¹..
0000000020  BD BE 07 80 7E 00 00 7C 0B 0F 85 0E 01 83 C5 10  ½¾.€~..|..…..ƒÅ.
0000000030  E2 F1 CD 18 88 56 00 55 C6 46 11 05 C6 46 10 00  âñÍ.ˆV.UÆF..ÆF..
0000000040  B4 41 BB AA 55 CD 13 5D 72 0F 81 FB 55 AA 75 09  ´A»ªUÍ.]r..ûUªu.
0000000050  F7 C1 01 00 74 03 FE 46 10 66 60 80 7E 10 00 74  ÷Á..t.þF.f`€~..t
0000000060  26 66 68 00 00 00 00 66 FF 76 08 68 00 00 68 00  &fh....fÿv.h..h.
0000000070  7C 68 01 00 68 10 00 B4 42 8A 56 00 8B F4 CD 13  |h..h..´BŠV.‹ôÍ.
0000000080  9F 83 C4 10 9E EB 14 B8 01 02 BB 00 7C 8A 56 00  ŸƒÄ.žë.¸..».|ŠV.
0000000090  8A 76 01 8A 4E 02 8A 6E 03 CD 13 66 61 73 1C FE  Šv.ŠN.Šn.Í.fas.þ
00000000A0  4E 11 75 0C 80 7E 00 80 0F 84 8A 00 B2 80 EB 84  N.u.€~.€.„Š.²€ë„
00000000B0  55 32 E4 8A 56 00 CD 13 5D EB 9E 81 3E FE 7D 55  U2äŠV.Í.]ëž.>þ}U
00000000C0  AA 75 6E FF 76 00 E8 8D 00 75 17 FA B0 D1 E6 64  ªunÿv.è..u.ú°Ñæd
00000000D0  E8 83 00 B0 DF E6 60 E8 7C 00 B0 FF E6 64 E8 75  èƒ.°ßæ`è|.°ÿædèu
00000000E0  00 FB B8 00 BB CD 1A 66 23 C0 75 3B 66 81 FB 54  .û¸.»Í.f#Àu;f.ûT
00000000F0  43 50 41 75 32 81 F9 02 01 72 2C 66 68 07 BB 00  CPAu2.ù..r,fh.».
0000000100  00 66 68 00 02 00 00 66 68 08 00 00 00 66 53 66  .fh....fh....fSf
0000000110  53 66 55 66 68 00 00 00 00 66 68 00 7C 00 00 66  SfUfh....fh.|..f
0000000120  61 68 00 00 07 CD 1A 5A 32 F6 EA 00 7C 00 00 CD  ah...Í.Z2öê.|..Í
0000000130  18 A0 B7 07 EB 08 A0 B6 07 EB 03 A0 B5 07 32 E4  . ·.ë. ¶.ë. µ.2ä
0000000140  05 00 07 8B F0 AC 3C 00 74 09 BB 07 00 B4 0E CD  ...‹ð¬<.t.»..´.Í
0000000150  10 EB F2 F4 EB FD 2B C9 E4 64 EB 00 24 02 E0 F8  .ëòôëý+Éädë.$.àø
0000000160  24 02 C3 49 6E 76 61 6C 69 64 20 70 61 72 74 69  $.ÃInvalid parti
0000000170  74 69 6F 6E 20 74 61 62 6C 65 00 45 72 72 6F 72  tion table.Error
0000000180  20 6C 6F 61 64 69 6E 67 20 6F 70 65 72 61 74 69   loading operati
0000000190  6E 67 20 73 79 73 74 65 6D 00 4D 69 73 73 69 6E  ng system.Missin
00000001A0  67 20 6F 70 65 72 61 74 69 6E 67 20 73 79 73 74  g operating syst
00000001B0  65 6D 00 00 00 63 7B 9A EB E3 EB E3 00 00 80 20  em...c{šëãëã..€ 
00000001C0  21 00 07 FE FF FF 00 08 00 00 00 00 6A 18 00 FE  !..þÿÿ......j..þ
00000001D0  FF FF 07 FE FF FF 00 08 6A 18 00 50 06 5C 00 00  ÿÿ.þÿÿ..j..P.\..
00000001E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000001F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA  ..............Uª

섹터 0을 보면 위와 같다. 오프셋 기준 0x0 ~ 0x1BD까지가 부트 코드, 0x1BE ~ 0x1FD에는 파티션 테이블, 마지막 2byte에는 0x55 0xAA로 시그니처 값이 있다.

  1. Boot Code (0x0 ~ 0x1BD)
  2. Partition Table Entry#1 (0x1BE ~ 0x1CD)
  3. Partition Table Entry#2 (0x1CE ~ 0x1DD)
  4. Partition Table Entry#3 (0x1DE ~ 0x1ED)
  5. Partition Table Entry#4 (0x1EE ~ 0x1FD)
  6. Signature (0x1FE ~ 0x1FF)

각각의 파티션 테이블 엔트리는 16바이트이며, 하나의 엔트리는 6가지 항목으로 나누어져 있다.

  1. Boot Flag (0x00 ~ 0x00): 0x00(cannot boot), 0x80(bootable)
  2. Starting CHS Address (0x01 ~ 0x03)
  3. Partition Type(0x04 ~ 0x04): 0x07=NTFS, 0x83=Linux ext…
  4. Ending CHS Address(0x05 ~ 0x07)
  5. Starting LBA (0x08 ~ 0x0B)
  6. Number of Sectors in Partition(0x0C ~ 0x0F)

CHS 주소는 Cylinder-Head-Sector 방식의 주소로 요즘에는 거의 사용하지 않는다. LBA는 해당 파티션이 시작하는 섹터를 LBA 주소 기준으로 알려준다. LBA 방식은 저장장치 내 모든 섹터들에 대해 순서대로 숫자를 지정해 주소를 계산하는 방식으로 일반적으로 사용하는 주소 지정 방식이다.

Partition Table Entry#1을 기준으로 해석해보면 다음과 같다.

80 20 21 00 07 FE FF FF 00 08 00 00 00 00 6A 18

  1. Boot Code 0x80: 부팅 가능
  2. Starting CHS Address 0x002120
  3. Partition Type 0x07: NTFS
  4. Ending CHS Address 0xFFFFFE
  5. Starting LBA 0x00000800
  6. Number of Sectors in Partition 0x186A0000

Starting LBA가 0x00000800 섹터이다. 섹터는 512바이트(0x200)이므로 오프셋을 계산해보면 0x800 * 0x200 = 0x100000이다. 해당 오프셋을 조사해보면 2048(0x800) 섹터에 해당 파티션의 VBR이 위치하는 것을 확인할 수 있다.

Offset(h)   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

0000100000  EB 52 90 4E 54 46 53 20 20 20 20 00 02 08 00 00  ëR.NTFS    .....
0000100010  00 00 00 00 00 F8 00 00 3F 00 FF 00 00 08 00 00  .....ø..?.ÿ.....
0000100020  00 00 00 00 80 00 80 00 FF FF 69 18 00 00 00 00  ....€.€.ÿÿi.....
0000100030  00 00 0C 00 00 00 00 00 02 00 00 00 00 00 00 00  ................
0000100040  F6 00 00 00 01 00 00 00 60 E7 B5 9E 0C B6 9E D4  ö.......`絞.¶žÔ
0000100050  00 00 00 00 FA 33 C0 8E D0 BC 00 7C FB 68 C0 07  ....ú3ÀŽÐ¼.|ûhÀ.

FAT32

FAT32는 보통 다음과 같은 영역으로 나눠진다.

+------------------------+
| Reserved Region        |
| (Boot Sector 포함)      |
+------------------------+
| FAT #1                 |
+------------------------+
| FAT #2 (백업)          |
+------------------------+
| Data Region            |
+------------------------+

Reserved Region

Reserved Region에는 주로 Boot Sector (VBR — Volume Boot Record), FSInfo(파일 시스템 정보 섹터), 기타 예약된 섹터로 이루어져 있다.

이 중 디지털 포렌식에서 주요한 데이터는 Boot Sector(0번 섹터)에 위치한다. HxD로 분석하고자 하는 논리 디스크를 가져오면 데이터를 확인할 수 있다.

Offset(h)  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

000000000  EB 00 90 20 20 20 20 20 20 20 20 00 02 20 24 00  ë..        .. $.
000000010  02 00 00 00 00 F8 00 00 3F 00 FF 00 20 00 00 00  .....ø..?.ÿ. ...
000000020  E0 17 DD 01 CE 1D 00 00 00 00 00 00 02 00 00 00  à.Ý.Î...........
000000030  01 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000040  80 00 29 7B 01 3E 51 4E 4F 20 4E 41 4D 45 20 20  €.){.>QNO NAME  
000000050  20 20 46 41 54 33 32 20 20 20 00 00 00 00 00 00    FAT32   ......
000000060  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000070  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000080  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000090  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000000A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000000B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000000C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000000D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000000E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000000F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000100  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000110  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000120  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000130  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000140  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000150  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000160  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000170  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000180  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000190  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000001A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000001B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000001C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000001D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000001E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000001F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA  ..............Uª
  1. jummp command (0x00 ~ 0x02): EB 00 90 부트 코드로 점프
  2. BPB(Bios Parameter Block) (0x03 ~ 0x5A)
  3. Boot Code (0x5B ~ 0x1FD)
  4. Signature (0x1FE ~ 0x1FF)

BPB(Bios Parameter Block)구조를 자세히 살펴보면 다음과 같다.

Offset(h)  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

000000000  EB 00 90 20 20 20 20 20 20 20 20 00 02 20 24 00  ë..        .. $.
000000010  02 00 00 00 00 F8 00 00 3F 00 FF 00 20 00 00 00  .....ø..?.ÿ. ...
000000020  E0 17 DD 01 CE 1D 00 00 00 00 00 00 02 00 00 00  à.Ý.Î...........
000000030  01 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000040  80 00 29 7B 01 3E 51 4E 4F 20 4E 41 4D 45 20 20  €.){.>QNO NAME  
000000050  20 20 46 41 54 33 32 20 20 20 00 00 00 00 00 00    FAT32   ......
000000060  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  1. OEM ID (0x03 ~ 0x0A)
  2. Reserved Sector (0x0E ~ 0x0F): 24 00
  3. Total Sector 32 (0x20 ~ 0x23)
  4. FAT Size 32 (0x24 ~ 0x27): CE 1D 00 00 (Size of one FAT Area)
  5. Volume Serial Number (0x43 ~ 0x46)
  6. Volume Label (0x47 ~ 0x51): NO NAME
  7. File System Type (0x52 ~ 0x5A): FAT32

FAT Area(FAT #1, FAT #2)

앞서 살펴본 FAT32 VBR영역 중 Reserved Sector에는 FAT Area 이전에 존재하는 섹터 수가 담겨 있기 때문에 이 값을 이용해 FAT Area의 시작 주소를 찾을 수 있다. FAT offset = VBR offset + Reserved Sector * 0x200 위의 경우 0 + 0x24 * 0x200 = 0x4800이다.

FAT Area는 여러 개의 엔트리로 구성되며 각 엔트리는 Data Area의 클러스터 할당 상태를 나타낸다. FAT Area 엔트리는 4바이트의 값이고, Data Area의 클러스터는 0x1000바이트 크기를 가지며 FAT Area의 하나의 엔트리는 하나의 클러스터와 일대일 대응된다.

Offset(h)  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

000004800  F8 FF FF 0F FF FF FF FF FF FF FF 0F 04 00 00 00  øÿÿ.ÿÿÿÿÿÿÿ.....
000004810  05 00 00 00 06 00 00 00 FF FF FF 0F 08 00 00 00  ........ÿÿÿ.....
000004820  09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00  ................
000004830  0D 00 00 00 0E 00 00 00 0F 00 00 00 10 00 00 00  ................
000004840  11 00 00 00 12 00 00 00 13 00 00 00 14 00 00 00  ................

0번(0x4800) 1번(0x4805) 엔트리는 사용하지 않기 때문에 2번 엔트리부터 사용자가 생성한 파일이나 폴더가 등장한다.

각 엔트리 값의 범위에 따른 의미는 다음과 같다.

  1. Free Cluster (0x00000000): 사용되지 않는 빈 클러스터
  2. Next cluster number (0x00000002 ~ 0x0FFFFFEF): 이 클러스터 다음에 이어지는 클러스터 번호
  3. Bad Cluster (0x0FFFFFF7): 손상된 클러스터
  4. End Of File (EOF) (0x0FFFFFF8 ~ 0x0FFFFFFF): 파일의 마지막 클러스터

2번(0x4808), 6번(0x4818) 엔트리는 End Of File로 엔트리가 파일에서 마지막임을 나타낸다. 이는 각 파일의 크기가 1개 클러스터보다 작기 때문에, 각 파일에 1개 클러스터만 할당되었음을 의미한다.

3번 ~ 6번 엔트리를 보면 5번까지는 해당 엔트리 값으로 다음 엔트리 값을 가지고 있다. 그리고 6번에서 EOF가 있는 것으로 보아 3 ~ 6 엔트리들이 하나의 파일에 할당되어 있는 것을 알 수 있다.

Data Area

Data Area는 FAT Area 주소에서 FAT 크기 2개(FAT #1, FAT #2)를 더한 값으로 찾을 수 있다. Data Area offset = VBR offset + Reserved Sector * 0x200 + FAT Size * 0x200 * 2 이므로 계산해보면 0+ 0x4800 + 0x1DCE * 0x200 * 2 = 0x778000이다.

0x778000주소에는 FAT32의 Root Directory가 위치하고, 이는 2번 클러스터에 해당하며 FAT 테이블의 2번 엔트리에 대응된다.

Root Directory 내에는 32바이트의 Directory Entry 구조가 반복되어 저장되며 구조는 다음과 같고, 이를 SFN 구조라고 한다.

  1. File Name (0x00 ~ 0x07)
  2. Extension (0x08 ~ 0x10): 파일 확장자
  3. Attributes (0x0B ~ 0x0B): 속성 플래그
  4. Reserved (0x0C ~ 0x0C)
  5. Creation Time(ms) (0x0D ~ 0x0D)
  6. Created Time (0x0E ~ 0x0F): 생성 시간
  7. Created Date (0x10 ~ 0x11): 생성 날짜
  8. Last Access Date (0x12 ~ 0x13): 마지막 접근 날짜
  9. High 16 bits of First Cluster (0x14 ~ 0x15): 클러스터 번호 상위 16비트
  10. Last Write Time (0x16 ~ 0x17): 마지막 수정 시간
  11. Last Write Date (0x18 ~ 0x19): 마지막 수정 날짜
  12. Low 16 bits of First Cluster (0x1A ~ 0x1B): 클러스터 번호 하위 16비트
  13. File Size (0x1C ~ 0x1F): 파일 크기(byte)

File Name을 보면 최대 8바이트까지만 저장이 가능하다. 파일이름이 8바이트를 초과하게 되면 SFN이 아닌 LFN 구조를 이용한다.

+------------------------+
| LFN Entry (N번째)      |
| - Sequence Number (N)  |
| - Name (부분문자 1~5)   |
| - Attribute: 0x0F      |
| - Checksum             | 
| - Name (부분문자 6~11) |
| - Name (부분문자 12~13)|
+------------------------+
| ... (다수의 LFN Entry) |
+------------------------+
| LFN Entry (1번째)      |
+------------------------+
| SFN Entry              |
| - Short Name (8.3)     |
| - Attributes           |
| - Cluster, Size 등     |
+------------------------+

LFN의 구조는 위와 같은 형태로 파일의 이름이 길어질수록 추가되는 형태이다. 또한 LFN 엔트리 내부의 구조는 다음과 같다.

  1. Seq Num (0x00 ~ 0x00): LFN 엔트리 순서
  2. File Name (0x01 ~ 0x0A)
  3. Attr(0x0B ~ 0x0B)
  4. Reserved (0x0C ~ 0x0C)
  5. Check Sum (0x0D ~ 0x0D)
  6. File Name (0x0E ~ 0x19)
  7. First Cluster Low (0x1A ~ 0x1B): 항상 0
  8. File Name (0x1C ~ 0x1F)

이 정보를 이용해 디스크 내 임의의 PNG파일을 찾아보자.

Offset(h)  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

000778340  42 64 00 66 00 2E 00 50 00 4E 00 0F 00 8F 47 00  Bd.f...P.N....G.
000778350  00 00 FF FF FF FF FF FF FF FF 00 00 FF FF FF FF  ..ÿÿÿÿÿÿÿÿ..ÿÿÿÿ
000778360  01 61 00 64 00 66 00 73 00 66 00 0F 00 8F 73 00  .a.d.f.s.f....s.
000778370  64 00 64 00 66 00 73 00 64 00 00 00 61 00 73 00  d.d.f.s.d...a.s.
000778380  41 44 46 53 46 53 7E 31 50 4E 47 20 00 08 AF BD  ADFSFS~1PNG ..¯½
000778390  78 4E D1 5A 00 00 B0 BD 78 4E 07 00 B2 18 0A 00  xNÑZ..°½xN..²...

Directory Entry 구조들을 살펴보다 PNG파일을 발견하였다. 파일 이름이 길어서 LFN 구조로 쌓여있는 것 같다. offset 0x0007783400x000778360를 보면 0x42와 0x01이라 되어있는데, LFN 구조의 Seq Num은 마지막 LFN 구조에만 0x40과 OR을 한다. 따라서 0x000778360가 첫 번째 LFN 엔트리, 0x000778340가 2번째 이자 마지막 LFN 엔트리, 0x000778380는 바로 파일 이름이 있는 것으로 보아 SFN 엔트리인 것 같다.

SFN 엔트리 부분을 Directory Entry 구조에 대응하여 몇가지 정보를 확인하면 확장자가 PNG임을 알 수 있고, 클러스터 번호 하위 16비트가 0x07임을 알 수 있다. 앞서 Root Directory가 2번 엔트리라 하였으므로 png파일의 데이터는 Root Directory 주소에서 5개 클러스터만큼 이동한 offset 즈음에 있을 것이다. 0x778000 + cluster(0x1000) * 5 = 0x77D000 해당 offset 이후부터 png파일의 시그니처 헤더와 푸터를 찾아 추출해보면 원래 디스크에 있던 png파일과 동일한 파일을 얻을 수 있다.

Offset(h)  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00078C000  89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52  ‰PNG........IHDR
00078C010  00 00 01 B6 00 00 02 48 08 06 00 00 00 0D 79 C1  ...¶...H......yÁ
00078C020  84 00 00 00 01 73 52 47 42 00 AE CE 1C E9 00 00  „....sRGB.®Î.é..
00078C030  00 04 67 41 4D 41 00 00 B1 8F 0B FC 61 05 00 00  ..gAMA..±..üa...
00078C040  00 09 70 48 59 73 00 00 0E C3 00 00 0E C3 01 C7  ..pHYs...Ã...Ã.Ç
00078C050  6F A8 64 00 00 FF A5 49 44 41 54 78 5E 74 FD 87  o¨d..ÿ¥IDATx^tý‡
...

NTFS

NTFS의 전반적인 구조는 다음과 같다.

+-------------------------+
| VBR (Volume Boot Record) |
+-------------------------+
| MFT (Master File Table)  |
+-------------------------+
| Data Area               |
+-------------------------+
| Backup VBR (끝부분)     |
+-------------------------+

VBR

Offset(h)   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

0000000000  EB 52 90 4E 54 46 53 20 20 20 20 00 02 08 00 00  ëR.NTFS    .....
0000000010  00 00 00 00 00 F8 00 00 3F 00 FF 00 00 30 14 00  .....ø..?.ÿ..0..
0000000020  00 00 00 00 80 00 80 00 FF 27 08 1D 00 00 00 00  ....€.€.ÿ'......
0000000030  00 00 0C 00 00 00 00 00 02 00 00 00 00 00 00 00  ................
0000000040  F6 00 00 00 01 00 00 00 B0 9E 7C F4 D1 7C F4 2C  ö.......°ž|ôÑ|ô,
0000000050  00 00 00 00 FA 33 C0 8E D0 BC 00 7C FB 68 C0 07  ....ú3ÀŽÐ¼.|ûhÀ.
0000000060  1F 1E 68 66 00 CB 88 16 0E 00 66 81 3E 03 00 4E  ..hf.ˈ...f.>..N
0000000070  54 46 53 75 15 B4 41 BB AA 55 CD 13 72 0C 81 FB  TFSu.´A»ªUÍ.r..û
0000000080  55 AA 75 06 F7 C1 01 00 75 03 E9 DD 00 1E 83 EC  Uªu.÷Á..u.éÝ..ƒì
0000000090  18 68 1A 00 B4 48 8A 16 0E 00 8B F4 16 1F CD 13  .h..´HŠ...‹ô..Í.
00000000A0  9F 83 C4 18 9E 58 1F 72 E1 3B 06 0B 00 75 DB A3  ŸƒÄ.žX.rá;...uÛ£
00000000B0  0F 00 C1 2E 0F 00 04 1E 5A 33 DB B9 00 20 2B C8  ..Á.....Z3Û¹. +È
00000000C0  66 FF 06 11 00 03 16 0F 00 8E C2 FF 06 16 00 E8  fÿ.......ŽÂÿ...è
00000000D0  4B 00 2B C8 77 EF B8 00 BB CD 1A 66 23 C0 75 2D  K.+Èwï¸.»Í.f#Àu-
00000000E0  66 81 FB 54 43 50 41 75 24 81 F9 02 01 72 1E 16  f.ûTCPAu$.ù..r..
00000000F0  68 07 BB 16 68 52 11 16 68 09 00 66 53 66 53 66  h.».hR..h..fSfSf
0000000100  55 16 16 16 68 B8 01 66 61 0E 07 CD 1A 33 C0 BF  U...h¸.fa..Í.3À¿
0000000110  0A 13 B9 F6 0C FC F3 AA E9 FE 01 90 90 66 60 1E  ..¹ö.üóªéþ...f`.
0000000120  06 66 A1 11 00 66 03 06 1C 00 1E 66 68 00 00 00  .f¡..f.....fh...
0000000130  00 66 50 06 53 68 01 00 68 10 00 B4 42 8A 16 0E  .fP.Sh..h..´BŠ..
0000000140  00 16 1F 8B F4 CD 13 66 59 5B 5A 66 59 66 59 1F  ...‹ôÍ.fY[ZfYfY.
0000000150  0F 82 16 00 66 FF 06 11 00 03 16 0F 00 8E C2 FF  .‚..fÿ.......ŽÂÿ
0000000160  0E 16 00 75 BC 07 1F 66 61 C3 A1 F6 01 E8 09 00  ...u¼..faáö.è..
0000000170  A1 FA 01 E8 03 00 F4 EB FD 8B F0 AC 3C 00 74 09  ¡ú.è..ôëý‹ð¬<.t.
0000000180  B4 0E BB 07 00 CD 10 EB F2 C3 0D 0A 41 20 64 69  ´.»..Í.ëòÃ..A di
0000000190  73 6B 20 72 65 61 64 20 65 72 72 6F 72 20 6F 63  sk read error oc
00000001A0  63 75 72 72 65 64 00 0D 0A 42 4F 4F 54 4D 47 52  curred...BOOTMGR
00000001B0  20 69 73 20 63 6F 6D 70 72 65 73 73 65 64 00 0D   is compressed..
00000001C0  0A 50 72 65 73 73 20 43 74 72 6C 2B 41 6C 74 2B  .Press Ctrl+Alt+
00000001D0  44 65 6C 20 74 6F 20 72 65 73 74 61 72 74 0D 0A  Del to restart..
00000001E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000001F0  00 00 00 00 00 00 8A 01 A7 01 BF 01 00 00 55 AA  ......Š.§.¿...Uª

VBR의 구조는 위와 같고 FAT32와 유사하다.

  1. jummp command (0x00 ~ 0x02): EB 00 90 부트 코드로 점프
  2. BPB(Bios Parameter Block) (0x03 ~ 0x5A)
  3. Boot Code (0x5B ~ 0x1FD)
  4. Signature (0x1FE ~ 0x1FF)

BPB(Bios Parameter Block)구조를 자세히 살펴보면 다음과 같다.

Offset(h)   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

0000000000  EB 52 90 4E 54 46 53 20 20 20 20 00 02 08 00 00  ëR.NTFS    .....
0000000010  00 00 00 00 00 F8 00 00 3F 00 FF 00 00 30 14 00  .....ø..?.ÿ..0..
0000000020  00 00 00 00 80 00 80 00 FF 27 08 1D 00 00 00 00  ....€.€.ÿ'......
0000000030  00 00 0C 00 00 00 00 00 02 00 00 00 00 00 00 00  ................
0000000040  F6 00 00 00 01 00 00 00 B0 9E 7C F4 D1 7C F4 2C  ö.......°ž|ôÑ|ô,
0000000050  00 00 00 00 FA 33 C0 8E D0 BC 00 7C FB 68 C0 07  ....ú3ÀŽÐ¼.|ûhÀ.
  1. OEM ID (0x03 ~ 0x0A)
  2. Total Sectors (0x18 ~ 0x1F): 볼륨의 총 섹터 수
  3. Start Cluster for $MFT (0x30 ~ 0x37)
  4. Volume Serial Number (0x48 ~ 0x4F)

MFT

MFT영역의 주소는 MFT addr = Start Cluster for $MFT * cluster size(0x1000)로 계산해보면 0xC0000000이다.

MFT 영역은 0x400 크기의 MFT 엔트리가 계속 반복된다.

+---------+---------+---------+---------+---------+---------+
| Entry 0 | Entry 1 | Entry 2 | Entry 3 | Entry 4 | ...     |
| (0x400) | (0x400) | (0x400) | (0x400) | (0x400) |         |
+---------+---------+---------+---------+---------+---------+
  1. 0 ~ 15번 엔트리 : 시스템 메타데이터
  2. 16 ~ 23 : 빈 엔트리
  3. 24 ~ : 사용자 데이터
Offset(h)   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00C0000000  46 49 4C 45 30 00 03 00 39 8B 3D 39 29 00 00 00  FILE0...9‹=9)...
00C0000010  01 00 01 00 38 00 01 00 E0 01 00 00 00 04 00 00  ....8...à.......
00C0000020  00 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00  ................
...
00C0000400  46 49 4C 45 30 00 03 00 DB 16 00 02 00 00 00 00  FILE0...Û.......
00C0000410  01 00 01 00 38 00 01 00 58 01 00 00 00 04 00 00  ....8...X.......
00C0000420  00 00 00 00 00 00 00 00 04 00 00 00 01 00 00 00  ................
...
00C0000800  46 49 4C 45 30 00 03 00 21 17 00 02 00 00 00 00  FILE0...!.......
00C0000810  02 00 01 00 38 00 01 00 58 01 00 00 00 04 00 00  ....8...X.......
00C0000820  00 00 00 00 00 00 00 00 04 00 00 00 02 00 00 00  ................

0x400 단위로 엔트리가 있는 것을 확인할 수 있다.

각 MFT 엔트리의 개략 구조는 다음과 같다.

MFT Entry (1024 bytes / 0x400 bytes)
+-------------------------------+ 0x00
| Header (약 42 bytes)          |
+-------------------------------+ 0x30
| Attributes:                   |
|   - $STANDARD_INFORMATION     |
|   - $FILE_NAME                |
|   - $DATA                     |
|   - (기타 속성들)              |
+-------------------------------+
| End Marker (0xFFFFFFFF)       |
+-------------------------------+
| Padding (빈 공간)              |
+-------------------------------+

Header를 확인해보면 다음과 같다.

Offset(h)   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00C0000000  46 49 4C 45 30 00 03 00 39 8B 3D 39 29 00 00 00  FILE0...9‹=9)...
00C0000010  01 00 01 00 38 00 01 00 E0 01 00 00 00 04 00 00  ....8...à.......
00C0000020  00 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00  ................
00C0000030  B5 05 00 00 00 00 00 00 10 00 00 00 60 00 00 00  µ...........`...
  1. Signature (0x00 ~ 0x03)
  2. Attribute Offset (0x14 ~ 0x15)
  3. Flag (0x16 ~ 0x17): 파일/디렉토리, 사용 여부(0x1-사용 중, 0x2-디렉토리)
  4. MFT Record Number (0x2C ~ 0x2F)

다음으로 Header(0x30)이후 부터 Attribute들이 줄줄이 이어진다. Attribute는 TLV (Type-Length-Value) 구조를 따르며 파일 이름, 시간정보, 보안정보, 데이터 등 모든 메타데이터는 Attribute로 표현된다. 각 Attribute는 Attribute ID에 따라 구분되며 다음과 같다.

Attribute ID 이름 설명
0x10 $STANDARD_INFORMATION 생성, 수정시간, 권한 등
0x20 $ATTRIBUTE_LIST 확장 Attribute 연결
0x30 $FILE_NAME 파일 이름, 부모 디렉토리
0x40 $OBJECT_ID Object ID
0x50 $SECURITY_DESCRIPTOR 보안 ACL
0x60 $VOLUME_NAME 볼륨 이름
0x70 $VOLUME_INFORMATION 볼륨 상태
0x80 $DATA 실제 파일 데이터
0x90 $INDEX_ROOT 디렉토리 인덱스 (B+트리)
0xA0 $INDEX_ALLOCATION 인덱스 확장
0xB0 $BITMAP 인덱스 할당 비트맵
0xC0 $REPARSE_POINT 심볼릭 링크 등
0xFFFFFFFF End Marker 종료 표시

Data Area

기본적으로 데이터가 작은 경우(700 ~ 800 byte) Resident라 하여 MFT 엔트리 내부에 데이터가 함께 저장된다. 데이터가 큰 경우는 Non-Resident로 Data Area에 데이터가 저장된다.

Offset(h)   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00C0009580                          80 00 00 00 48 00 00 00          €...H...
00C0009590  01 00 00 00 00 00 04 00 00 00 00 00 00 00 00 00  ................
00C00095A0  01 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00  ........@.......
00C00095B0  00 20 00 00 00 00 00 00 00 20 00 00 00 00 00 00  . ....... ......
00C00095C0  00 20 00 00 00 00 00 00 21 02 E0 1D 00 00 00 00  . ......!.à.....

위 Data Attribute를 살펴보면 마지막 0x00C00095C8 ~ 0x00C00095CF 부분을 cluster run이라 하며 실제 데이터가 있는 곳의 오프셋을 담고 있다.

구조를 시각화 하면 다음과 같다.

+------------+-------------------+-------------------+
| 1 Byte Head| Length (L bytes)  | Offset (O bytes)  |
+------------+-------------------+-------------------+

여기서 head는 앞 4bit와 뒤 4bit로 나뉘어 앞 4bit는 run offset의 길이, 뒤 4bit는 run length의 길이를 나타낸다. 여기서 run offset은 데이터가 저장되어 있는 볼륨의 클러스터 번호를 나타낸다. 실제 값으로 해석을 해보면

21 02 E0 1D 00 00 00 00

head가 21이고 우선 하위 4bit인 1이 run length의 길이로 02가 된다. 그리고 상위 4bit인 2가 run offset의 길이이므로 E0 1D가 된다. 이제 offset을 알았으므로 데이터의 위치를 계산해보면 run offset(0x1DE0) * cluster size(0x1000) = 0x1DE0000이 된다.

Leave a comment