본문 바로가기

My Study/Programming&Theory

NTFS : MFT 요소 값 구하기 2가지 방법

요새 파일 시스템 공부를 쫌 해보고 있는데 NTFS 쪽은 정말 멘붕할 것 같다. 으악!


NTFS 관련 구조는 구글에 치면 너무나 많은 자료가 나오기 때문에 따로 구조를 설명하진 않겠다.


========================= MFT Entry 구하기 1 =========================

MBR(Master Boot Record) 에서 Index 446 위치부터 파티션 테이블이 존재한다.



위 그림은 Harddisk0 (전 그냥 하드 ㅠ_ ㅠ)에 대한 내용을 봐본 것이다.

하나의 파티션 테이블 엔트리는 16Byte로 이루어져 있다. 현재 내 컴퓨터는 3개의 파티션이 있는것을 알 수 있다. 아래 그림은 증거다. 믿어라!



Harddisk1은 외장하드다 =_=;;


아무튼 저 파티션 테이블에서 C드라이브의 VBR 위치를 찾아야한다.

그림으로부터 C드라이브는 파티션 테이블에서 두번째 엔트리 라는 것은 알고 있다.



위 그림의 위치가 바로 C드라이브의 VBR가 있는 곳의 섹터 번호이다. ( 206848 )


이제 C드라이브의 VBR를 왔다. 파란색 부분은 VBR에 boot code로 점프하는 부분과 boot code 부분을 뺀 부분이다. 저 부분에 해당 볼륨에 대한 정보들이 들어있다. 내부적으로 섹터당 바이트 수 클러스터당 바이트 수 등등 필요한 정보들이 많지만 일단 다 건너뛰고 우리는 MFT(Master File Table) 의 위치를 찾아가야한다. 해당 위치를 뒤져야 디스크 상에 존재하는 파일들의 속성 정보들을 알 수 있기 때문이다. 위 그림에서 빨간색 네모친 위치에 StartOfMFT 값이 존재한다. ( 0xC0000 )


하지만 저건 섹터 위치가 아니고 클러스터 Index이다. 그리고 기준 위치는 MBR이 아닌 VBR이기 때문에 MFT의 섹터 위치는 다음과 같이 구하면 된다.


VBR 섹터 위치 + (StartOfMFT * 클러스터당 섹터 수)


그 위치로 가보자.



제대로 찾아왔다. 파란색으로 나온 부분은 MFT Entry header (42Byte) 이다.

그리고 MFT Entry는 1개당 크기가 1KB 이므로 두 섹터 씩 건너뛰면 원하는 MFT Entry 위치를 구할 수 있다. 

파일 시스템 책에 나와있는 예제 코드는 다음과 같이 구하고 있었다.



HDD_read는 물리 "\\\\.\\PhysicalDriveX" 이름을 갖는 디바이스의 핸들을 얻고 파일 포인터를 옮긴다음 해당 영역에서 원하는 블럭 개수 만큼 데이터를 얻어온다.


이제 MFT Entry를 얻었으니 MFT header를 분석해 각각의 속성들을 뽑아내고 데이터를 읽어가면 된다. 이 부분은 생략 다음번에 포스팅을 해보도록 하겠다.


========================= MFT Entry 구하기 2 =========================

위 과정을 직접 따라가보고 코딩을 해봤지만 뭔가 찝찝한 부분이 있다. 바로 MBR의 파티션 테이블에서 C드라이브의 위치를 알아내는 과정이다. 아무 정보도 없는 상태에서 파티션 테이블만 보고 어떠한 파티션이 C드라이브인지 알 수 있을까?? 아직 내가 모르는 것 같지만 아무튼 내 머리속엔 없다.( 있다면 알려주세요 ㅠ ㅠ )


그래서 툴을 찾아보니 nfi.exe 라는 툴이 있다.



프로그램을 실행 전 인자로 드라이브 이름을 주면 해당 드라이브의 MFT를 전부 분석해 각각의 내용들을 보여주는 프로그램이다. 보면 드라이브 이름만 입력 받고 있다. 내가 원하는 부분이 바로 저 프로그램 내부에 구현이 되어 있을 것이다.

그래서 리버싱을 시작했다. +_+


리버싱 과정은 보여줄 필요가 없으므로 생략한다.


아무튼 리버싱 후 대략 어떻게 구현되어 있는지 파악하였다. 해당 내용을 토대로 드라이브 이름을 입력 받고 해당 드라이브에서 원하는 MFT Entry를 구하는 코드를 작성해보았다.



코드는 그렇게 깔끔한 편은 아니므로 참고만 하면서 다시 짜면 좋을 것 같다.



잘 얻어온다. ㅎㅎ



그리고 코드 상에서 위와 같은 부분이 있는데 저기서 liMFTIndex 변수에 MFT Entry 요소 번째를 지정할 수 있다.


그리고 첫번째 방법보다 장점은 원하는 드라이브의 MFT를 구할 수 있는 것도 있지만 특정 MBR->VBR->MFT 이동하면서 Offset 계산을 해야하는 번거로움 없이 nt 함수로 그냥 원하는 MFT Entry를 얻어올 수 있다는게 큰 장점이다.


NTFS는 너무 어렵다!! 악악 그래도 잼있네 ㅎㅎ 파일 시스템 공부를 하다보니 포렌식이 땡긴다 = _ =ㅋㅋ