반응형

ZIP 파일 형식이란 데이터를 압축, 보관하기 위한 파일형식이다. ZIP 파일은 하나 혹은 여러 개의 파일들을 그 크기를 줄여 압축하고 하나로 묶어 저장한다. ZIP 파일 형식에서는 다양한 종류의 압축 알고리즘의 사용이 가능하나, 2009년 현재 Deflate 알고리즘만이 가장 많이 사용되고 지원되는 압축 알고리즘이다.

파일 형식은 1989년 필 캐츠가 PKZIP에서 사용하기 위해 만들어진 것으로, Thom Henderson의 ARC 파일 압축 형식을 발전시킨 것이다. 현재도 PKZIP 형식은 PKZIP뿐만 아닌 다른 많은 유틸리티 소프트웨어에서 지원하고 있다. 마이크로소프트사는 1998년도부터 "압축 폴더"라는 이름으로 운영 체제에 포함시켜 지원하고 있으며, 애플사는 맥 오에스 텐 10.3버전부터 지원하고 있다.

ZIP 파일은 일반적으로 그 파일의 확장자로 ".zip" 혹은 ".ZIP"으로 사용하고, MIME 형식으로는 application/zip으로 표시하여 사용한다. 또한 다양한 소프트웨어에서 파일 저장 형식으로 사용되고 있으나, 그럴 경우 일반적으로 그 파일의 확장자가 다른 형태로 저장된다. 예를 들어, 자바의 경우 .jar 로, 모질라 파이어폭스의 애드온의 경우 .xpi로, 이드 소프트웨어사의 .pk3/.pk4 파일이 그러하며, 윈앰프 윈도 미디어 플레이어의 스킨 파일들과 오픈오피스 오픈도큐먼트 파일인 .odt와 마이크로소프트사의 Open XML 파일 형식인 .docx, 안드로이드의 애플리케이션 파일인 .apk도 그러하다.

https://ko.wikipedia.org/wiki/ZIP_(%ED%8C%8C%EC%9D%BC_%ED%8F%AC%EB%A7%B7)



집(Zip) 파일의 구조는 간략하게 위와 같이 나타낼 수 있다. 굉장히 심플한 구조를 나타내고 있으나 추가된게 많아져서 조금 복잡해졌다고 한다.

Zip 파일을 읽게되면 순서는 대략적으로 아래와 같이 나타 낼 수 있다.


① 최초 실행시 End of Central Directory로 이동한다.

② End of Central Directory에서 정보를 읽는다.

③ End of Central Directory에서 Central Directory위치로 이동한다.

④ Central Directory에서 정보를 읽는다.

⑤ End of Central Directory에서 Central Directory의 개수만큼 반복하여 End of Central Directory전까지 읽는다.

⑥ Central Directory에서 읽은 Local Header 위치로 차례대로 접근한다.

⑦ Local Header에서 정보를 읽고 해당되는 File Data를 압축해제한다.

⑥ ~ ⑦을 Local Header의 개수 만큼 반복한다.


※ 자세히 알아보기전에 이 내용에는 Little-Endian이 중구난방인 상태이므로 Little-Endian을 알고 가는게 좋겠다.

    https://ko.wikipedia.org/wiki/%EC%97%94%EB%94%94%EC%96%B8


이제 좀 더 자세히 알아보자. 

① 최초 실행시 End of Central Directory로 이동한다.

  - 파일이 실행이 되면 먼저 맨 마지막으로 이동하여 앞으로 차례대로 이동하면서 Signature를 읽게 된다. 그러긴 위해선 먼저 End of Central Directory의 구조를 알아보자.

임의

Offset

Bytes

Description[25]

1.

0

4

End of central directory signature = 0x06054b50

2.

4

2

The number of this disk (containing the end of central directory record)

3.

6

2

Number of the disk on which the central directory starts

4.

8

2

Number of central directory records on this disk

5.

10

2

Total number of central directory records

6.

12

4

Size of central directory (bytes)

7.

16

4

Offset of the start of the central directory on the disk on which the central directory starts

8.

20

2

The length of the following comment field

9.

22

n

Comment

End of Central Directory의 구조는 위와 같이 구성 되어 있다. 아래의 예제를 통해서 하나씩 설명해보겠다.





1. 0x504B0506 : End of Central Directory의 Signature로써 이 값을 가진다면 이 부분은 End of Central Directory가 된다.

2. 0x0000 : 분할 파일일 때 현재 디스크 번호이다. 최대 0xffff를 가질 수 있다.

3. 0x0000 : 분할 파일일 때 Central Directory가 시작되는 disk 번호

4. 0x0002 : 이 디스크에 있는 Central Directory records의 개수 

5. 0x0002 : Central Directory records의 총 개수

6. 0x00000074 : Central Directory records의 크기

7. 0x00014495 : Directory records의 시작 offset 0x11495 = Byte 83093  (분할 압축일때는 해당 디스크 기준으로)

8. 0x0000 : 파일 Comment의 길이

9. NULL : 파일에 Comment가 없으므로 나타나지 않음.


② End of Central Directory에서 정보를 읽는다.

따라서 위의 예제의 End of Central Directory 정보는 아래와 같다.

End of Central Directory

Signature

'\x50\x4b\x05\x06'.

Disk Number

0

Disk # w/cd

0

Disk entries

2

Total entries

2

Central directory size

116Bytes

Offset of cd wrt to starting disk

83093Bytes

Comment len

0

ZIP file comment

NULL


③ End of Central Directory에서 Central Directory위치로 이동한다.

  - End of Central Directory에서 얻은 정보로 Central Directory 위치로 이동하게 된다.


  - 정보를 읽기 위해서 먼저 Central Directory의 구조를 파악해보자. 

임의

Offset

Bytes

Description[25]

1.

0

4

Central directory file header signature = 0x02014b50

2.

4

2

Version made by

3.

6

2

Version needed to extract (minimum)

4.

8

2

General purpose bit flag

5.

10

2

Compression method

6.

12

2

File last modification time

7.

14

2

File last modification date

8.

16

4

CRC-32

9.

20

4

Compressed size

10.

24

4

Uncompressed size

11.

28

2

File name length (n)

12.

30

2

Extra field length (m)

13.

32

2

File comment length (k)

14.

34

2

Disk number where file starts

15.

36

2

Internal file attributes

16.

38

4

External file attributes

17.

42

4

Relative offset of local file header. This is the number of bytes between the start of the first disk on which the file occurs, and the start of the local file header. This allows software reading the central directory to locate the position of the file inside the .ZIP file.

18.

46

n

File name

19.

46+n

m

Extra field

20.

46+n+m

k

File comment


Central Directory의 구조는 위와 같이 구성 되어 있다. 아래의 예제를 통해서 하나씩 설명해보겠다.



1. 0x504B0102 : Central Directory의 Signature이다.

2. 0x0014 : 압축 생성시 Version 정보이다. 아래의 표를 참고하여 VFAT인 것을 알 수있다.

Byte

Version

Byte

Version

0

MS-DOS and OS/2

(FAT/VFAT/FAT32)

11

MVS(OS/390-Z/OS)

1

Amiga

12

VSE

2

OpenVMS

13

Acorn Risc

3

UNIX

14

VFAT

4

VM/CMS

15

alternate MVS

5

Atari ST

16

BeOS

6

OS/2 H.P.F.S

17

Tandem

7

Machintosh

18

OS/400

8

Z-System

19

OS/X(Darwin)

9

CP/M

20-255

unused

10

Windows NTFS

 


3. 0x0014 : Version needed to extract로써 압축 해제할 때 필요한 버전이다. 여기선 0x14 = 십진법 20 = 2.0 version이 되게 된다. 버전에 따른 정보는 아래의 표를 참고한다.

Version

value

Version

value

1.0

Default value

5.0

File is encrypted using 3DES

1.1

File is a volume label

5.0

File is encrypted using original RC2 encryption

2.0

file is a folder(directory)

5.0

File is encrypted using RC4 encryption

2.0

file is compressed using Deflate compression

5.1

File is encrypted using AES encryption

2.0

File is encrypted using traditional PKWARE encryption

5.1

File is encrypted using corrected RC2 encryption**

2.1

File is compressed using Deflate64(tm)

5.2

File is encrypted using corrected RC2-64 encryption**

2.5

File is compressed using PKWARE DCL Implode

6.1

File is encrypted using non-OAEP key wrapping***

2.7

File is a patch data set

6.2

Central directory encryption

4.5

File uses ZIP64 format extensions

6.3

File is compressed using LZMA

4.6

File is compressed using BZIP2 compression

6.3

File is compressed using PPMd+

5.0

File is encrypted using DES

 

6.3

File is encrypted using Blowfish

 

 

6.3

File is encrypted using Twofish


4. 0x0000 : Flag값으로써 아래의 표를 참고하여 정보를 알 수 있다. 아래의 표를 통해 encrypted file인것을 알 수 있다.

Bit

Purpose

Bit

Purpose

Bit 00

encrypted file

Bit 06

strong encryption

Bit 01

compression option

Bit 07 ~ 10

unused

Bit 02

compression option

Bit 11

language encoding

Bit 03

data descriptor

Bit 12

reserved

Bit 04

enhanced deflation

Bit 13

mask header values

Bit 05

compressed patched data

Bit 14 ~ 15

reserved


5. 0x0008 : Compressed method = 압축이 어떤 방법을 사용했는지 알 수 있다. 아래의 표를 참고하여 deflated를 사용함을 알 수 있다. 대부분의 기본 zip 파일의 압축 방법은 deflated를 따른다.

Byte

Method

 Byte

Method

0

no compression

10

PKWare DCL

imploded

1

shrunk

11

reserved

2

reduced with compression factor 1

12

compressed using

BZIP2

3

reduced with compression factor 2

13

reserved

4

reduced with compression factor 3

14

LZMA

5

reduced with compression factor 4

15 ~ 17

reserved

6

imploded

18

compressed using

IBM TERSE

7

reserved

19

IBM LZ77 z

8

deflated

98

PPMd version l, Rev 1

9

enhanced deflated

 

 


※ Deflated 알고리즘 : DEFLATE는 기본적으로 LZ77 알고리즘을 통해 데이터를 압축한 뒤, 중복되는 내용에 대한 포인터(일치하는 내용의 위치와 길이) 허프만 부호화를 사용하여 한 번 더 압축한다.

DEFLATE 알고리즘은 일반적으로 그 압축률에 비해 압축/해제 속도가 빠르나, 나중에 나온 압축 알고리즘에 비해서는 압축률이 다소 떨어지는 경향이 있다.

LZ77 알고리즘 = http://uzys2011.tistory.com/152

허프만 부호화 = http://wooyaggo.tistory.com/95


6. 0xBCA2 : 파일의 최종 수정시간이 된다.

① BCA2 -> A2BC : little endian이기때문에 순서를 바꿔준다. 

② A 2 B C를 이진법으로 나타낸다.

      A      2       B     C 

    1010, 0010, 1011, 1100

③ 1010001010111100 :이진법으로 나타낸 것을 다 이어 붙인다.

④ (10100)01010111100 : 괄호안에 있는 값을 10진법으로 바꾼 값이 시간이 된다. (앞에서 5bits)  = 20(Hour)

⑤ 10100(010101)11100 : 괄호안에 있는 값을 10진법으로 바꾼 값이 분이 된다. (이어서 6bits) = 21(Minutes)

⑥ 1010001010(111100) : 괄호안에 있는 값을 10진법으로 바꾼 값에 *2를 하면 초가 된다. (이어서 6bits) = 28 * 2 = 56(Seconds)

⑦ 20:21:56에 이 파일이 최종 수정이 되었다는 것을 알 수 있다.

Bits

Means

Bits

Means

Bits 00~04

seceonds divided by 2

Bit 11~15

hour

Bits 05~10

minute

Stored in standard MS-DOS format


7. 0xDA48 : 파일의 최종 수정날짜가 된다.

① DA48 -> 48DA : little endian이기 때문에 순서를 바꿔준다.

② 4 8 D A를 이진법으로 나타낸다.

       4      8      D      A

    0100, 1000, 1101, 1010

③ 0100100011011010 : 이진법으로 나타낸 것을 다 이어 붙인다.

④ (010010)0011011010 : 괄호안에 있는 값을 10진법으로 바꾼 값에 1980을 더하면 년도가 된다.(앞에서 6bits) = 36 + 1980 = 2016(Year)

⑤ 0100100(0110)11010 : 괄호안에 있는 값을 10진법으로 바꾼 값이 월이 된다. (이어서 4bits) = 6(Month)

⑥ 01001000110(11010) : 괄호안에 있는 값을 10진법으로 바꾼 값이 날이 된다. (이어서 5bits) = 26(Day)

⑦ 2016/6/26에 이 파일이 최종 수정이 되었다는 것을 알 수 있다.

Bits

Means

Bits

Means

Bits 00~04

day

Bit 09~15

years from 1980

Bits 05~08

month

Stored in standard MS-DOS format


8. 0x087b1295 : CRC-32로써 전송시에 파일이 제대로 갔는지 확인해주는 값이다.

  CRC 정보 https://ko.wikipedia.org/wiki/%EC%88%9C%ED%99%98_%EC%A4%91%EB%B3%B5_%EA%B2%80%EC%82%AC


9. 0x0B440100 : Compressed size로 압축된 파일 크기를 의미한다.

① 0x0B440100 -> 0x0001440B : Little-Endian이기 때문에 순서를 바꿔준다.

② 82955Bytes : 0x001440B를 10진법으로 바꾸면 82955 Bytes가 나온다.


10. 0xDCAC0100 : Uncompressed size로 압축되기 전 파일 크기를 의미한다.

① 0xDCAC0100 -> 0x0001ACDC : Little-Endian이기 때문에 순서를 바꿔준다.

② 109788 Bytes : 0x0001ACDC를 10진법으로 바꾸면 109788 Bytes가 나온다.


11. 0x0008 : File name length으로 파일 이름 길이를 나타낸다.


12. 0x0008 : Extra field length으로 엑스트라 필드의 길이를 의미한다.


13. 0x0000 : File comment length으로 파일 코맨드의 길이를 의미한다.


14. 0x0000 : 이 파일이 시작되는 디스크의 수


15. 0x0001 : 파일의 내부 속성이다 아래의 표를 참고한다.

Bit

Means

Bit

Means

Bit 0

apparent ASCll / text file

Bit 2

control field records precede logical records

Bit 1

reserved

Bit 3~16

unused


16. 0x00000020 : 파일의 외부 속성이다. Host-System에 영향을 받으며 Version Made by를 참고한다.


※ 14, 15, 16에 대한 설명이 부족한거 같아서 아래의 정보를 추가한다. 정확히 어떻게 해석해야하는지 감이 안온다.


17. 0x00000000 : 제일 처음의 Local Header의 Relative Offset을 나타낸다. 00000000이므로 00000000의 위치가 Local Header 1의 위치가 된다.


18. 0x313131312E4A5047 : 파일의 이름이다.


19. 18.에 이어서 0x504B0506앞까지 : Extrafield 와 Filecomment가 있다.


④ Central Directory에서 정보를 읽는다.

    따라서 위의 예제의 Central Directory의 정보는 다음과 같다.

 Central Directory

Signature

'\x50\x4b\x01\x02'.

Version

0x14 = VFAT

Version needed

0x14 = 20 -> 2.0

Flags

00 = Encrypted file

Compression method

08 = deflated

File modification time

(10100)01010111100 = 20(Hours)

10100(010101)11100 = 21(Minutes)

10100010101(11100)= 28*2=56(Seconds)

= 20:21:56

File modification date

(0100100)011011010 = 36(Year) + 1980 = 2016

0100100(0110)11010 = 6(Month)

01001000110(11010) = 26(Day)

= 2016/6/26

Crc-32 checksum

0x087b1295

Compressed size

0001440B = 82955Bytes

Uncompressed size

0001ACDC = 109788Bytes

File name length

0008 -> 8Bytes

Extra field length

0008 -> 8Bytes

File comment length

0000 -> 0Bytes

Disk # start

0000 -> 0

Internal attributes

Bit 1 = Reserved

External attributes

0x20

Offset of local header

0000

File name

111.jpg

Extra field

0x7A E5 04 00 B5 03 00 00

File comment

 


⑤ End of Central Directory에서 Central Directory의 개수만큼 반복하여 End of Central Directory전까지 읽는다.


⑥ Central Directory에서 읽은 Local Header 위치로 차례대로 접근한다.

  - Local Header의 정보는 Central Directory의 부분집합이 된다. 그러므로 Central Directory에 있는 정보로 Local Header의 정보를 거의 다 알 수 있다.

  - 그래도 Central Directory와 구조가 약간 다르니 구조를 알아보자.

Offset

Bytes

Description[25]

0

4

Local file header signature = 0x04034b50 (read as a little-endian number)

4

2

Version needed to extract (minimum)

6

2

General purpose bit flag

8

2

Compression method

10

2

File last modification time

12

2

File last modification date

14

4

CRC-32

18

4

Compressed size

22

4

Uncompressed size

26

2

File name length (n)

28

2

Extra field length (m)

30

n

File name

30+n

m

Extra field

Central Directory와 거의 유사하다. 단지 Version , file commend length, disk #start, internal attr, external attr, Offset of local header를 제외하고 signature만 다를 뿐 나머지는 다 똑같다. 


⑦ Local Header에서 정보를 읽고 해당되는 File Data를 압축해제한다.

위의 예제 기준으로 Local Header의 정보는 아래와 같이 정리 할 수 있다.

 Local Header #1

Signature

'\x50\x4b\x03\x04'.

Version

0x14 = 20 -> 2.0

Flags

00 = Encrypted file

Compression method

08: deflated

File modification time

(10100)01010111100 = 20(Hours)

10100(010101)11100 = 21(Minutes)

10100010101(11100)= 28*2=56(Seconds)

= 20:21:56

File modification date

(0100100)011011010 = 36(Year) + 1980 = 2016

0100100(0110)11010 = 6(Month)

01001000110(11010) = 26(Day)

= 2016/6/26

Crc-32 checksum

0x087b1295

Compressed size

0001440B = 82955Bytes

Uncompressed size

0001ACDC = 109788Bytes

File name length

0008 -> 8Bytes

Extra field length

0008 -> 8Bytes

File name

111.jpg

Extra field

0x7A E5 04 00 B5 03 00 00

이러한 정보들을 이용하여 file #에 있는 파일을 해독하여 압축을 하거나 풀게된다.


⑧ ⑥ ~ ⑦을 Local Header의 개수 만큼 반복한다.




⑨ 맺으며

  -   Extra field가 어떤 역할을 하는지 좀 더 알아봐야 될 듯하나 영향을 크게 주는 부분인거 같지는 않다. 

  -  시작되는 디스크의 수나 internal attr나 external attr이 정확히 어떻게 정해지는지 잘 모르겠다.

  -  마지막으로 2010년도에 반디집 만들었던 사람이 요약해둔 파일을 첨부한다. 매우 간략하게 되어있고 좀 더 신빙성 있으신 분의 글이므로 많은 참고가 될 듯 싶다.           

       ZIP 포맷.xlsx                 <http://kippler.tistory.com/91>



< 참고 자료 >

http://www.softlab365.com/wordpress/?p=478


https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html


https://en.wikipedia.org/wiki/Zip_(file_format


https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기