* 들어가기에 앞서 본 스터디에 사용 된 OS 종류 및 VMware 종류에 대해 기술하고 시작하고자 한다. 다른 버전이어도 상관은 없으나, 사용 상 불편한 부분까지 본 블로그에서 일일히 다루어 주지는 않는다. 물론, 질문을 남겨줄 경우, 따로 확인해서 답변을 드리긴 하겠다.

  - 필자 E-Mail : wotmd9408@naver.com

  - 가상머신 : VMWare WorkStation 12

  - OS : Window7 Enterprise K 64bit

  - RAM : 1GB

  - 나머지 사항은 기본적인 세팅으로 설정하였다.

  - 추가 필요 Tool : Hxd(https://mh-nexus.de/en/downloads.php?product=HxD)


우리는 MBR을 시작으로 FAT32 구조의 순서대로 정리를 진행하고 있다. 앞에서도 지겹게 설명한 내용이지만 이 블로그의 내용일 본 포스팅부터 접한 독자도 있을테고 혹은 기억하지 못한 독자도 있을테니 한번 더 확인하고 넘어가도록 하자.


[그림 1. FAT32 구조]

우리는 지난 포스팅을 통해 FAT 영역에 대해 알아보았다. 이제 오늘 포스팅을 통해 알아 볼 영역은 Root Directory Entry이다. 먼저 Root Directory Entry의 모습을 그림을 통해 보도록 하자.


[그림 2. Root Directory Entry 구조]

[그림 2]는 Root Directory Entry의 구조를 보여주고 있다. 앞에서 보던 FAT 또는 BR 구조와는 다르게 이 Root Directory Entry에서는 우리가 확실히 구분할 수 있는 것들이 보인다. 바로 KOALA JPG와 같은 파일을 의미하는 것 같은 내용들이다. 이를 통해 우리는 Root Directory Entry가 어떤 역할을 하는지 유추 할 수 있을 것 같다.

Rood Directory Entry는 위에서 보는것과 같이 볼륨에 존재하는 파일과 디렉터리의 정보를 가지고 있는 영역이다. 데이터 영역의 가장 앞 섹터에 존재하는 영역으로 데이터 영역과 함께 설명해도 전혀 상관없는 영역이지만, 포스팅의 글이 너무 길어 질 경우 가독성이 떨어져 제대로 보지 않게 되어 나누어 설명하고자 한다.(현재까지는 정상적인 실습을 진행하지 않고 이론적으로 설명만 했는데, 데이터 영역부터는 어느정도 실습이 포함되며, File System 에 대한 전반적인 설명이 끝난후에는 여러분이 실습을 해 볼 수 있도록 어느정도 실습 문제 또는 파일도 제공하려고 하니 참고하기 바란다.)


본격적으로 Root Directory Entry에 들어가기 전에 독자 여러분들이 제대로 해당 영역까지 찾아 갈 수 있는지 확인해 보도록 하자. [그림 2]에 Root Directory Entry의 섹터 위치가 나와있긴 하지만, 이 포스팅을 보는 독자들은 양심적으로 안 보고 계산 할 수 있을 거라 본다. 계산이 되었는가? 혹시 기억이 나지 않는다면, 과거 포스팅들을 보는 방법도 있을 것이지만, 시간을 단축하기 위해서 계산에 참고 할 수 있는 내용을 아래에 적어 드릴테니 기억을 더듬어 보도록 한다.

  - BR 영역의 위치

  - 예약된 영역(Reserved Area)의 크기

  - FAT32 의 수

  - FAT32 영역이 가지고 있는 크기


위의 내용으로 계산이 되었는가? 정확히 Root Directory Entry에 도달했다면 정상적으로 계산을 잘 한것이다. 만약 제대로 도달하지 못했다면 기본 세팅에서 잘못 세팅했거나, 어딘가에서 잘못 계산했을 가능성이 있으니 다시 한번 신중하게 계산 해 보기 바란다.


[그림 3. Root Directory Entry 출력 화면]

앞서 여러분이 봤던 [그림 2]와는 거의 비슷한 내용의 출력화면이다. 달라진게 있다면 확장자가 없는 무언가가 추가 된 것이다. Root Directroy Entry는 Directory Entry라 불리는 구조치들의 집합이며 그들의 가장 상위에 있는 엔트리이다. 데이터 영역에는 두가지 형태의 구조체가 저장되는데 그것이 우리가 알고있는 디렉터리와 파일이다.  파일은 말 그대로 해당 파일의 정보를 가지고 있으며, 디렉터리의 경우 자신의 정보와 하위 디렉터리 및 파일의 정보를 가지고 있다.


[그림 3]의 경우 Root Directory Entry에 들어있는 출력 형태 중 많이 볼 수 있는 내용을 약 3가지로 구분해서 표시한 내용이다. 각각의 파일 혹은 디렉터리는 디렉터리 엔트리에서 32Byte 단위로 표기되며, 이로 인해 한 섹터당 16개의 디렉터리 엔트리를 담을 수 있다. 

가장 먼저 빨강색 테두리 부분을 보도록 하자. 굉장히 눈에 익숙한 모습이다. 여러분이 예상 하듯이 저 빨강색 테두리는 파일 형태의 디렉터리 엔트리이다. 앞쪽에 파일명과 확장자 명이 보이며, 나머지 모양은 아직 해석하기 어려운 내용들로 구성되어 있다. 그다음으로 아래쪽의 파란색 테두리를 먼저 보도록 하자. 저 파랑색 테두리는 빨강색 테두리와는 다르게 확장자가 표시되지 않았다. 즉, 저런 형태로 되어있다면 디렉터리라는 표시이다.(물론 32Byte 중 디렉터리와 파일을 구분할 수 있도록 따로 입력되어있다)마지막으로 가운데 갈색 테두리 역시 디렉터리이다. 다만 파란색 테두리와는 다르게 ~1로 표기되어 있는데, 이는 뒤에서 설명할 Long File Names로 표기 할 수 있는 이름보다 길게 파일 혹은 폴더명이 생성 될 경우 저런식으로 표기된다.


이제 각각의 디렉터리 엔트리를 표기하는 32Byte의 상세 내역을 확인 해 보도록 하자.

이름

 Name

offset

 0~7

Size

8 Byte 

 Value

파일 명

설명 

파일 또는 디렉터리의 이름이 기록되는 항목. 최대 8자리까지 작성 할 수 있으며 반드시 대문자로 기록된다. 만일 8자리 이하의 이름이 들어갈 경우 빈자리는 반드시 0x20으로 채워야 한다. 우리는 일반적으로 채우는 null(0x00)으로 채울 경우 에러가 발생한다.

  * Name의 경우 첫번째 바이트에 오는 내용에 따라 특별한 의미를 가지고 있는 경우가 있는데 이는 아래를 참고하도록 하자.

Name[0]의 값

설명

0xE5 

이 문자열이 파일명의 맨 앞에 위치 할 경우, 해당 디렉터리 엔트리의 파일은 삭제 된 파일이라는 의미이다. FAT 파일 시스템에서는 파일 혹은 디렉터리를 삭제 할 경우 엔트리를 완전히 초기화 하는 것이 아니라 파일명의 맨 앞 바이트를 0xE5로 바꾸어 저장한다. 이로 인해 삭제 하더라도 파일의 복구가 가능하다.

 0x00

해당 디렉터리 엔트리는 비어있으며 이전까지 탐색한 디렉터리 엔트리가 가장 마지막 리스트임을 의미한다. 실제로 해당 내용이 나올 경우 뒤에 나오는 모든 값이 0x00으로 표기되어 있음을 확인할 수 있다. 분석 간 이 문구를 만난다면, 더이상 아래를 분석 할 필요가 없다.

0x05

이 바이트에 대한 실제 파일 이름 문자는 0xE5이다. 일본어로 파일을 만들경우 문제가 하나 발생하는데, 일본 문자(간지)의 집합 선두 바이트도 0xE5로 표기된다. 이로 인해 일본어로 파일명을 만들면 전부 삭제된 데이터로 인식되어 버리게 되어, 이에 대한 편법으로 0x05로 적고 있다. 

 * 여기서 주의할 점이 하나 있다면 파일명의 첫번째 바이트에는 0x20(스페이스)이 올 수 없다. 또한 0x05를 제외하고는 0x20보다 작은 값이 올 수 없다.

이름

 Extender

offset

 8~10

Size

3 Byte 

 Value

확장자

설명 

파일의 확장자를 넣는 항목이다. 최대 3자리까지 입력 가능하며 반드시 대문자로 입력해야 한다. 만약 3자리 이하의 확장자(ex : sh 등등)라면 남는 공간은 반드시 0x20으로 채워야 한다. 파일이 아닌 디렉터리의 경우 확장자가 없기 때문에 반드시 0x20으로 채워 넣어야 한다.


이름

 Attribute

offset

 11

Size

1 Byte 

 Value

아래 참조

설명 

해당 Directory Entry의 용도를 결정하는 값이다. 해당 Directory Entry가 파일인지 폴더인지 결정되는 부분이 바로 이 부분이다. 각각의 항목들에 대해서는 아래 표를 참고하도록 하자.



속성 값

 속성 Name

설명

0x01

Read Only

읽기 전용 파일. 이 속성이 걸려있는 파일은 쓰기를 막도록 코드를 작성해야 함.

0x02

Hidden

숨김 파일. 보통의 사용자에게 해당파일을 보여주지 않음. 

0x04 

System

운영체제(System)이 사용하는 파일

0x08

Value Label

이 파일의 이름이 곧 볼륨의 이름이 된다. 이 속성은 반드시 Root에 있어야 하며 1개만 존재한다. 이 속성의 파일은 ClusterHigh와 ClusterLow가 0x00으로 만들어진다. (클러스터를 할당 할 필요가 없음) 

0x10

Directory

서브 디렉터리를 의미(우리가 일반적으로 말하는 디렉터리를 의미한다) 

0x20

Archive

일반으로 말하는 파일을 의미한다. 

0x0F

Long FIle 

name Entry

파일명, 또는 확장자의 이름이 제한보다 길어 Long File Name Entry로 사용한다.


이름

 NT Resource

offset

 12

Size

1 Byte 

 Value

0x00

설명 

NT 계열의 Windows 운영체제가 사용하기 위해 예약해 놓은 공간. 항상 0으로 해야 한다.


이름

 Create Time Tenth

offset

 13

Size

1 Byte 

 Value

0 ~ 199

설명 

파일이 생성 된 시각을 1/10초 단위로 기록한 항목으로 Create Time과 관련 이 있다.


이름

 Create Time

offset

 14~15

Size

2 Byte 

 Value

가변적

설명 

파일 생성 시간을 표현하는 영역으로, 자세한 내용은 아래 설명을 참고하도록 하자.

 * Create Time은 뒤에서 나오는 다른 시간 관련 설정과 마찬가지로 2Byte 안에 정보를 담아야 한다. 그래서 Create Time 이나 Access Time 등 시간 정보를 정할 때는 해당 Hex 값을 이진수로 바꾸어 계산해야 한다. [그림 3]에 있는 KOALA.JPG 파일을 기준으로 설명해보도록 하겠다. 

[그림 4. koala.jpg 파일의 Create Time 값]

[그림 4]에서 드래그 한 부분은 koala.jpg 파일을 표기하는 32Byte를 보이는 부분이며 붉은색 네모 [38 1B] 가 바로 우리가 지금 확인 할 Create Time 부분이다. 앞서 우리가 사용하는 Intel 기반에서는 리틀엔디언 표기법을 사용한다고 설명했다. 즉 [38 1B]를 우리가 표기할 때는 0x1B38로 확인 후 계산해야 한다. 이 값을 이진수로 변환할 때 바이트 단위로 변환하는게 아닌 값 하나 하나를 변환 해야한다. 다시 말해 1B, 38를 이진수로 변화하는게 아닌 1, b, 3, 8를 각각 이진수로 변환해야 한다는 의미이다. 

각각을 이진수로 변환하면 0001 1011 0011 1000이 된다. 이를 순서그대로 다시 합친 뒤 5bit, 6 bit, 5bit 크기로 자른다. 이 설명대로 실행 하면 00011 011001 11000 가 된다. 각각의 bit 의미는 아래 표를 참고하도록 하자. 

[그림 5. Create Time 항목 구조]

[그림 5]처럼 항목별로 구분했다면, 이제는 각각의 파트를 우리가 알아볼 수 있는 10진수로 다시 변환하면 된다. 이번 koala.jpg의 경우 03시 25분 24초가 된다. 그런데 여기서 한가지 문제가 있는데 5bit의 이진수 표기는 최대 31까지(실제로는 29)만 표기된다는 문제가 있다. 현실세계에서 Seconds(초)는 60초로 표기되기 때문에 Seconds를 계산한 값에 2를 곱해줘야 한다. 즉, 3시 25분 48초가 된다. 지금은 필자의 파일로 테스트를 했지만, 독자분들도 한번 테스트 해보면서 맞는지 확인해보도록 한다. 실제로 필자가 확인 한 파일 생성 시각은 아래 그림과 같았다.

[그림 6. koala.jpg 파일의 생성 시각 확인]

여러분도 과정을 정확히 따라왔다면 정확하게 계산됨을 알 수 있다. 또한 초를 계산할 떄 2가 곱해지기 때문에 짝수로만 표기되게 된다. 해당 계산은 모든 시각에 동일하게 사용되기 때문에 잘 기억하기 바란다. 따라서 시각에 대한 유효 범위는 00:00:00 ~ 23:59:58이 된다.

이름

 Create Date

offset

 16~17

Size

2 Byte 

 Value

가변적

설명 

파일의 생성 날짜를 표시한다.

  * Create Date 역시 Create Time과 비슷하게 2바이트 파일에 날짜 정보를 모두 표기해야한다. 따라서 이 부분도 실제 날짜를 10진수로 확인하기 위해서는 Hex 값을 이진수로 바꾼 뒤 다시 10진수로 변환해야 한다. 이번에도 동일하게 Koala.jpg 파일을 예시로 들어보도록 하겠다.


[그림 7. koala.jpg 파일의 Create Date]

방식은 Create Time을 계산할 때와 비슷하다. [3B 4B] 값을 리틀엔디언으로 표기하면 0x4B3B가 되며, 이를 이진수로 변환하면 0100 1011 0011 1011이 된다. 이를 순서대로 나열한 뒤 이번에는 7bit, 4bit, 5bit로 나누도록 한다. 이대로 실행하면 0100101 1001 11011 가 된다. 각각의 의미는 아래 표를 참고하도록 하자.


[그림 8. Create Date 항목 구조]

[그림 8]을 기준으로 각각의 항목을 10진수로 변환하면 37년 9월 27이 된다. 무언가 이상하지 않은가? 현재 우리가 살고있는 년도는 서기 2017년이다. 앞의 두자리는 빼더라도 뒤의 두자리도 맞지 않는다. 왜 그럴까? 위에서 우리가 Create Time를 계산 할 때 초 단위를 계산하던 것을 생각하면 비슷하다. [그림 8]에서 알 수 있듯이 년도는 총 7bit의 이진수로 구성 되는데, 이 범위는 0 ~ 127까지의 범위만을 표기 할 수 있다. 따라서 FAT32 파일시스템에서는 기준년도 1980년을 기준으로 오프셋을 계산하여 나타낸다. 즉, 이를 기준으로 다시 계산하면 2017(1980 + 37)년 9월 27이 된다. 맞는지 확인해 보도록 하자. 

[그림 6]으로 돌아가서 확인하면 우리가 계산한 값이 맞게 나오는 것을 알 수 있다. 위 계산은 시간 계산할 때와 마찬가지로 모든 날짜(Last Access Date, Write Date)를 표기할 때도 동일하게 적용된다.


이름

 Last Access Date

offset

 18~19

Size

2 Byte 

 Value

가변적

설명 

이 항목은 파일의 읽기/쓰기 작업을 했던 마지막 날짜를 기록한다. 파일 생성과는 다르게 Time은 없이 Date만 표기함을 기억하라. 만약 마지막 작업이 쓰기였다면 이 항목의 값과 Write Date의 값이 동일해야 한다. 10진수로 표현하기 위해서는 Create Date와 동일하게 계산하면 된다.


이름

 First Cluster High

offset

 20~21

Size

2 Byte 

 Value

가변적

설명 

이 항목은 파일의 첫번째 클러스터 번호의 상위 2Byte를 담고 있다. FAT16의 경우 클러스터 번호가 2Byte로 이루어져 있어 이 항목이 필요없다. 지금 공부하는 FAT32 에서는 보통 0x0000으로 기록된다. (value를 가변적이라고 적었지만 아직까지 0 이외의 값을 본적은 없다.)


이름

 Write Time

offset

 22~23

Size

2 Byte 

 Value

가변적

설명 

가장 최근에 이 파일을 수정한 시간을 표시한다. 만일 이 파일이 생성되고 단 한번도 수정되지 않았다면 최초 생성시간으로 기입하기도 한다. 10진수로 표현하기 위해서는 Create Time과 동일하게 계산하면 된다.


이름

 Write Date

offset

 24~25

Size

2 Byte 

 Value

가변적

설명 

가장 최근에 이 파일을 수정한 날짜를 표시한다. 만일 파일이 생성되고 단 한번도 수정되지 않았다면 최초 생성날짜로 기입하기도 한다. 10진수로 표현하기 위해서는 Create Date와 동일하게 계산하면 된다.


이름

 First Cluster Low

offset

 26~27

Size

2 Byte 

 Value

가변적

설명 

이 항목은 파일의  첫번째 클러스터 번호의 하위 2Byte를 담고 있다. FAT16의 경우 클러스터 번호가 2Byte로 이루어져 있기 때문에 이 항목만으로도 확인이 가능하다. 지금 공부하는 FAT32의 경우 파일이 가지는 클러스터의 가장 앞 번호를 표기하도록 되어있다.


이름

 File Size

offset

 28~31

Size

4 Byte 

 Value

가변적

설명 

이 항목은 파일의 크기를 나타낸다. FAT32를 공부하는 동안 유일하게 실제 용량을 나타내는 부분이다. MBR이나 BR영역에서 용량을 계산하려면 사용하는 Sector 양을 확인한 뒤 512를 곱해 계산해야 하지만 이 부분은 따로 추가적인 계산없이 Hex 값을 10진수로 바꾸면 바로 파일의 용량이 나온다. 만약 해당 영역이 디렉터리라면 반드시 0으로 표기되어야 한다.


지금까지 Root Directory Entry에서 표기되는 항목들에 대해 알아보았다. 이후 실습과정에서 실제로 Hex Editor를 통해 파일을 직접 생성해 볼 예정이다. 부디 실습간 유용하게 쓰이기를 빈다. 

그러나 이 포스팅에서 Root Directory Entry에 나오는 모든 항목을 설명하지 않았다. 바로 Long File Names에 대한 내용이다. 이번 포스팅이 좀 내용이 길어져 다음 포스팅에 파일명 등을 정리해 보도록 하겠다.


* 참고 1 : 임베디드 개발자를 위한 파일시스템의 원리와 실습(정준석, 정원용 공저), 한빛미디어

* 참고 2 : http://hyd3.tistory.com/125


Posted by Latte_
,