본문 바로가기

File System

디렉터리 엔트리 분석 [Directory Entry Analysis] - SFN, LFN

디렉터리 엔트리는 Windows의 FAT 파일시스템에서 파일의 이름, 확장자, 위치, 크기등을 표현하기 위한 구조체입니다.

하나의 파일 및 디렉터리는 각각의 메타정보를 표현하기 위해 하나의 디렉터리 엔트리를 가집니다.

 

FAT(File Allocation Table) 파일 시스템의 FAT 영역 뒤에 오는 루트 디렉터리을 살펴 보면 최상위 디렉터리에 존재하는 파일들의 디렉터리 엔트리를 확인할 수 있습니다.

 

파일의 메타 정보를 저장하는 디렉터리 엔트리의 구조는 32바이트 이며 구조 먼저 확인해 보면 아래와 같습니다.

 

SFN File Structure Layout

위와 같은 구조를 가지는 파일을 SFN 이라고 이야기 합니다.

SFN File 이란 Short File Name 의 약자로 파일명이 8바이트 이하인 파일을 이야기 합니다.

 

7바이트를 초과한 파일들은 SFN 파일이 아닌 LFN 파일을 사용합니다.

LFN File 이란 Long File Name 의 약자로 파일명이 8바이트를 초과한 파일을 이야기합니다. 

 

위에 있는 File Structure 는 SFN(Short File Name) 파일 구조 이기 때문에 SFN 파일을 먼저 알아 보겠습니다.

 

실제로 USB를 FAT File System으로 포맷후에 파일명이 7바이트인 파일을 하나 만든후에 위의 파일 구조랑 대조 해 보겠습니다.

Create SFN Example File(File Name 7byte)

SFNFile.txt 라는 파일을 만들고 아래와 같이 내용을 적어 줬습니다.

View SFNFile.txt Contents

이제 Hex값을 확인해 보겠습니다.

앞서 FAT16 FileSystem Structure 을 분석해 봤기 때문에 바로 Root Directory 에 가보겠습니다.

 

1. SFN(Short File Name) Structure - 32 bytes

SFN File Structure Layout

위의 파일구조는 SFN File 의 구조로 32바이트 입니다.

 

실제 파일의 Hex값을 확인해 보면 아래와 같습니다.

Example SFN File Structure Hex Data

이제 위의 구조에 맞춰서 한번 어떤 값들을 의미 하는지 알아 보겠습니다.

[참고로 앞전에 FAT16 FileSystem Structure Analysis  에서 SFN File 은 다룬 적이 있습니다.]

 

1.1 SFN(Short File Name) Structure - File Name

SFN File Structure - File Name(Smaller than 7 bytes) 

0x00 ~ 0x07은 File Name이 있는 필드 이다.

기본적으로는 아스키 코드값이 들어 있지만 0x00 offset 에 특수한 값이 들어 있는 경우가 존재합니다.

어떠한 경우에 0x00에 특수한 값이 들어가는지 확인해 보겠습니다.

└ 0x00 : 파일이름이 사용된 적이 없음

└ 0xe5 : 파일이 이미 삭제 되었지만 파일의 이름은 확인이 가능한 상태

└ 0x05 : 파일명의 첫번째 문자가 'σ' 인 경우 ('σ' 의 아스키 코드 값이 0xe5 이기 때문에 0x05로 표기됨)

 

1.2 SFN(Short File Name) Structure - File Extension

SFN File Structure - File Extension

0x08 ~ 0x0A 은 파일의 확장자가 들어있는 공간입니다.

확장자가 없는 파일이라면 0x202020으로 채워 집니다.

 

1.3 SFN(Short File Name) Structure - File Attribute

SFN File Structure - File Attribute

0x0B는 파일의 속성을 의미합니다.

해당 offset에 들어가는 값은 아래와 같습니다.

└ 0x01 : 읽기 전용 파일

└ 0x02 : 숨긴 파일

└ 0x04 : 운영체제 시스템 파일

└ 0x08 : 속성값 대신 디스크 볼륨 레이블을 포함한 엔트리를 나타냄

└ 0x10 : 서브 디렉터리를 가짐 (= 디렉터리 파일)

└ 0x20 : 일반 파일

 

1.4 SFN(Short File Name) Structure - Reserved Area

SFN File Structure - Reserved Area

이 영역은 예약된 영역입니다.

 

1.5 SFN(Short File Name) Structure - Time Stamp Data

SFN File Structure - Time Stamp Data

표시한 부분을 순서대로 확인해 보면 아래와 같습니다.

Create Time : 생성 시간(0xB842)

Create Date : 생성 날짜(0x504A)

Last Accessed Date : 마지막 접근 날짜(0x504A)

Last Written Time : 마지막 수정 시간(0xB851)

Last Written Date : 마지막 수정 날짜(0x504A)

 

각각의 Time Stamp 에서는 2바이트의 크기를 가지게 됩니다.

변환 방법은 2가지가 있는데 시간 과 날짜로 나눌수 있습니다. 시간은 Create Time을 예시로 변환을 하고, 날짜는 Create Date을 예시로 변환을 해보겠습니다.

 

먼저 시간 변환을 해보겠습니다.

0xB842 를 2진수로 변환을 해보면 아래와 같습니다.

0xB842 = 1011 1000 0100 0010 입니다.

 

5비트(hhhhh) / 6비트(mmmmmm) / 5비트(sssss)로 나눠 보면 아래와 같이 나눌 수 있습니다.

10111 / 000010 / 00010 로 변환이 가능합니다.

23시 02분 02초 로 해석이 가능합니다.

하지만 실제 폴더의 속성을 확인해 보면 만든 시간이 하루가 지나지 않아서 5분 전으로 나오는 것을 알 수 있습니다

 

SFN File Structure - Create Time View

5분 전이라고 나오는데 글을 작성하는 현재 시각은 23시 07분 이기 때문에 얼추 맞습니다.

 

여기서 HEX값으로 시간을 구했을때 23시 02분 02초로 해석이 됬지만 실제 속성에서는 23시 02분 04초로 나올것입니다.

그 이유는 60초 를 계산 하려면 최소한 6비트는 사용을 해야 하지만 시간에서 5비트 , 분에서 6비트를 사용하기 때문에 남은 5비트로 초를 계산 해야합니다

그렇기 때문에 기존의 초에서 절반의 값을 5비트에 담아서 계산을 하는 것입니다.

 

이번에는 날짜를 한번 해석해 보겠습니다.

0x504A 을 2진수로 바꾸면 아래와 같습니다.

0x5043 = 0101 0000 0100 1010 입니다.

 

날짜는 시간과 달리  7비트(yyyyyyy) / 4비트(mmmm) / 5비트(ddddd)로 나눠야 합니다.

0101000 / 0010 / 01010 로변환이 가능합니다.

 

40 / 2 / 10 으로 나오는데 년도 부분이 조금 이상하다는 것을 알 수 있습니다.

그 이유는 년도에서 -1980 한 값이 들어있기 때문입니다.

 

그렇기 때문에 재대로 계산을 해보면 2020 / 2 / 10 으로 해석을 하면 정확하게 나옵니다.

SFN File Structure - Create Date View

1.6 SFN(Short File Name) Structure - Starting Cluster

SFN File Structure - Starting Cluster

0x14 ~ 0x15 와 0x1A ~ 0x1B 에는 Starting Cluster 값이 들어 있습니다.

위의 값을 확인해 보면 0x00000006 인것을 확인 할 수있고, 해당 파일 내용는 6번째 클러스터에 있다는 것을 알 수 있습니다.

 

클러스터는 FAT 영역이 끝나고 데이터 영역(Root Directory)부터 시작됩니다.

먼저 Root Directory 의 시작 섹터는 480 섹터 였습니다.

Root Directory의 시작 섹터인 480섹터 + 32섹터 = 512섹터가 클러스터2번이면서 Data Area의 시작 주소입니다.

 

그 이후부터 다음 클러스터의 섹터 값은 Reserved Area 에서 0x0D에서 표현된 Sector Per Cluster의 값에 따라 정해집니다.

FAT File System Reserved Area - Sector Per Cluster

0x40 = 64 이므로 클러스터 3번은 512 섹터 + 64섹터 인 576섹터 입니다.

그렇다면 앞서 SFNFile.txt의 파일내용은 클러스터 5번 위치에 있다고 했기 때문에 

 

512섹터(2번) + ((6-2)*64섹터) = 512섹터 + 256섹터 = 768섹터에 존재 하게되는 것입니다.

SFN File Structure - File Contents Data

앞서 본 파일의 내용과 일치 하는 것을 알 수 있습니다.

 

1.7 SFN(Short File Name) Structure - File Size

SFN File Structure - File Size

위에서 본 파일 처럼 0x11 인 17바이트 인것을 알 수 있습니다.

 

이처럼 File Name 이 7바이트 이하인 파일인 SFNFile.txt 의 구조인 SFN File에 대해서 한번 알아 보았습니다.

이번에는 파일이름이 엄청 길다면 어떻게 파일을 저장하는지 보도록 하겠습니다.

 

Create LFN Example File(File Name 16byte)
View digital forensic.txt Contents

2. LFN(Long File Name) Structure - (32 * N) bytes

 

일단 파일 구조를 그린 Layout을 보기 전에 Hex값을 먼저 살펴 보겠습니다.

Example LFN File Structure Hex Data

앞에서 본 SFN의 구조는 0x3C100 ~ 0x3C11F 까지 있는것 같습니다.

이를 미루어 볼때 LFN File은 아래와 같은 구조를 띄는 것 같습니다.

LFN File Structure Simple Layout

LFN File Structure 은 파일 이름의 길이가 길어질수록 추가되는 형식의 구조인것 같습니다.

 

위의 예시 파일인 digital forenisc.txt 파일은 LFN File 2개와 SFN File 1개로 구성되어 있습니다.

 

일단 SFN File 에서 뭐가 달라졌는지 확인해 보겠습니다.

LFN File Structure - SFN File Name

파일 이름에서 6바이트만 출력되고 ~1이 붙어서 대체 된것을 알 수 있습니다.

 

이제 LFN File Structure 에 대해서 알아 보겠습니다.

예시 파일의 구조가 LFN - LFN - SFN 구성으로 되어 있기 때문에 그것을 기준으로 해보겠습니다.

 

LFN File Structure Detail Layout

이제 위의 구조에 맞춰서 앞에서 본 Hex값들이 무엇을 의미 하는지 알아 보겠습니다.

 

2.1 LFN(Long File Name) Structure - Sequence Number(Status Byte)

LFN File Structure - Sequence Number(Status Bytes)

마지막 LFN 구조에 들어있는 값은 해당 LFN 파일 구조의 개수를 의미합니다.

 

위의 구조에서는 LFN 파일 구조가 2개 이기 때문에 0x40 XOR 0x2를 해서 0x42 라는 값이 들어가 있는 것입니다.

마지막 LFN 구조의 Sequence Number만 0x40과 XOR을 하고 나머지 LFN 파일의 Sequence Number는 그냥 0x1을 시작으로 순차적으로 증가 합니다.

 

이처럼 마지막 LFN 파일에 있는 Seq Num 값은 존재하는 LFN File Structure의 개수를 의미합니다.

 

또다른 예시를 보기 위해서 a 30개를 파일명으로 하는 파일을 하나 만들어 봤습니다.

Example LFN File Structure - Sequence Number(Status Bytes)

LFN 파일이 3개 이기 때문에 0x01 , 0x02 그리고 0x40 XOR 0x03 = 0x43 으로 표시가 됩니다.

 

또한 하나의 LFN 파일 구조에는 13바이트의 파일명이 들어가기 때문에 13바이트를 초과하면 LFN 파일의 개수가 하나씩 늘어나게 됩니다.

 

2.2 LFN(Long File Name) Structure - FileName #1,2,3,4,5 ...

LFN File Structure - File Name(#1,2,3,4,5 ...)

파일 명이 2바이트에 1글자씩 들어있는 것을 확인 할 수 있습니다.

앞에서 말한거 처럼 1개의 LFN 파일구조에는 13바이트의 글자가 들어가게 됩니다.

 

2.3 LFN(Long File Name) Structure - Attribute

LFN File Structure - Attribute

항상 이값은 0x0F 를 가지고 있습니다.

 

2.4 LFN(Long File Name) Structure - Reserved Area(Type)

LFN File Structure - Reserved Area(Type)

이부분은 예약된 영역으로 Type을 나타내기도 하는데 매번 0x00 으로 채워져 있습니다.

 

2.5 LFN(Long File Name) Structure - CheckSum

LFN File Structure - CheckSum

이 부분은 SFN에 존재하는 파일명에 대응하는 값이 CheckSum 값으로 채워지게 됩니다.

CheckSum 값은 아래와 같은 코드(로직)를 통해서 값이 정해지게 됩니다.

def CheckSum(string):
	sum = 0
	check = 0
	for i in range(0, len(string)):
		check = 0x80 if (check & 1) esle 0
		sum = check + (sum >> 1)
		sum = sum + ord(string[i])
		if sum >= 0x100:
			sum = sum - 0x100
		check = sum
	return sum

if __name__ = "__main__":
	string = input("LFN 파일에 있는 파일명을 적어주세요(Ex. DIGITA~1TXT) : ")
	print(hex(CheckSum(string)))

앞서 말한것과 위의 코드를 보아 LFN File일때의 파일 명과 확장자에 따라서 CheckSum을 구하게 됩니다.

 

Seq Num, File Name, Attribute Value, Type, CheckSum 중 어떠한 값이라도 잘못된 값이 들어가면 LFN File Structure가 인식이 되지 않습니다.

 

2.6 LFN(Long File Name) Structure - First Cluster Low

LFN File Structure - First Cluster Low

First Cluster Low는 해당 파일의 내용이나 해당 디렉터리의 하위 데이터 들이 있는 클러스터 번호을 가지고 있습니다.

 

해당 파일은 txt 파일이기 때문에 5번 클러스터에 파일내용이 들어 있다는 것을 의미 합니다.

 

N번 클러스터의 섹터값을 구하는 방법은 많이 다뤄봤기 때문에 생략을 해보면 5번 클러스터인 704번 섹터에 가보면 파일 내용을 확인 할 수 있습니다.

Example LFN File Structure - File Contents

SFN 과 LFN 파일의 구조를 한번 알아 보았습니다.

클러스터나 섹터를 구하는 법만 알면 File System 파일만 가지고도 Root Directory을 시작으로 트리구조로 디렉터리 및 파일을 찾을 수 있다는 것을 알수 있습니다.

 

위에서 다룬 내용은 아스키코드에 한정되어 있지만 한글로 작성한 파일명은 유니코드를 다룹니다.

유니코드는 2바이트가 1글자로 이루어지기 때문에 값을 구할때 0xD3EC 와 같이 값을 변환 하면 될 것 같습니다.

0xD3EC 는 '포' 라는 글자의 유니코드 값입니다.

 

유니코드를 이용한 LFN 파일도 구조는 동일 하기 때문에 생략하겠습니다!