마지막으로 FAT32 FileSystem을 다룬것이 작년 10월 경이니, 어느새 1년 가까운 시간이 지나버렸습니다. 지난 1년간 블로그를 그냥 두려고 했던 것은 아니나, 본의아니게(?) 실컷 놀아버린 꼴이 되어버렸습니다.

정신을 차리고보니 이도 저도 아닌 제 모습이 보여서.. 뭐라도 해야 할 것 같았습니다. 그래서 매번 공부해야지 해야지 하고 못했던.. 리버스 엔지니어링을 시작해보고자 합니다. 

Reverse Engineering, 주로 리버싱이라고 불리는 이 역공학 방식은 소프트웨어 공학의 한 분야로 '이미 만들어진 시스템을 역으로 추적하여 처음의 문서나 설계자료를 얻어내는 일'을 말합니다.[1] 역공학이라고 불리우는 이유는, 보통 소프트웨어 생명주기의 마지막 단계에서 초기의 자료등을 얻어내기 때문에 기존 소프트웨어 공학의 역방향으로 흐르기에 역공학이라고 지칭되고 있습니다.

리버싱은 단순히 소프트웨어 공학에만 쓰이는 것이 아니라, 보안쪽에서도 많이 사용되고 있습니다. 주로 백신사나 침해사고 대응 업무에서 많이 사용되고 있는데 침해 PC나 Web 상에서 수집 된 악성코드를 역공학을 이용해 분석 후 탐지될 수 있는 Singnature를 추출하거나 특정 Software를 분석하여 취약점을 찾는데 사용되고 있습니다.


리버스 엔지니어링을 할 줄 안다는 것은 그만큼 여러 분야에 도움이 될 수 있다는 장점이 될 수 있지만 반면 수요가 그리 많지 않다는 단점도 존재합니다. Anti-Virus 생산 업체나 일부 특수한 조건을 제외하고는 해당 분야에 필요한 인재를 뽑지 않거나, 뽑더라도 적은 수를 뽑기 때문입니다. 

필자도 악성코드 분석가가 되고 픈 마음은 굴뚝같지만, 리버싱을 잘 하지 못하기 때문에 지원하지 못하고 있습니다.(이 블로그는 제가 잘 알아서 쓰는게 아니라, 제가 공부한 것을 정리하는 개념으로 작성하는 부분입니다)

따라서 여러분께 이 블로그를 통해 악성코드 분석의 비법을 전달해 드린다기 보다는 '필자는 이렇게 공부했다' 라는 내용을 보여드리는 쪽으로 진행 될 것 같습니다. File System 때와 마찬가지로 부족한 부분이 많겠지만 보시고 많은 질책과 격려 부탁드립니다.

시간이 지나면 여러 악성코드도 분석하고 할 기회가 있겠지만, 이 [Reverse Engineering] 의 시작은 Lena's Tutorial로 시작 할 예정입니다.

그럼 많은 관심 부탁드립니다. 아! 그리고 본격적인 설명 및 분석에는 File System 때와 마찬가지의 어법이 쓰일 예정입니다. 지금처럼 완전 존대가 되지 않으니 참고 하시기 바랍니다.


[참고]

[1] https://terms.naver.com/entry.nhn?docId=1180896&cid=40942&categoryId=32837

Posted by Latte_
,

2018년 새해가 되자마자 보안업계 뿐 아니라 일반 업체에도 한바탕 크게 태풍이 몰아쳤다. 과거에도 이런 큰 태풍이 있었을까? 경력이 그렇게 길진 않아서 과거에 얼마나 큰 이슈가 있었는지 까지는 알지 못한다. 

그나마 작년에 크게 터진 이슈라면 전 세계적으로 확산 된 WannaCry 정도 일 것이다. 근데 그런 WannaCry도 Microsoft에서 긴급 패치를 발표하고 일단락이 됐다.


그런데 이녀석은 그렇지 않다. 다른건 둘째치고 규모가 어마어마하다. 과거 WananCry의 경우 Windows OS를 사용하는 PC로 제한됐다. SMB를 사용하기 때문에 Linux는 Target이 아니었기 때문이다.

지금 소개할 두 녀석은 WannaCry를 뛰어넘는다. 이녀석은 OS를 구분하지 않는다. Windows, Linux, Mac OS 할 것 없이 취약하다. 이게 무엇을 의미하는지 아는가?

이 두 녀석은 Software적인 취약점이 아닌 Hardware 취약점이다. 즉 특정 Hardware가 들어간 PC 혹은 서버는 이 취약점을 가지고 있다는 소리이다. 문제는 이 Hardware의 점유율이 80%에 육박한다는 점이다. 


제목에도 나와있지만 지금부터 소개할 두 녀석은 Meltdown과 Spectre이다. 2017년 6월 Google Project Zero Team에 의해 발견된 이 취약점은 2018년 새해가 되자마자 전 세계에 태풍을 몰고 왔다. 그간 일반 유저의 PC 뿐 아니라 기업의 Server에 독보적인 점유율을 자랑하던 Intel CPU에 잠들어 있던 취약점이 공개되자 보안 업계는 술렁했고, 기업들 역시 패치에 고심하고 있는 추세이다.

이 두녀석이 태풍을 몰고 온 이유는 바로 저 점유율이 큰 역할을 했다. CPU는 Intel과 AMD가 대립하고 있다고는 하지만, AMD로서는 Intel의 점유율을 따라갈 수가 없었다. Ryzen을 공개하며 돌풍을 몰고가나 헀던 AMD의 점유율은 Intel과의 큰 차이를 극복하지 못했고, 현재도 60%가까운 차이를 보이고 있다.

문제는 이 Intel의 점유율이 단순히 수치만으로 보이지 않는다는 점이다. 이 두 취약점은 Intel CPU의 구조적인 취약점을 이용한다. 문제는 이 취약점이 최근 프로세서에 생긴 문제가 아니라, 과거 20년이상 이어온 취약점이라는 점이다.

취약점 자체가 20년동안 발견되지 않은 것도 놀랍지만, 20년산(?) 취약점이 생각보다 큰 파급력을 가져온다는 것이 문제였다. Meltdown은 보안 전반에, 그리고 Spectre는 특히 가상화를 사용하는 기업에 큰 피해를 유발 할 가능성이 있다. 무엇보다! 대부분 기업에서 사용하는 서버에는 Intel CPU가 들어가있다는 점이다!!!


일반 사용자분들은 크게 와닿지 못할 Meltdown과 Spectre! 한번 필자와 쉽게 이해 할 수 있도록 해보자. 

'보안 > Issue_알아보기' 카테고리의 다른 글

#1. 들어가며  (0) 2018.03.05
Posted by Latte_
,

마지막으로 블로그에 글을 언제 연재했나 봤더니 2017년 10월이다.

그간 공부를 얼마나 안했는지 알 수 있는 지표이며, 또한 필자가 얼마나 끈기가 없는 지 보여주는 지표가 아닐까 싶다.

사실 리버싱도 일을 벌려놓고 작성도 못한 포스트들이 넘쳐나는데, 이 포스팅도 제대로 진행할 수 있을지는 필자 스스로에 대한 의문이 든다.

부디 올 한해는 열심히 포스팅을 하겠다는 마음가짐으로.. 최선을 다해보도록 노력 하겠다.


2018년이 시작되고 3달이 지났고, 그 사이에 우리가 알게 모르게 보안 취약점들이 많이 나왔으며 그 중에는 Meltdown / Spectre와 같은 큰 충격으로 다가온 취약점들도 있었다.

사실 Meltdown과 Spectre가 나오고 나서도 필자는 그렇게 크게 탐구하거나 하지는 않았다. 내가 근무하고 있는 업체는 Endpoint를 방어하는게 아니라 상단 Network 구간을 담당하고 있었으니까.

그러다 최근 회사에서 해당 이슈를 알아야 할 필요성이 생겨 간단히 찾아보게 되었고, 그를 토대로 이렇게 포스팅을 할 기회가 생긴것 같다.

물론 '이미 공개된지 2달이 지난 시점이고 많은 분석가 분들이 분석을 해 주셨기에 따로 포스팅을 할 필요가 없다'라는 말씀을 하시는 분들도 있을 것이다.

사실 그 생각은 필자도 어느정도 동의하고 있는 바이다. 이미 인터넷에는 수많은 Meltdown과 Spectre에 대한 설명들이 나와있으니까. 과연 지금 작성하는게 무슨 의미가 있을까?


그래서 이 포스트는 과거 발생한 크고 작은 보안 Issue에 대해 일반인들도 알기 쉽게 설명해 보는데 목표를 두고자 한다.

어느정도 기술적인 부분이 들어가는건 어쩔 수 없을 것이지만, 그래도 비유등을 통해서 쉽게 접근해 보도록 하겠다. 

기술적인 부분은 각종 보안 분석가들이 자세히 설명해 놓으셨거나, github에 올라와 있는 것들이 많을테니, 그부분들을 참조해주시면 되겠다.


그럼, 이번엔 부디 꾸준히 포스팅을 하기를 기원하며..

'보안 > Issue_알아보기' 카테고리의 다른 글

[Meltdown&Spectre] #1. 이슈 소개  (0) 2018.03.05
Posted by Latte_
,

* 들어가기에 앞서 본 스터디에 사용 된 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)


여기까지 따라온 독자들에게 깊은 감사의 인사를 드린다. 되도록이면 하나의 포스팅을 짧게 끝내려고 생각은 하고 있으나, 쓰다보니 그게 마음대로 되지 않아 전반적으로 내용이 길어져 읽는데 힘들었을 독자들을 생각하면 조금 죄송스러운 마음이 드는건 사실이다. 이 이야기를 여기에 쓰는 이유는 앞으로 만들어질 실습을 제외하면(물론 정확히 언제 완성될지는 모르겠지만..) 마지막 포스팅이 될 예정이기 때문이다. 


[그림 1. FAT32 구조]

위 그림을 기억하겠는가? 포스팅을 잘 따라온 독자라면 "이제는 그만좀 올려도 되지 않을까?"하는 생각을 할만한 그림일 것이다. 우리는 MBR을 시작으로 [그림 1]의 순서대로 공부를 진행해 왔다. 이제 대망의 마지막인 Data Area(데이터 영역)을 보려고 한다.

사실 Data Area는 앞서 포스팅했던 Root Directory Entry를 포함한다. [그림 1]에서는 조금 더 보기 쉽도록 표시되어 있지만, 예약영역(Reserved Area)의 가장 앞 섹터에 존재하는것과 마찬가지로 FAT32에서 Root Directory Entry는 데이터 영역의 가장 앞 섹터에 위치한다. 즉, Root Directory Entry부터 해당 파티션이 갖는 마지막 섹터까지가 데이터 영역이 된다. 


먼저 데이터 영역에 존재하는 내용이 무엇인지 살펴보자. 가장 먼저 앞서 확인한 Directory Entry가 있다. 이때 데이터 영역의 가장 앞에 존재하는 디렉터리 엔트리가 Root Directory Entry이고, 나머지가 그냥 Directory Entry이다. 이 Root Directory Entry에 포함하는 파일/디렉터리는 우리가 파티션에 해당하는 드라이브에 접근했을 경우 보이는 가장 상단 경로의 디렉터리 혹은 파일을 의미한다. 그리고 그 Root Directory Entry에서 우리는 해당 디렉터리 엔트리에 존재하는 파일과 디렉터리의 각종 정보를 확인 할 수 있다.

디렉터리 엔트리에서 특정 파일에 대한 정보를 수집했다면 이제 그 파일에 대한 데이터가 있는 부분으로 이동할 수 있다.(이 부분에 대해서는 이후에 자세히 설명하도록 한다.) 물론, Root Directory Entry에서 확인한 정보가 '파일'에 대한 정보라면 해당 파일의 데이터 정보에 접근할 수 있다. 그러나 파일이 아닌 디렉터리에 대한 정보라면 해당 디렉터리가 가지고있는 디렉터리 엔트리 부분으로 향하게 된다. 이번 포스팅에서는 파일을 분석해 파일의 데이터를 확인하고, 실제로 정보들을 역 이용해 데이터를 생성하는 과정을 진행해 볼 것이다.


[그림 2. Directory Entry내 파일 정보]

파일의 데이터 영역에 접근하기 위해서는 디렉터리 엔트리 내에 있는 파일의 정보를 읽어 낼 수 있어야 한다. 사실 데이터 영역에 접근하기 위해서 [그림 2]에 있는 모든 정보를 구할 필요는 없다. 결론부터 이야기하면 3가지(First Cluster High, First Cluster Low, File Size)만 알면 데이터 정보를 찾아오는데는 아무런 문제가 없다. 그러나 복습을 위해서, 하나하나 분석 해 보도록 하자.

  - File Name / Extender : KOALA.JPG

  - Attribute : 0x20 => 일반적인 File을 지칭

  - Create Time : 0x1B38 => ‭0001 1011 0011 1000‬

    Time값이니 5/6/5로 나누면 ‭00011 011001 11000 가 되고, 이를 다시 10진수로 변환하면 ‬3시 25분 48(시간값은 계산값에 *2)초 가 된다.

  - Create Date : 0x4B3B => ‭0100 1011 0011 1011‬

    Date값이니 7/4/5로 나누면 ‭0100101 1001 11011‬ 가 되고, 이를 다시 10진수로 변환하면 2017(년도 값은 기본 1980년에 계산값을 더한다)년 9월 27일이 된다.

  - Last Access Date : 0x4B3B => 위의 Create Date와 값이 같으니 계산은 생략한다.

  - First Cluster High : 0x0000

  - Write Time : 0x7410 => ‭0111 0100 0001 0000‬

    Time 값이니 5/6/5로 나누면 ‭‭01110 100000 10000‬‬ 가 되고, 이를 다시 10진수로 변환하면 14시 32분 32(시간값은 계산값에 *2)초가 된다.‬

  - Write Date : 0x3AEE => ‭0011 1010 1110 1110‬

    Date값이니 7/4/5로 나누면 ‭0011101 0111 01110 가 되고, 이를 다시 10진수로 변환하면 ‬2009(년도 값은 기본 1980년에 계산값을 더한다)년 7월 14일이 된다.

  - First Cluster Low : 0x03

  - File Size : 0x000BEA1F => ‭780,831‬

    여러분이 FAT32 또는 NTFS에서 "유일"하게 이 부분만이 추가적인 계산 없이 바로 용량을 표기하게 된다.(다른 부분에서는 사용하는 Sector 수 로 확인되는 경우가 많다)

    또한 디렉터리의 경우 용량이여기 존재하지 않기 때문에 File Size 값이 0으로 되어있다.

 * 지난 포스팅에서 소개한 NT Resource 및 Create Time Tenth의 경우 중요하지 않아 따로 표기하지 않았다. 추가적으로 필자가 적은 결과와 독자가 계산한 결과는 다를 수 있다. 과정을 동일하게 진행했더라도 생성 시간 등은 같을 수 없기 때문에 반드시 본인이 작성한 환경에서 계산을 진행해야 한다.

 * 당시 포스팅에서 제대로 소개하지 않았지만, FAT32 구조에서는 Access Time을 표기하지 않는다. 해당 내용을 표기하지 않는 이유는 32byte 안에 해당 내용을 다 기입 할 수 없기 때문이다.


이 Koala.jpg 파일을 기준으로 파일의 데이터가 위치한 곳으로 접근해 보도록 하자. 우선 파일의 데이터 영역으로 가기 위해서 중요한 부분은 First Cluster High, First Cluster Low 그리고 File Size이다. 사실 First Cluster High의 경우 항상 0을 가지니 결국엔 First Cluster Low와 File Size만 중요하다고 보면 된다. 방금 설명한 세가지에 대한 계산은 [그림 2]를 분석하며 확인했으니 다시 기입하지는 않겠다.

데이터로 가기 위해서는 First Cluster High와 First Cluster Low를 순서대로 결합한 뒤 2을 빼 주면 된다. 이는 FAT32에서 0번과 1번 클러스터는 이미 시스템에서 예약 후 사용하고 있기 때문이다. 이를 토대로 계산을 해보도록 하자.

  - First Cluster High + First Cluster Low = 0x00000003 = 3

  - FAT32에서 0번과 1번 클러스터는 이미 사용중이니 빼면 3-2 = 1

여기서 우리가 한가지 알아야 할 내용이 있는데, 1개의 클러스터는 8개의 섹터를 가진다는 점이다. 이를 토대로 Root Directory Entry인 16512 섹터에서 8 섹터를 이동한 16520으로 가면 우리가 찾던 Koala.jpg 파일의 데이터를 확인 할 수 있다.


[그림 3. Koala.jpg 파일의 Data 부분]

여러분이 필자와 동일하게 구성을 했거나, 아니면 각자의 세팅에 맞게 찾아 갔다면 위와 같이 정상적인 koala.jpg 파일의 데이터를 확인 할 수 있다. 여기서 문제는 여러분이 찾아간 16520 섹터에 있는 내용이 정말로 koala.jpg 파일의 데이터가 맞냐는 점이다. 물론 File Size를 이용해 데이터를 복사해서 따로 저장한 뒤 확인 하는 방법도 있을것이다. (그리고 그게 가장 정석적인 방법이기는 하다.) 그 방법은 잠시 후에 확인 해 볼 예정이며 지금은 File Signature를 이용해 확인하는 방법을 알아보자.

File Signature란 문자 그대로 해석하면 '파일의 서명'이 되는데 보다 자세히 풀이하면 '파일이 가지고 있는 고유한 문자열'이라고 봐도 무방하다. 파일은 일부 확장자를 제외하면 대부분의 확장자가 각기 다른 시작 문자열을 가지고 있다.(여기서 말하는 시작 문자열은 확장자 명이 아닌 해당 파일을 Hex Editor로 열었을 때 보이는 Hex 값 및 String 값을 의미한다.)

  * DLL 과 EXE 확장자처럼 서로 다른 확장자를 가지고 있으나 동일한 시그니처를 가지고 있는 경우도 존재한다. 

시그니처는 보통 파일의 시작 문자열부터 일정 부분까지를 의미하는데 평균 4Byte 정도에서 많게는 16Byte까지 되는 경우가 있다. 우리가 확인한 JPG 확장자의 File Signature는 FF D8 값을 시그니처로 가지고 있으며 데이터의 가장 끝은 항상 FF D9로 끝나게 되어있다. 그러나 보통 JPG/JPEG 파일을 확인 할 경우에는 FF D8 FF E0 와 JFIF 부분을 확인한 뒤 JPG 파일임을 확인하는 경우가 대부분이다.

  * 파일 별 시그니처 정보를 확인하고 싶은 경우 이 URL에 접속해 검색하면 확인 해 볼 수 있다.(http://www.garykessler.net/library/file_sigs.html)


이제 시그니처를 통한 확인이 아니라 데이터 영역을 복사해 파일을 생성함으로써 실제 koala 파일이 맞는지 확인 해 보도록 하자. 만약 koala.jpg 파일의 데이터 섹터에서 벗어났다면 다시 계산을 통해 해당 섹터로 이동하도록 하자. 이후 데이터의 가장 앞부분에 커서를 놓고 마우스를 우클릭한 뒤 [블록 선택]을 누르도록 하자. 

[그림 4. koala.jpg 파일 크기 입력]

이후 [그림 2]를 통해 계산한 File Size 값을 길이에 입력한 뒤(10진수로 변환한 뒤 780,831‬를 입력해도 상관없다.) 수락을 누르면 가장 해당 데이터의 마지막으로 이동되며 그 이전까지가 블록 선택이 된다. 그 내용을 복사해 새로 파일을 만들어 test.jpg로 저장하면 koala.jpg와 동일한 그림이 나타나는 것을 볼 수 있다.


폴더의 경우도 계산하는 방법은 파일과 동일하다. 다만 파일과 달리 폴더는 용량을 가지고 있지 않다. 따라서 동일하게 계산한 섹터로 이동하면 폴더의 데이터 영역이 있는게 아니라 해당 폴더에 저장된 파일들의 디렉터리 엔트리로 이동하게 된다. 그리고 해당 디렉터리 엔트리 내에 있는 파일의 내용을 기준으로 다시 들어가면 파일의 실제 데이터 영역으로 이동하게 되는 것이다. 한번 실습을 통해 확인 해 보도록 하자.

[그림 5. Forensics 폴더의 Directory Entry 정보]

우리가 실습해 볼 폴더는 [그림 5]에 입력 된 forensics라는 폴더이다. 폴더명이 8자를 넘어 LFNs(Long File Names) 방식으로 입력되어 있는 것을 확인할 수 있으며 폴더는 File Size가 0이므로 First Cluster High 와 First Cluster Low만 확인 후 계산하면 된다.

  - First Cluster High + First Cluster Low = 0x000000C2 = 0xC2

  - FAT32에서 0번과 1번 클러스터는 이미 사용중이니 빼면 0xC2 - 2 = 0xC = 192

위에서 파일의 데이터 영역 주소를 찾을 때도 설명했듯이 하나의 클러스터는 8개의 섹터를 가지고 있다. 즉 16,512 섹터로부터 1,563 섹터 뒤로 이동하면 이 폴더의 디렉터리 엔트리로 이동 할 수 있다. 계산 값인 18,048로 이동해 결과를 확인해 보도록 하자.

[그림 6. Forensics 폴더 계산 후 결과 비교]

Foreniscs 폴더의 디렉터리 엔트리 정보를 통해 계산한 결과. Forensics 폴더 안에는 Jellyfish.jpg라는 파일이 있는것을 확인 할 수 있었으며 실제 Windows 탐색기를 통해 확인한 결과 실제로 Jellyfish.jpg 파일을 확인 할 수 있었다.

지금까지 배워온 내용들을 잘 이용하면 Hex Editor를 이용해 실제로 파일을 생성해 내는게 가능하다. 단순히 생성하는 것 뿐만 아니라 MAC Time을 조작한 데이터를 생성할 수 있고 원하는 데이터를 밀어 넣을 수도 있다. 관련된 실습은 추가적인 실습 포스팅을 통해 진행할 예정이다.


이 포스팅을 마지막으로 FAT32에 대한 설명을 마무리 하려고 한다. 필자도 실무에서 포렌식 업무를 수행하지 않고 있어 실제 어떻게 업무가 진행되는지는 정확히 알려줄 수는 없으나 여태까지 진행해온 이론이 실제 업무에 도움이 될 수 있을 것으로 생각한다. 파일 시스템에 대해 공부하다보면 Web Hacking이나 모의해킹과는 다르게 조금 지루함을 느끼기가 쉽다. 아무래도 모의해킹이나 다른 여러가지 분야에 비해서는 실제로 보여지는 퍼포먼스나 결과가 그렇게 화려하거나 크지 않기 때문이다.

그러나 여러분이 실제로 Encase나 FTK(Forensics ToolKit)를 이용해 보면 모의해킹이나 기타 다른 보안 공부를 할때와 같은 기분을 느낄 수 있을 것이다. 지금까지 진행 된 포스팅은 그 밑바탕이 되기 위한 이론을 다지는데 그 목적을 두었다.


길고 긴 FAT32에 대한 포스팅을 따라온 독자분들께 감사의 인사를 남긴다. 다음 포스팅부터는 NTFS를 진행하게 될텐데, 아마 FAT32보다는 조금 어렵고 복잡한 부분이 있기때문에 조금은 더 각오를 하고 들어오는 것을 추천한다. 그동안 고생많았고, 부디 진행된 포스팅들이 여러분의 앞날에 도움이 되었기를 바란다.


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

* 참고 : http://www.garykessler.net/library/file_sigs.html

Posted by Latte_
,

* 들어가기에 앞서 본 스터디에 사용 된 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)


이제 FAT32 파일시스템도 어느정도 마무리 단계에 접어 들었다. 물론 이번 포스팅이 끝이 아니고 몇가지가 더 남아있긴 하지만(간단하게 풀어볼 수 있는 문제도 제작 해 보려고 하고있다.) 그래도 칠부능선을 넘은건 사실이다. 이론만 따지면 두번이나 세번 정도의 포스팅이면 간략하게나마 마무리 될 것으로 보인다.


지난 포스팅을 통해 Root Directory Entry의 구조와 각각의 디렉터리 엔트리가 어떤식으로 구성되어있는지 세부적인 내용들을 알아보았다. 그러나 해당 포스팅에서 다루지 않은 내용이 남아있다. 그것이 이번 포스팅에서 다룰 Short File Name과 Long File Names 이다.

파일 및 디렉터리는 생성할 때 각각의 고유한 이름을 가진다. 물론 이 고유한 이름이 절대적으로 Unique 하지는 않다. 동일한 확장자에 대해서만 고유한 이름을 갖고 있으니 오해 없기를 바란다. 그리고 각각의 파일명은 몇가지 규칙을 가지고 있으며, 해당 규칙을 위반할 경우 파일이 정상적으로 생성되지 않는다. 이 규칙은 SFN(Short FIle Name) 과 LFN(Long File Name)이 조금씩 다른 부분이 있기 때문에 따로 나누어 설명 하도록 하겠다.


먼저 알아볼 내용은 SFN(Short File Name)이다. 의미 그대로 짧은 파일명을 의미하고, FAT32기준에서는 8Byte (영문 8자, 한글 4자)이하, 3Byte이하의 확장자 파일 혹은 디렉터리일 경우 Short File Name으로 표기된다. 그림을 통해 예시를 들어보도록 하자.

[그림 1. Short File Name의 예시]

[그림 1]은 지난번 Root Directory Entry에서도 봤던 코알라 사진이다. 위에서 말한 Short File Name의 조건과 일치하는지 한번 확인해 보도록 하자. 먼저 파일명이 8Byte인지 확인하면 K,O,A,L,A로 총 5개의 알파벳으로 파일명이 구성되어 5Byte 값을 가진다. 그리고 확장자 역시 JPG로 3Byte 값만 가지기 때문에 Short File Name의 조건이 된다고 볼 수 있다.

그러면 Short File Name에 만족한다는 가정하에 어떤 규칙을 지켜야 파일이 생성되는지 확인해 보도록 하자.

  - 영어 대문자 A ~ Z (소문자는 대문자로 바꾸어 저장)

  - 해당 운영체제가 지원하는 언어의 문자( ex : 한글 MS-DOS라면 한글 파일명 가능)

  - 아라비아 숫자 0 ~ 9

  - 특수문자 중 $, %, ', -. _, @, ~, !, (), {}, ^, #,&


위에서 가장 첫번째 조건의 경우, 실제 파일을 만들때는 소문자로 만들어도 문제가 없지만, Root Directory Entry에 저장될 때는 대문자로 저장하기에 저렇게 기입하였다. 또한 따로 적혀있지 않지만, Short File Name 작성 규칙에서 파일 명 사이에 스페이스(0x20)을 입력하는 것은 가능하다. ( ex : MY NAME.HWP) 그러나 일부 프로그램의 경우 파일명 중간에 Space가 포함될 경우 파일을 제대로 인식 못할 수 있기 때문에 Under Bar( _ )를 지향하는 것이 좋다. 또한 영어가 아닌 외래어의 경우 한 글자당 2Byte로 인식하기 때문에 그 또한 알아두면 좋다. 그리고 마지막으로, 전 포스팅에서 이야기 했듯이 파일명 가장 앞에 스페이스(0x20)이 들어갈 수 없다.


SFN(Short File Name)은 이정도로만 설명해 두도록 하자. 이후 추가적으로 필요한 부분이 있으면 필자가 더 채워 두도록 하겠다. 이제부터는 이 포스팅에서 본격적으로 다뤄 볼 LFNs(Long File Names)에 대해 알아보도록 한다.


Window 95가 나오기 이전, 그러니까 MS-DOS와 Window 3.x버전이 PC의 기본 OS였던 시절에는 FAT 파일시스템이 나올 때부터 쓰이던 8.3 Naming, 즉 우리가 위에서 SFN(Short File Name)으로 알고있는 방식만이 사용되었다. 그러한 이유로 많은 유저들은 매킨토시(MAC OS)나 Unix, Linux 계열처럼 긴 파일명을 사용 할 수 있기를 원했다. 그래서 나온 기능이 Window 95와 함께 나온 LFNs(Long File Names)이다.

LFNs의 자세한 구조를 알기전에, LFNs의 특징들에 대해 먼저 짚고 넘어가도록 하자.

  - 유니코드(UTF-16)방식으로 인코딩되어 있기 때문에 다국어 지원이 가능

  - 최대 255자까지 저장 가능

  - 3자리 이상의 확장자도 저장 가능

  - 기존의 SFN(Short File Name)과 호환 됨

  - SFN보다 사용할 수 있는 특수문자 폭이 넓어짐

MircroSoft는 LFNs를 설계하면서 하위 호환의 개념을 버리지 않으려고 노력했다. 앞으로 우리가 보게 될 Long File Name Entry는 전 포스팅에서 보았던 Directory Entry를 변형해서 구성하여 하위 호환성을 유지했다. 물론, 억지로 비틀어(?)만든 방식이니 만큼 구조가 어색하고 상당히 불편하다. 

LFNs의 가장 큰 특징중 하나는 바로 유니코드를 지원한다는 점이다. 이는 Microsoft의 큰 밑그림(빅픽처??)으로 인해 지원하는 부분인데 Windows가 여러 나라에 사용될 것을 대비해 추가 된 기능이다. 물론 이 기능으로 인해 저장 공간이 2배이상 늘어나 버린 단점은 분명히 존재하지만, 현재의 상황으로 따지고 보면 미래를 정확히 내다 본 좋은 선택이었음에는 틀림없다.


[그림 2. Long File Names 표기의 예시]

[그림 2]는 필자가 예시로 만든 Forensics라는 디렉터리를 Root Directory Entry에서 확인한 것이다. [Forensics] 이라는 단어는 총 9자로 Short File Name 방식인 8/3(8자리 파일명, 3자리 확장자명)법칙으로는 만들어 낼 수 없다. 따라서 [그림 2]처럼 LFNs(Long File Names)로 표기된다. [그림 2]를 보면 동일한 Forensics가 2가지 방식으로 표현된 것을 볼 수 있는데, 붉은색 네모칸과 초록색 네모칸이 바로 그것이다. LFNs의 특징 중 하나는 표기 할 수 있는 부분까지 표기해준 뒤 모자란 부분에 대해서 ~1로 표현하여 LFNs로 표현됐음을 알려주는 것이다. 앞으로 여러분이 보게 될 디렉터리 엔트리 중 ~1이 있으면 LFNs로 표기되었다고 보아도 좋다.

위 그림에 대해 자세히 알아보도록 하자. 먼저 초록색 네모를 보면 SFN(Short File Name)처럼 기록되어있다. 최대 6자까지 파일명을 표기하고 남은 부분을 ~1로 표기하여 LFNs(Long File Names)로 표현되었음을 지칭한 뒤. 파일의 나머지 정보(생성시간, 파일 용량 등)을 표기한다. 여기까지는 [그림 1]에서 본 SFN(Short File Name)과 비슷하다. 그런데 LFNs(Long FIle Names)는 어찌됐든 File명을 전체를 표시해 줘야 하기 때문에, 해당 디렉터리 엔트리 상단 32Byte를 추가로 할당하여 파일명을 마저 표기한다. 이 부분이 붉은색 네모에 해당하는 부분이며 Short Directory Entry와 구분되게 Long Directory Entry라 지칭한다.


아래 정리를 통해 [그림 2] 중 붉은색 영역(Long Directory Entry)에 해당하는 부분에 대하여 자세히 알아보도록 하자.

이름

 Order

offset

 0

Size

1 Byte 

 Value

가변적

설명 

Long File Name Entry가 정렬 된 순번을 기록하는 항목으로 만약 이 항목의 6번째 비트(0x40)가 1이라면 해당 파일명을 구성하는 마지막 Entry를 의미

이름

 Name1

offset

 1~10

Size

10 Byte 

 Value

가변적

설명 

해당 엔트리에 저장할 문자열 중 1~5번째 문자열을 여기에 저장

이름

 Attribute

offset

 11

Size

1 Byte 

 Value

0x0F

설명 

이 항목은 언제나 ATTR_LONG_FILE_NAME을 뜻하는 '0x0F'가 들어가야 한다. 그렇지 않으면 MS-DOS와 같이 LFN Entry를 인식하지 못하는 기존 운영체제에서 문제를 일으키게 된다.

이름

 Type

offset

 12

Size

1 Byte 

 Value

일반적으로 0

설명 

이 항목의 값이 0이라면 일반적으로 LFNs의 항목 중 하나라는 의미이다. 다른 값들은 미래를 위해 예약되어 있다.

이름

 Check Sum

offset

 13

Size

1 Byte 

 Value

가변적

설명 

이 항목은 Short Directory Entry 항목에 들어가는 11자의 문자열에 대한 Check Sum을 저장한다.

이름

 Name2

offset

14~25 

Size

12 Byte 

 Value

가변적

설명 

해당 Entry에 저장할 문자열 중 6~11번째 문자열을 이곳에 저장한다.

이름

 First Cluster Low

offset

 26~27

Size

2 Byte 

 Value

반드시 0

설명 

Long Directory Entry는 파일명을 저장하는 기능밖에 없기 때문에 이 부분은 의미 없는 값이기는 하나, 기존의 FAT 코드와의 호환성을 위해 반드시 0으로 기입한다.

이름

 Name3

offset

 28~31

Size

4 Byte 

 Value

가변적임

설명 

해당 Entry에 저장할 문자열 중 12~13번째 문자열을 이곳에 저장한다.

위 표들을 자세히 살펴보면 한가지 특이한 점을 알 수 있다. Long File Name Entry 하나 당 13개의 문자열을 저장할 수 있으며, 문자열을 저장할 때 2Byte 당 1개의 문자열을 저장한다는 점이다. 이는 LFNs가 문자열 지정 방식을 유니코드(UTF-16)으로 하고 있기 때문인데, 이 부분에 대해서는 차후에 기회가 되면 따로 정리해보도록 하겠다. 

여기서 의문점 하나. 만약 파일명, 혹은 디렉터리 명이 13자를 넘어갈 경우에는 어떻게 되겠는가? 간단하다. 필요한 숫자만큼 Long Directory Entry를 생성하게 되며 최대 255자 까지 생성이 가능하기 때문에 255/13을 해보면 최대 20개의 Long Directory Entry가 생성되게 된다.


그러면 Short Directory Entry 와 Long Directory Entry가 저장되는 형태에는 어떠한 규칙이 존재하는지 아래표를 통해 알아보자.

 Directory Entry 순서

 Order 항목 값 

 N번째 Long File Name Entry(마지막 Entry) 

 LAST_LONG_ENTRY(0x40) | N


 두 번째 Long File Name Entry

 0x02

 첫 번째 Long File Name Entry

 0x01

 위와 대응하는 Short Directory Entry

 (해당 없음)

위 표대로 Short Directory Entry가 가장 하단에 위치하고 그 위로 Long Directory Entry가 순서대로 시작되어서 맨 위쪽에 마지막 문자열의 Long File Name Entry가 위치한다. 마지막 Long File Name Entry에는 해당 Entry가 마지막임을 알려주기 위해 Order 항목에 마지막 Entry 번호와 0x40번 비트를 OR시키게 된다. 만약 7번째가 Long File Name Entry라면 Order 값은 0x47이 되는 것이다. 아래 예시를 통해 Short Directory Entry 및 Long Directory Entry를 정리 해 보도록 하자.


[그림 3. Short/Long Directory Entry 예시]

실습을 위해 제목이 긴 파일 하나를 만들었다(필자가 매우 좋아하는 영국 드라마 "Doctor Who"에서 주인공이 타고다니는 우주선 이름이다). [그림 3]을 통해 하나하나 확인 하도록 하자. 먼저 가장 하단의 Short Directory Entry부터 확인해 보도록 하겠다. 기준은 전 포스팅에서 설명했던 디렉터리 엔트리 설명과 이번 포스팅에서 설명한 Long File Name Entry 설명을 기준으로 작성하도록 하겠다.

 - Name  : TIMEAN~1 

   -> 해당 파일명으로만 봤을 때는 TIMEAN~1로 보일 수 있으나 위의 내용들을 함께 봤을 때 이 파일은 LFNs로 표현되어 있음을 알 수 있다.

 - Extender : TXT

 - Attribute : 0x20

   -> 0x10은 디렉터리, 0x20은 파일을 의미한다. 따라서 이 디렉터리 엔트리는 파일임을 알 수 있다.

 - Create Time : 0xB61A => 1011 0110 0001 1010

    5/6/5로 변환하면 10110 110000 11010 가 되는데 이를 다시 10진수로 변환하면 22시 48분 26초가 되는데 마지막 Seconds 부분은 최대 31까지밖에 표기하지 못하므로 2를 곱해야 해서 22시 48분 52초가 된다.

[그림 4. Create Time 확인]

 - Create Date : 0x4B47 => 0100 1011 0100 0111

    7/4/5로 변환하면 0100101 1010 00111 가 되는데 이를 다시 10진수로 변환하면 37년 10월 7일이 된다. 전 포스팅에서 연도를 계산할 때는 기본 1980에 앞에서 구한값을 더하라고 했으므로 최종 값은 2017년 10월 7일이 된다. [그림 4]를 통해 맞는 결과인지 확인하도록 하자.

 - Last Access Date : 0x4B47 => 마지막 접속 날짜는 날짜 변경 이후에 따로 접속한 이력이 없기 때문에 생성 날짜와 동일한 값을 가진다.

 - First Cluster High : 0x00

 - Write Time : 0xB623 => 1011 0110 0010 0011

    5/6/5로 변환하면 10110 110001 00011 이 되는데 이를 다시 10진수로 변환하면 22시 49분 3초가 된다. 위의 Create Time과 마찬가지로 마지막 seconds 값은 2를 곱해줘야 하므로 최종 결과는 22시 49분 6초가 된다. [그림 4]에서 수정한 날짜의 시간을 확인해 보도록 하자.

 - Write Date : 0x4B47 => Create Date와 같은 값이 표기되어 있다.

 - First Cluster Low : 0x00C4 => 다음 포스팅에서 실제로 사용 할 수 있을 것이다.

 - File Size : 0x00000E => 10진수로 변환하면 14Byte가 나온다. [그림 4]에서 크기를 확인해 보도록 하자.


위에서는 Short Directory Entry에 대해서 알아보았다. 전 포스팅의 복습이 되었길 바라며 이제 이번 포스팅에서 다루었던 Long Directory Entry 내용을 확인 해 보도록 하자.

먼저 32Byte 씩 잘라서 총 몇개의 Long File Name Entry가 있는지 확인해보자.

[그림 5. 예제 파일의 Long File Name Entry 종류]

조금 그림자체가 복잡하게 되어있지만 [그림 5]는 에제 파일의 Long Directory Entry 내에 Long File Name Entry를 하나하나 나눈 것이다. Long File Name Entry의 수를 세는것은 생각보다 간단하다. Short Directory Entry에서 LFNs 타입을 확인 한 후 해당 디렉터리 엔트리 위로 32Byte씩 잘라가면서 가장 앞 바이트 값을 확인하면 된다.(마지막 엔트리가 0x01, 0x02 등이 아닌 0x41~ 0x60 사이의 값이 오면 마지막 엔트리가 된다.)

앞서 위의 표에서 봤던 내용을 토대로 Long File Name Entry 값을 확인해 보도록 하자.(내용이 길어지는 관계로 본 포스팅에서는 1번 Long Directory Entry만 함께하도록 하겠다. 이후 내용은 스스로 실습 해 보도록 하자)

 - Order : 0x01 => 첫번째 Long Directory Entry

 - Name1 : T.i.m.e. . => Time 과 스페이스(0x20)이 해당 Name1에 포함된 이름 값으로 되어있다.

 - Attribute : 0x0F => 이 값은 반드시 고정되어야 한다.

 - Type : 0x00 => LFNs의 항목중 하나

 - Check Sum : 0xA3 => 계산법은 추후에 따로 설명하도록 한다.

 - Name2 : A.n.d. .R.e. => And와 스페이스(0x20), 그리고 Re가 Name2에 포함되어 있다.

 - First Cluster Low : 0x00

 - Name3 : l.a. => la가 name3에 포함되어 있다.

위 내용으로 봤을 때 첫번째 Long Directory Entry에 포함된 파일의 이름은 Time And Rela가 된다. 이후 나머지 Long Directory Entry값은 독자분들이 실습을 통해 확인해 보기 바란다. 파일명은 [그림 4]에 나와있으니 최종 결과는 그곳에서 확인하면 되겠다.

생각보다 짧게 끝날것으로 예상했던 포스트였는데 실습이 포함되면서 생각보다 길어진 감이 있다. 이해가 잘 안될수도 있고, 이론만으로 진행하다보니 학습에 지루함이 있을 수 있다. 실제 업무에 들어가서는 이렇게 Hex Editor를 사용하는 일보다는 Encase나 FTK Editor를 이용하는 일이 더 많을 것이다.(필자로 실제로 실무를 하지 않아서 확신할 수는 없지만..) 그러나 이렇게 이론을 알아가는 것이 실제 업무를 하는데 상당한 도움이 될 것이니 소홀히 하지 말기 바란다.

다음 포스팅에서는 FAT32 의 마지막 단계인 Data Area에 대해 기술하도록 하겠다.


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

Posted by Latte_
,

* 들어가기에 앞서 본 스터디에 사용 된 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_
,

* 들어가기에 앞서 본 스터디에 사용 된 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)


지난 포스팅에 이어 이번에는 FAT 영역에 대해 정리해 보도록 하겠다. 먼저 앞서 설명했던 FAT32의 구조에 대해서 기억하는지 살펴보자.


[그림 1. FAT32 구조]

[그림 1]은 FAT32#1 포스팅에서 보았을 것이다. FAT32 볼륨 가장 앞에는 Boot Record가 오며, 그 뒤를 이어 예약영역, FAT 영역, 데이터 영역 등으로 이루어져 있다. Boot Record는 앞선 포스팅에서 설명을 했고, 이번에 설명할 영역은 FAT #1과 #2로 이루어진 FAT 영역에 대해서 설명하고자 한다.


위 구조대로라면 우리가 원하는 FAT 영역으로 가기위해서는 Boot Record와 예약영역을 지나야 갈 수 있다. 앞에 내용을 복습하기 위해, MBR부터 FAT#1까지 가기위한 계산을 수행해 보도록 하자.

[그림 2. MBR 영역 구조]

가장 먼저 볼륨의 Boot Record의 위치부터 확인해야 한다. BR 영역의 시작을 가르키는 Start LBA Address는 파티션 테이블 영역의 시작에서 8번째 offset ~ 11번쨰 offset에 위치하고 있으며, [그림 2]에서는 0x80 (Dec = 128)을 기록하고 있다. 이를 따라 128번 Sector로 가면 우리가 찾던 BR 영역이 존재함을 확인 할 수 있다. 


[그림 3. Boot Record 영역]

[그림 3]은 바로 지난 포스팅에 설명했던 Boot Record 영역이다. BR영역의 전체적인 구성이나 세부적인 내용은 바로 전 포스팅을 참조하도록 하자. 우리가 이번 포스팅을 통해 공부해야 할 내용은 BR영역이 아니라 FAT 영역이니까 말이다. 

위 FAT 영역의 위치를 잘 모르겠다면 화면을 위로 올려 [그림 1]을 다시 보고 오기 바란다. FAT 영역으로 가기 위해서는 BR영역까지의 섹터와 예약 영역의 섹터 수를 더하면 FAT 영역의 시작 섹터가 나오게 된다. Boot Record에는 예약 영역이 갖는 전체 섹터 수(Reserved Sector Count)를 표기하고 있는데 offset 주소로 000E ~ 000F가 Reserved Sector Count가 된다. 값은 0x2A10으로 기록되어있으나, *리틀엔디언 표기법에 따라 0x102A로 계산하면 4,138이 나온다.

 * 앞서 설명했어야 하나, 미처 설명하지 못해 본 포스팅에서 '리틀 엔디언'에 대해 설명하고자 한다. 엔디언은 쉽게말하면 바이트를 배열하는 순서인데, 큰 단위가 앞에오는 빅 엔디언, 작은 단위가 앞에오는 리틀 엔디언으로 나뉜다. 예를 들어 0x1234를 입력할 경우, 빅 엔디언 기반의 구조에서는 12 34로 입력되고 리틀 엔디언 기반에서는 34 12로 기록되는 것이다. 우리가 사용하는 Intel 기반에서는 리틀 엔디언 기반으로 사용하고 있으니 섹터 수를 계산할 때 특히 햇갈리지 않도록 한다. 특별한 경우가 없다면 앞으로는 리틀 엔디언 기반으로 설명할 예정이며 빅 엔디언 기반으로 설명해야 할 경우에는 따로 언급 하도록 한다.

혹시라도 4,138 섹터로 간 독자가 있는가? 혹시 가봤다면 어떤 결과가 나오는가? 필자랑 동일하게 앞의 과정부터 수행했다면, 나오지 않아야 정상이다. Reserved Area는 말 그대로 시스템에서 나중에 사용하기 위해 '예약한' 영역이기 때문이다. 


[그림 4. FAT Area]

[그림 4]는 [그림 1]에서 FAT#1에 해당하는 영역이다. 우리가 예전에 봐왔던 MBR이나 BR과는 사뭇 다르게 굉장히 심플하게 구성되어있다. 하지만 저 심플하게 구성된 부분이 파일 시스템에서는 굉장히 중요한 역할을 한다. FAT는 이름 그대로 File Allocation Table로 파일 할당 테이블을 의미한다. 윈도우 기반의 파일시스템(현재 주로 사용하는 FAT32, NTFS)은 파일의 용량을 할당할 때 클러스터 단위로 할당 한다. 

따라서 FAT 영역에는 별다른 구조체가 존재하지 않고 클러스터의 상태값만을 보여주는 모습이다. 아래 구조를 보고 FAT 영역의 내용에 대해 조금 더 자세히 알아보도록 하자.


[그림 5. FAT Area Structure]

[그림 5]는 [그림 4]에서 보인 FAT 영역을 구조화 한 표이다. 위에서 볼 수 있는 것과 같이 하나의 클러스터는 4byte를 가지고 있다. 자세히 보면 클러스터의 시작이 0번이 아닌 2번부터 시작하는 것을 볼 수 있다. 이는 파일시스템이 FAT 영역의 0번과 1번 클러스터를 Media Type 과 Partition Status의 용도로 사용해버렸기 때문이다. 이는 다음 포스팅에서 다룰 Root Directory에서의 파일 생성 / 복구 등에서 꽤나 중요하게 작용하니 반드시 기억하기 바란다. 


별다를게 없어 보이는 이 FAT 영역을 굳이 포스팅을 통해 정리하는 이유는 이 영역이 파일의 생성, 삭제 등에 있어서 매우 중요하기 때문이다. FAT32 파일시스템은 생성 된 파일의 용량을 정할 때 Cluster 단위로 저장한다. 예를 들어, 5kbyte의 파일을 생성한다고 가정하자. 파일은 생성 될 때 아무리 작은 용량의 파일이라도 1개 이상의 클러스터를 할당 받는다. 기억할지 모르겠지만, 여러분은 BR영역에서 클러스터 당 섹터 수에 대해 정의한 내용을 보았다.


[그림 6. Boor Record Structure]

앞의 포스팅으로 돌아가서 관련 내용을 확인하고 와도 좋지만, 시간을 낭비하기 싫은 독자들을 위해 [그림 6]을 통해 BR의 구조를 확인하도록 하자. 0x0D를 보면 'Sector Per Cluster' 라는 영역을 볼 수 있는데 이 부분이 우리가 이 포스팅에서 중요하게 봐야 할 부분이다. 실제 여러분의 환경에서 'Sector per Cluster'의 값을 보면 '0x08'로 표기되어있는 것을 볼 수 있는데, 아마 여러분이 앞으로 보게 될 거의 모든 FAT32 환경에서는 동일하게 표기되어 있을 것이다. 

FAT32영역에서 'Sector Per Cluster'는 사용자가 임의로 조정하지 않는 한 Defualt 값으로 0x08을 갖는다. 하나의 Sector는 512byte의 값을 갖는데 이를 볼 때 하나의 클러스터는 4Kbyte ( 512Byte * 8 = 4096Byte)의 크기를 갖는 것을 알 수 있다. 다시 위로 올라가서, 5kbyte의 파일을 예를 들면, 1개의 클러스터로는 용량이 부족하기 때문에 2개의 클러스터를 필요로 한다. 아래에서 파일이 있을 떄의 FAT Area의 상태에 대해 자세히 알아 보도록 하자.


[그림 7. 파일이 존재하는 FAT 영역]

[그림 8. VHD 내 존재하는 파일 List]

[그림 7]은 필자의 FAT 영역 내용 중 일부이다.  또한 [그림 8]은 현재 필자의 가상 환경 내 VHD에 존재하는 파일의 List 이다. 각각의 파일은 jpg 파일이 826kbye, txt 파일은 각각의 6자리의 영문을 담고 있는 파일이다. 지금부터 [그림 8]의 파일 List를 기준으로 [그림 7]에 존재하는 내용들을 정리하는 시간을 갖고자 한다.


먼저 [그림 4]로 다시 한번 올라가보자. [그림 4]는 [그림 8]에서 'Desert.jpg'만 존재하지 않는 상태이다. 앞서 [그림 5]에서 우리는 각각의 클러스터의 구조가 어떤식으로 구성되어있는지 확인했다. FAT 영역에서 각각의 클러스터는 파일이나 디렉터리가 저장 된 위치를 Linked List 방식으로 표현하고 있다. 즉, 각각의 FAT Entry는 자신의 다음 Cluster 값을 담고 있다는 의미이다. 즉, 파일이 1개 이상의 클러스터를 가지고 있을 경우 클러스터에는 다음 클러스터의 위치를 갖게 된다는 의미이다.

[그림 7]을 보면 자세히 알 수 있다. 다만 여기서 주의할 게 하나 있다. [그림 7] 의 1번 클러스터를 보면 앞 뒤로 있는 0, 2번 클러스터와는 조금 다른 것을 알 수 있다. 0번은 [F8 FF FF F0], 1번은 [FF FF FF F7] 그리고 2번은 [FF FF FF F0]으로 되어있다. 여기서 0번 클러스터는 [그림 5]에서 설명한것과 같이 시스템이 Media Type으로 사용하고 있다. 

그러면 [그림 7]의 1번 클러스터가 [그림 5]의 Partition status가 되어야 한다. 근데 그렇게 되면 [그림 4]의 내용이 맞지 않게된다. 결론부터 이야기하자면 1번 클러스터는 Bad Cluster로 인식되어 있다. 즉 잘못된 클러스터로 인식되어 사용하지 못해 시스템이 1번 대신 2번 클러스터를 Partition Status으로 설정 한 것으로 보인다. (정황 사정상 그래보이며, 필자도 추가적인 확인을 하게 될 경우 수정하도록 하겠다.) 추가적으로 Bad Cluster의 경우 [FF FF FF F7]로 표기 된다.


이제 실제 데이터 파일이 포함된 3번 Cluster부터 이야기를 해 보도록 하자. 앞서 말했듯이 윈도우 시스템에서는 파일에 용량을 부여할 때 클러스터 단위로 부여하며, 최소 1개 이상의 클러스터를 가진다. 하나의 클러스터는 8개의 섹터를 가진다.(자세한 설명은 필자의 다른 포스팅인 Boot Record 부분을 참고하라. / http://jh8992.tistory.com/entry/FileSystem-Forensics-4-FAT322)


[그림 7]처럼 파일이 하나의 클러스터만 가질 경우 [FF FF FF 0F] 로 표기된다. 이는 해당 클러스터가 파일이 갖는 마지막 클러스터이며 더이상 Link 되는 클러스터가 없음을 의미한다. 그리고 클러스터가 하나 이상의 클러스터를 가질 경우 앞 클러스터의 가장 앞부분에 다음 클러스터의 위치를 담게 된다. [그림 7]을 보면 5번째 클러스터에서 새로운 파일이 시작됨을 알 수 있다. 그리고 그 클러스터 부터 다음 클러스터들을 쭈욱 보면 하나의 공통점을 알 수 있는데 그것은 바로 클러스터의 가장 앞에 다음 클러스터의 번호가 쓰여있으며 나머지는 0으로 채워져 있다는 점이다. 

이는 클러스터가 항상 연결된 Link를 갖지 않기 때문이다. 완전히 포멧된 깨끗한 파일 시스템의 경우 FAT 영역이 꺠끗하기 때문에 순서대로 채워지겠지만 파일이 생성되고 지워짐을 반복함에 따라 모든 클러스터가 순서를 유지할 수 없게 된다. 이러한 경우를 대비해서 모든 클러스터는 자신의 위에 다른 클러스터가 연결 될 경우 다음 클러스터를 명시하도록 되어있다. 물론 파일의 용량이 작아 단일 클러스터만 가지고 있거나 더이상 연결될 클러스터가 없는 마지막 클러스터일 경우 [FF FF FF 0F] 값을 가지게 된다.


어떻게 보면 앞에서 설명한 Boot Record 부분보다는 단순한 구조를 가지고 있는 영역임에도 상당히 길게 서술된 느낌이 있다. 그림이 많이 포함됐거나 하는 여러 이유등이 있을 수 있지만 가장 큰 이유는 이후 포스팅 할 파일 수동 생성 부분에서 이 FAT 영역이 상당히 중요하기 때문이다. Root Directory 영역에 대해 공부하거나, Data 영역에 파일을 수동으로 생성 할 때 다른 곳을 모두 정상적으로 적용했다고 하더라도 FAT 영역의 클러스터가 맞지 않으면 정상적으로 파일이 열리지 않기 때문이다.

그렇기 때문에 상당히 단순한 구조임에도 확실하게 알고 갈 필요가 있다. 여러분이 공부하는데 이 포스팅이 쉽게 이해되길 빌어본다.


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

Posted by Latte_
,


* 들어가기에 앞서 본 스터디에 사용 된 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)


지난 포스팅을 통해 FAT32 분석을 위한 환경 구성을 진행하였다. 환경 구성이 뭔지 궁금한 독자분들 혹은 아직 구성을 하지 않으신 분들은 바로 전 포스팅(3. FAT32#1)으로 돌아가 환경구성을 진행하면 되겠다. 

환경 구성이 마무리 된 독자들은 상단 추가 필요 Tool의 URL을 타고 들어가 HxD를 다운받아 설치하도록 한다. 실제 업무를 함에 있어서는 HxD로 보는 일이 많지 않고 HxD보다 좋은 도구들이 많이 나와있다. 그러나 그 도구들을 사용함에 있어서 정확한 결과를 내려면 기본에 충실해야 한다. 필자가 본 블로그를 시작하고 포스팅을 함에있어서 가장 우선시했던 부분 역시 바로 '기본' 이다. 


설치한 HxD를 '관리자 권한'으로 실행하도록 하자. 반드시 관리자 권한으로 실행하여야 한다. 일반 사용자로 Disk를 불러오려고 하는 경우 오류메시지를 띄우며 Disk를 불러오지 않는다. 


[그림 .1 HxD를 이용해 Disk 열기]

HxD를 실행한 수 위쪽의 디스크 모양(작은 네모)를 클릭하면 [그림 1]과 같이 디스크 열기 창이 열린다. [디스크 열기] 창은 크게 논리 디스크와 물리 디스크로 구분이 되어있는데 논리 디스크를 선택할 경우 바로 해당 파티션의 Boot Record로 시작한다. 반면 물리 디스크에 속해있는 부분을 선택 할 경우 Master Boot Record부터 시작되게 된다. 마지막으로 '읽기전용으로 열기' 체크를 해지해 주고 수락을 누르면 우리가 원하는 파티션 디스크를 열 수 있다.(물리 디스크에서 선택해야 하는 디스크는 실습 환경에 따라 다를 수 있다.)


이후 보이는 화면은 독자여러분이 이 블로그의 포스팅을 제대로 봤거나, 혹은 다른 경로를 통해서 공부를 했던 기억이 있다면 눈에 익은 화면일 것이다.(기억이 나지 않는다면 http://jh8992.tistory.com/entry/FileSystem-Forensics-FAT32 를 참고하기 바란다.) 물리 디스크 선택을 통해 보이는 가장 첫 화면은 바로 여러분이 선택한 디스크의 Master Boot Record이다. MBR에 대한 설명은 앞서 포스팅을 통해 설명했기 때문에 여기서는 설명하지 않고, 바로 Boot Record 로 넘어가기 위한 내용만 서술 하기로 한다.


[그림 2. VHD의 MBR 구조]

부팅에 필요한 프로그래밍이 포함되어있는 440byte(Boot Code)를 넘어가면 우리가 원하는 파티션 테이블 영역을 확인 할 수 있다. [그림 2]에서 보면 해당 파티션은 부팅은 불가능한 파티션(Bootable Flag Value =0x00)이며 파티션 타입은 0x0B로 FAT32인 것을 알 수 있다. Start LBA Address는 0x80(Dec = 128)로 이 Start LBA Address가 바로 우리가 원하는 파티션의 시작 위치이자 Boot Record의 위치이다. 혼자 개인적으로 하는 공부라면 Start LBA Address만 보고 바로 BR 영역으로 넘어가겠지만, 복습을 위해 마지막 부분인 파티션의 용량도 구해보자.

이 파티션의 전체 크기를 Hex값으로 보면 0x5FE800이 된다. 이를 10진수로 변경하면 6,285,312이 되는데 이는 Size in Sector로 파티션이 사용하는 총 섹터의 '수' 이다. 한 섹터는 512Byte에 크기를 갖는데 앞서 구한 값에 512를 곱하면 전체 파티션의 크기가 나온다. 물론 단위는 byte 값으로 3,218,079,744Byte가 나오는데 이를 보기 편한 GB로 나누기 위해서는 1024로 3번 나누어 주면 된다. 결과를 계산해보면 정확히 3GB로 나누어 떨이지진 않고 2.99GB가 나오는데 반올림 하면 3GB가 된다. (계산 시 주의 할 내용이 있는데, 보통 Hex 값을 위해 프로그래밍 용 계산기를 통해 계산을 진행하는데, 이 경우 10진수 계산 시 소수점 아래자리를 버리기 때문에, 총 Byte 값을 구하고 나면 일반 계산기로 변경 후 계산하도록 한다.)


[그림 3. VHD의 Boot Record 영역]

앞서 [그림 2]에서 계산한 Start LBA Address 값의 Sector로 이동하면 [하드 디스크2]의 Boot Record로 진입하게 된다.(개인의 설정마다 결과값이 다르게 나올 수 있다. 반드시 자신의 Start LBA Address 값으로 이동하기 바란다.)

Boot Record는 해당 볼륨의 여러가지 설정 값들을 저장하고 있으며 볼륨의 첫번째 섹터에 위치하고 있다. 만약 하나의 하드 디스크에 여러개의 파티션(혹은 볼륨)이 있다면 각각의 파티션에 Boot Record가 위치하며, 단일 파티션만 위치할 경우 MBR 영역에 Boot Record가 위치한다. 


 [그림 4. Boot Record에서 필수로 알아야 할 내용]

[그림 4]는 향후 파일복구 혹은 데이터 복구를 위해 반드시 알아야 할 부분 중 하나이다. 가장 윗 줄을 기준으로 순서대로 목록을 정리하면 아래와 같다.

 - Byte Per Sector(섹터 당 Byte 수)

 - Sector Per Cluster

 - Reversed Sector Count

 - Number of FATs

 - Total Sector 32(볼륨 섹터 수)

 - FAT Size 32(FAT 영역의 섹터 수)

Byte Per Sector는 하나의 Sector가 차지하는 Byte 수, 즉 용량을 나타낸다. 따로 설정을 하지 않는다면 Default로 0x200(Dec = 512)로 고정이 되며, 앞서 MBR에서 Size in Sector를 구할 때 512를 곱한 이유가 여기에 있다. 보통은 따로 설정을 하지 않기 때문에 512Byte로 알고 계산을 해도 상관없기는 하지만, 앞서 설명했듯이 "절대"라는 값을 갖는 것은 없다. 따라서 분석을 하거나 복구를 함에 있어 반드시 이 부분을 확인해야 한다.

Sector Per Cluster는 하나의 클러스터가 갖는 섹터의 수를 의미한다. 쉽게 이해시켜주기 위해서 한가지 실습을 해보고자 한다. 지금 메모장을 열고 'test'라는 간단한 단어를 입력 후 저장하자. 영어는 하나의 단어가 1Byte의 값을 가지기 때문에, 방금 생성한 텍스트 파일은 4Byte 값을 가져야 한다. 과연 그런가? 저장된 파일의 용량은 우리의 예상대로 4Byte가 아닌 4KByte가 되는것을 확인 할 수 있다. 왜 우리가 예상한 결과와 다른 값을 가지는가? 그 이유가 바로 이 Sector Per Cluster이다. 

Reversed Sector Count는 시스템을 위해 예약 된 영역이다. 해당 영역은 시스템이 나중을 대비해 비워둔 영역이다.  미래를 위해 비워두었지만, 주 용도는 Boot Record 저장과 주요 항목의 백업이다. 여기서 알 수 있듯이, 예약영역에는 Boot Record가 포함되는데 Boot Record는 예약영역의 가장 앞 Sector에 위치하게 된다.

Number of FATs는 사실 그렇게 중요한 부분은 아니다. 보통 값이 2로 고정되어 있으며 볼륨에 있는 FAT 영역의 수를 표기한다. 1로 표기되어 있어도 Window는 호환성을 보장하기는 한다. 만약 1로 되어있는 경우가 있다면 뒤에 나올 Directory Entry를 갈 때 계산을 조금 달리해야 한다. 대부분은 2로 되어있겠지만.. 세상에 무조건 이라는 내용은 없으니 반드시 확인이 필요한 부분이다.

Total Sector 32는 여러분이 MBR영역에서 확인 한 Size in Sector와 동일한 값을 갖는다. 이 영역은 해당 볼륨이 가지고 있는 섹터의 수를 의미하기 때문에, MBR에서 호가인 한 Size in Sector와 동일 한 값을 가져야 한다.

FAT Size 32는 FAT 영역이 갖는 섹터 수를 의미한다. 그러나 여기서 주의해야 할 점이 하나있다. FAT Size 32는 위의 Number of FATs의 값인 2가 아닌 하나의 FAT 영역이 갖는 섹터 수를 의미한다. 앞서 환경구성에 대한 포스팅을 할 때 간단히 FAT32 구조에 대해서 표기해준 적이 있다. 해당 구조에서 FAT#1, FAT#2로 표기한 것은 각각의 FAT영역을 의미한다.


위에 정리한 주요 6개의 영역을 포함한 나머지 기타 영역은 아래와 같으며, 해당 내용에 대해 간략히 표현에 보도록 하겠다.

[그림 5. Boot Record Structure]


 - Jump Boot Code : Boot code로 넘어가기 위한 코드

 - OEM Name : OEM 회사를 나타내는 문자열(바뀌어도 부팅에는 문제되지 않는다)

 - Byte Per Sector : 1개의 섹터가 가지고 있는 byte 수(Default 설정 시 512byte)

 - Sector Per Cluster : 1개의 클러스터가 가지는 Sector 수

 - Reserved Sector Count : 예약 영역이 가지고 있는 Sector 수

 - Number of FATs  : 볼륨에 존재하는 FAT 영역의 수(Default 2개)

 - Root Directory Entry Count : Root Directory 내에 몇개의 파일 / 디렉토리를 수용할지 기록하는 부분. 

    -> FAT32의 경우 Root Directory 위치가 지정되어있지 않기 때문에 0으로 채워진다.

 - Total Sector 16 : FAT16 파일 시스템에서 볼륨의 섹터 수

   ->FAT32에서는 0으로 기록

 - Media : 해당 볼륨이 이동식미디어 인지 고정식 미디어인지를 구분. 플로피 디스크가 아니라면 0xF8(고정식)이 기록되어 있다.

 - FAT Size 16 : FAT16 파일시스템에서 FAT 영역이 갖는 섹터 수

   -> FAT32에서는 0으로 기록

 - Sector Per Track : Track 당 Sector의 개수를 의미하는데 Window 계열에서는 더이상 참조하지 않는다.

 - Number of Header : 볼륨의 헤더 수를 의미하며 Sector Per Track과 마찬가지로 윈도우에서는 더이상 참조하지 않는다.

 - Hidden Sector : 볼륨 앞의 숨겨진 섹터 수를 의미하며 위와 같이 윈도우에서는 더이상 참조하지 않는다.

 - Total Sector 32 : FAT32 파일시스템에서 해당 볼륨의 전체 섹터 수.

 - FAT Size 32 : FAT32 파일시스템에서 단일 FAT 영역의 섹터 수.

 - Ext Flags : FAT 테이블의 사용 여부 등 여러 설정 값 기록

 - File System Version : FAT의 버전정보를 의미하나 실제로는 0으로 기록

 - Root Directory Cluster : FAT32에서는 Root Directory가 어디에 와도 상관없기 때문에 그 시작위치를 값으로 저장한다.

 - File System Information : 파일 시스템 구조체의 위치를 기록

 - Boot Record Backup Sector : Boot Record의 백업 섹터 위치를 기록한다. 일반적으로 FAT32에서는 6번 섹터를 기록하며 0번 섹터를 기록하면 백업을 하지 않음을 의미한다.

 - Reserved : 예약된 영역으로 항상 0으로 기록

 - Driver Number : Windows 계열에서는 더이상 참조 하지 않는 영역

 - Reserved 1 : Windows NT에서 사용하기 위해 만든 예약영역. 항상 0으로 기록

 - Boot Signature : 확장 부트 서명으로 0x29를 기록.

 - Volume ID : 볼륨의 시리얼 번호

 - Volume Label : 볼륨 레이블을 명시

 - File System Type : 항시 FAT32를 기록


이로서 FAT32의 Boot Record 영역에 대한 정리를 진행했다. 다음 포스팅에서는 FAT32 영역에 대해서 정리해 보도록 한다.


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

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

Posted by Latte_
,

* 들어가기에 앞서 본 스터디에 사용 된 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)


시작하기에 앞서 지금 이 글을 읽고 있는 독자분들이 알고있는 파일시스템에 대해 생각해보자. FAT32, NTFS, HFS, ext2,3,4, ReFS 등 다양하 파일시스템을 알고 있을 것이다. 어떤 파일시스템을 주로 사용하느냐는 여러분이 사용하는 OS에 따라 달라질 것이고, 또는 여러분의 회사에서 사용하는 시스템이 무엇이냐에 따라 달라질 것이다. 

필자는 주로 NTFS를 많이 사용한다. 실제 사용하는 OS가 Window가 많기 때문이다. 실제 일반유저가 사용하는 많은 프로그램중 가장 높은 비중을 차지하는 파일시스템은 아마 Windows 파일시스템일 것이다. 여러가지 프로그램들도 잘 만들어져있고, 무엇보다 금융 거래등을 위해서 꼭 필요한 Active X등을 사용하기 위해서는 Windows OS가 필수로 필요하기 때문이다. 지금부터는  Windows OS의 파일시스템 중 FAT32에 대해 집중적으로 다루려고 한다.


FAT(File Allocation Table)은 디지털 카메라 등에 장착되는 대부분의 메모리 카드와 수많은 컴퓨터 시스템에 사용되는 파일시스템 구조이다. FAT 파일시스템은 1977년 빌게이츠와 마크 맥도널드가 1년간 개발해 만들어 낸 파일시스템 구조로 MS-DOS, DR-DOS, Microsoft Windows를 포함한 다양한 운영체제를 위한 파일 시스템이다. FAT12, FAT16, FAT32, FATX, exFAT 등이 존재하며, 현재 주로 쓰이는 파일시스템은 FAT32이다. 

FAT12는 주로 과거에 많이 쓰이던 MS-DOS 초기에 사용되었고, 이후 플로피 디스크를 사용할 경우 여전히 통용되고 있다. FAT16은 32MB 이상의 하드디스크를 지원하기 위해 사용되었고(당시에는 디스크 및 메모리 사용량이 현재처럼 크지 않았다) Window 95까지는 사용되었다. FAT16은 최대 2GB 까지 용량을 지원한다. 

우리가 이 포스팅부터 다루게 될 FAT32는 2GB 이상의 하드디스크를 지원하기 위해 만들어졌으며 Windows 95 OSR2부터 사용할 수 있게 만들어져있다. FAT32에서 하나의 파일은 최대 4GB -1Byte의 용량을 가질 수 있으며, 하나의 파티션이 최대 8TB의 용량을 가질 수 있다. 그런데 이쯤 되면 하나의 의문이 생길 것이다. 전에 포스팅한 MBR 구조에서 하나의 파티션은 최대 2TB의 크기를 갖는다고 설명했다. 그런데 FAT32 파일시스템은 8TB까지 최대 용량을 갖는다고 한다. 과연 어느게 우선시 되는게 맞는것인가? 

사실 생각해보면 간단하다. 시스템이 구동 될 때, MBR이 먼저 구동되는지 FAT32가 먼저 구동되는지를 알아보면 된다. MBR에 대해 설명할 때 부트코드에는 부팅을 위해 파티션 내 BR(Boot Record)을 호출하는 과정이 프로그래밍 되어 있다고 이야기 했다. FAT32 파일시스템에 대한 정보는 이 BR에 포함되어 있다. 따라서 최대 8TB까지(물리적으로 라면) 지원하는 FAT32라 하더라도 MBR 구조로 되어있는 OS라면 파티션 당 최대 2TB까지만 지원하게 된다.

그리고 이 뒤를 잇는 exFAT나 기타 여러가지 것들이 존재하지만, 실제로는 많이 쓰이지 않으니 이번 포스팅에서는 따로 다루지 않도록 하겠다.


[그림 1. FAT32 구조]


[그림 1]은 FAT32의 전체적인 구조를 보여준다. 하나의 FAT32 파티션은 위와 같은 구조를 가진다. 지금부터 [그림 1]의 세부적인 내용에 대해 하나하나 알아보도록 하자.

세부적으로 알아보기에 앞서, 가상의 FAT32 파티션 하나를 구성해 보도록 하자. 이 내용은 이후 NTFS 파일시스템을 할 때도 동일한 방법으로 이루어질 것이며 이번 포스팅에만 작성 할 것이다. 실제로 한번만 해보면 다시 외울 필요 없을 정도의 내용이니 실습을 통해 숙달하는것을 추천한다.

먼저 실행창(Window 키 + R)을 열어 diskmgmt.msc를 입력한다. 이 명령어는 [디스크 관리] 창을 여는 명령어로 제어판을 통해 찾아 들어가는 방법도 존재하나 매우 번거로우므로 그냥 이 명령어를 기억하고 익숙해지도록 한다. 이후 포스팅을 보고 따라하다보면 상당히 많이 사용하게 될 명령어이다.

 [그림 2. 디스크 관리]

컴퓨터를 사용하다 저장장치를 하나 이상 추가해본 독자라면 한번 이상은 봤을 것으로 생각되는 창이다. 거의 마지막에 하게 될 파일 생성 / 복구 등을 할 때 정말 자주 보게 될 화면이니 잘 기억해두도록 한다. (질리게 해야 할 지도 모른다.)


[그림 3. VHD 만들기 과정#1]

앞으로 자주 사용 될 FAT32 VHD를 하나 만들어 보도록 하자.  먼저 [디스크 관리]에서 동작 -> VHD를 들어가 VHD 생성 탭을 연다. 기존에 만들어둔 VHD가 있다면 VHD 연결을 통해 미리 생성한 VHD를 열어도 상관없다.


[그림 4. VHD 파일 경로 지정 및 크기 지정]

사용할 VHD의 크기 및 경로를 지정해 준다. MB, GB, TB 단위로 지정이 가능하며 원하는 대로 지정할 수 있다.(단 VHD도 하나의 파일로서 크기만큼의 용량을 차지한다.) 본 실습에서는 무난하게 3GB를 지정하였다.

[그림 5. 생성 된 3GB의 VHD 화면]

정상적으로 과정을 완료되었다면 위 붉은 테두리처럼 3GB의 디스크가 생성 된 것을 확인할 수 있다. 다만 현재까지의 과정으로 저 VHD를 바로 사용할 수는 없다. 다음 과정에서 거칠 포멧과정을 거쳐서 정상 Disk로 작동 할 수 있도록 조치할 수 있다.

디스크를 포맷하는 과정을 자세히 설명하지는 않도록하겠다. Forensics를 공부하려는 독자들이라면 간단한 디스크 포맷 지식 정도는 알고 있으리라는 생각도 있지만, 검색을 통해서도 쉽게 찾아 낼 수 있기 때문이다. 다만, 디스크 포맷과 정에서 한가지 주의 해야 할 부분이 있다. 아래 [그림 6]처럼 디스크 포맷 과정 간 파일시스템을 결정하는 부분이 나온다. 이때 Default 값은 NTFS로 되어있는데, 실습을 위해 FAT32로 변경한 후 과정을 진행하도록 한다.


[그림 6. 파티션 포맷 간 FileSystem 설정]


위 과정을 정상적으로 수행했다면 [내 컴퓨터]에 들어갔을 때 방금 생성하 VHD가 정상적으로 접근되는 것을 확인 할 수 있다.


지금까지 FAT32를 본격 분석하기 위한 Setting에 대해 알아보았다. 다음 포스팅부터는 FAT32를 본격적으로 탐구하고 분석하는 시간을 갖도록 하겠다.

Posted by Latte_
,

* 들어가기에 앞서 본 스터디에 사용 된 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)


파일시스템은 현대 모든 운영체제의 기본 구성 요소로 '컴퓨터에서 파일 또는 자료를 쉽게 발견 및 접근할 수 있도록 보관하는 조직 또는 체계'를 의미한다.

파일시스템은 크게 디스크, 네트워크 그리고 특수용도의 파일 시스템으로 나눌 수 있으며, 이번에 다루기 시작해 한동안 다룰 파일 시스템은 FAT32(Window에서 사용되는 파일 시스템. 기존 XP까지 주력 파일시스템으로 사용되었으며 Window7 이후 NTFS를 주력으로 사용 중)이다.


파일시스템 파트는 일단 MicroSoft사 OS인 Window 파일시스템부터 시작할 예정이며 가장 먼저 FAT32로 진행 할 예정이다.


FAT32에 대해 이야기하기 전에, 간단이 짚고 넘어가야 할 부분이 있다. 바로 MBR이다.

Master Boot Record(이하 MBR)은 간단히 말하면 디스크의 정보를 담고 있는 영역을 말한다. 모든 디스크의 시작 지점(0번 Sector)부터 512Byte의 크기를 가지고 있으며, 그 안에는 Master Boot Code와 Partition Table Area, 그리고 Signature를 포함하고 있습니다.

  * 아래 그림에 대한 실제 실습 과정은 다음 FAT32 파트에서 다루도록 한다.

<그림 1. MBR 구조>


위와 같이 크게 세 부분으로 구분되어있는 MBR은 전체 512 Byte 중 대부분을 부트코드로 채우고 있다. 또한 파티션 테이블(그림 1의 Partition Area)를 가지고 있는데, 이는 MBR의 가장 최종목표가 바로 부팅임을 알려주고 있다. 


MBR에서 가장 많은 영역을 차지하는 부분은 부트코드인데 440Byte 크기를 차지하고 있다. 부트코드는 부팅을 위해 파티션 내의 BR을 호출하는 과정이 프로그래밍 되어있으며 이를 위한 파티션 테이블 확인, 그리고 각 파티션의 부팅가능 여부를 확인하는 루틴이 들어있다. 또한 디스크의 정상여부를 판단해 예외처리를 진행하며 최종적으로 Start LBA(Logical Block Addressing, 논리 블록 어드레스)를 계산하여 해당 파티션의 Boot Record를 호출함으로서 그 임무를 다하게 된다.

어떻게 보면 전체 섹터에서 그렇게 큰 부분을 차지하지는 않는 부트코드지만 이 부분이 문제가 있을경우 PC가 정상적으로 부팅이 되지 않기 때문에 가장 중요한 부분이라고 보면 되겠다.


그다음으로 중요하게 봐야 할 부분은 파티션 테이블 영역이다. 총 64 Byte의 크기를 가지고 있는 파티션 테이블은 개당 16 Byte씩 총 4개의 파티션  테이블을 차례로 갖는다. 각 파티션에 대한 자세한 내용은 아래서 더 다루어 보기로 한다.

이름

 Bootable Flag

offset

 0

Size

1 Byte 

 Value

   0x80(부팅가능)     0x00(부팅불가) 

설명 

부팅 가능한 파티션임을 나타내는 Flag로 4개의 파티션 중 1개 이상에 0x80 Flag가 존재하면 부팅이 가능하다. 

이름

 Starting CHS Address

offset

 1~3

Size

3 Byte 

 Value

  가변적인 값

설명 

CHS 모드로 표현하는 파티션의 시작 번지로 현재는 거의 사용하지 않는다. 현재 사용되는 거의 대부분의 OS는 LBA 모드를 이용하고 있으며 이로인해 이부분이 0으로 채워져도 아무런 문제가 없다.

이름

 Partition Type

offset

 4

Size

1 Byte 

 Value

0x07(NTFS)
 0x0B(FAT32 CHS mode)
 0x0C(FAT32 LBA mode)

설명 

파티션 타입을 표현한 값으로 현재까지 나온 파티션들은 각각의 고유 값을 가지고 있다. 이 글에서 모든 파티션 타입을 다 다루지는 않을 예정이며 주로 많이 쓰이는 파티션 타입은 Value값을 참고하기 바란다.

이름

 Ending CHS Address

offset

 5~7

Size

3 Byte 

 Value

가변적인 값

설명 

CHS 모드로 표현하는 파티션의 끝 번지. Start CHS Address와 같이 현재는 거의 사용하지 않으며 마찬가지로 0으로 채워져도 부팅에는 아무런 문제가 없다.

이름

 Start LBA Address

offset

 8~11

Size

4 Byte 

 Value

가변적인 값

설명 

LBA 모드로 표현하는 파티션의 시작 번지. 현존하는 거의 대부분의 OS는 LBA 모드로 파티션을 사용하고 있다. 

이름

 Size in Sector

offset

 12~15

Size

4 Byte 

 Value

가변적인 값

설명 

파티션이 사용하는 Sector의 총 개수를 의미하며, 하나의 Sector는 512 Byte(Default value)이므로 파티션의 총 용량은 Size in Sector * 512가 된다.






<표 1. 파티션 영역 세부 분석>


[표 1]을 보다보면 CHS 부분은 현재는 거의 사용하지 않으며, 0으로 채워도 부팅에는 지장이 없다고 설명해 놓았다. 필자가 분석가는 아니지만, 많은 분들이 실제로 딱히 저부분은 크게 알 필요가 없다고 말하기도 하고, 어느경우는 무시하고 바로 LBA만 보라고 하는 경우도 있다. (필자도 여태까지 공부하면서 CHS 부분을 봐본적은 사실 없다.) 

물론 위에 말한 내용이 '요새 설정에 있어서'는 맞는 말이기는 하다. 여러분이 사용하는 OS의 파일 시스템 대부분이 LBA 모드를 사용하고 있기 때문이다. 그러나 잊지 말았으면 하는점이 있다. IT에 있어서, 아니 세상에 있어서 '절대' 라는 것은 단 하나밖에 존재하지 않는다. 바로 '생명은 태어나면 반드시 언젠간 죽음을 맞이한다는 것' 이다. 즉, 그 이외의 모든것들은 언제나 항상 맞는것은 아니라는 점이다. 

여러분이 분석을 진행하다 보면 대부분의 확률로 LBA 모드의 파일 시스템을 보게 될 것이다. 그러나 CHS 모드나 LBA 모드를 결정하는 것은 전적으로 어플리케이션이다. 함부로 단정짓지 않길 바란다. 여기에 기술하지는 않겠지만 인터넷을 찾아보면 각각의 파티션 타입을 설명해 놓은 글이 존재한다. 그리고 그것들은 단순히 파티션의 종류만 설명해 놓은 것이 아닌 CHS 모드인지 LBA 모드인지 역시 함께 서술해 놓고 있으니 참고하며 공부하길 권한다.

위 내용을 토대로 각각의 파티션별 디스크 최대 인식 용량을 구해보도록 하자.

위의 [그림 1]을 다시 한번 보면 MBR 내 파티션 테이블 영역은 0x1BE부터 0x1FD까지 총 64 byte를 차지하고 있다. 그리고 그 안에서 각각의 파티션은 16 Byte씩 최대 4개의 파티션을 가질 수 있다. 또한 각 파티션의 Size는 [표 1]의 Size in Sector 부분을 참고하면 찾을 수 있다. 

총 4 Byte의 크기를 가지고 있는 이 영역의 Max 값을 쉽게 표현해 보자. 16진수는 2의 4승만큼의 값을 가진다. 그런데 4 Byte의 값을 가지는 Size in Sector는 총 8개의 16 진수 값을 가질 수 있다. 즉, 최대의 개수는 2의 4승이 8개가 있다는 의미이기 때문에 2의 32승만큼의 섹터 값을 가진다. 

일반적인 파일시스템의 경우 섹터당 512 Byte의 값을 가진다. 그러면 Size in Sector 값과 512를 곱해줄 경우 해당 파티션의 용량이 구해지는데 최대 용량의 경우 가장 높은 값은 2의 32승 * 512(2,199,023,255,552 Byte)가 된다. 이것을 이제 1024로 지속적으로 나누게 되면 Byte -> KByte -> MByte -> GByte -> TByte 순이 된다. 

이렇게 계산할 경우 계산되는 MBR 구조에서 각각의 파티션 별 디스크 최대 인식 용량은 2TB가 된다. 이는 MBR 구조의 큰 단점 중 하나인데, 과거에는 파일별 용량이 크지 않았으나 상관이 없었으나, IT가 발전되면서 프로그램의 용량이 늘어남에 따라 곧 한계가 올 것으로 보인다. 

이를 해결하기 위해 나온 구조가 GPT구조이다. 나중에 기회가 되면 따로 설명하겠지만, GTP구조는 MBR의 구조적 문제를 해결하기 위해 만들어진 구조로 2TB 이상의 파티션도 인식 가능하다는 장점이 있다.


이상으로 파일시스템 중 FAT32에 들어가기에 앞서 기본 베이스가 될 수 있는 MBR구조에 대해 알아보았다. 다음 포스팅부터는 FAT32에 대해 자세히 알아보도록 한다.


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

Posted by Latte_
,