1. 서론

apk 파일은 Zip파일에서 확장된 형태로 Zip파일과 동일한 구조를 같습니다. apk의 구조를 알아보기 위해 Zip파일 구조를 알아보았습니다. 


2. 본론

Zip 파일은 여러 개의 파일이 압축(혹은 압축되지 않은)되어 묶여 있는 파일이며 각 파일에 대한 내용이 담긴 헤더(Local file header)가 있고 이 헤더를 위한 각각의 헤더(Central Directory header)가 있으며 이 헤더들을 위한 끝판왕 헤더(End of Central Directory header)로 살펴볼 수 있습니다. 말로 풀어 이해가 잘 안되지만 그림으로 살펴보면 아래와 같습니다.

   

zip file 개요


2.1 ) End of Central Directory

End of Central Directory는 파일의 맨 마지막에 위치하고 있으며, 위에서 언급했 듯 Central Directory의 정보(시작 offset, 전체 Central Directory사이즈 등)를 가지고 있습니다. 즉, Zip파일 구조를 뜯어보려면 제일 먼저 End of Central Directory를 찾으면서 시작해야합니다. 하지만 End of Central Directory의 크기는 file comment때문에 가변적이고, 시작점을 단번에 찾기는 쉽지 않습니다. 

file comment는 End of Central Directory의 맨 마지막에 위치하고, file comment를 제외한 상위 바이트들의 사이즈는 22바이트입니다. 따라서 file comment가 존재하지않는 경우 파일의 끝에서부터 22바이트 떨어진 지점 부터 End of Central Directory가 시작됩니다. End of Central Directory가 시작되는지 확인하기 위해서는 4바이트를 읽어 signature(0x06054B50)와 일치하는지 확인해여 확인 할수 있습니다. 

종합해보면 End of Central Directory를 찾는 과정은 다음 처럼 생각해 볼 수 있습니다.

1) 파일 맨 끝에서부터 22바이트 떨어진 지점으로 파일포인터를 이동한다.

2) 해당 지점에서 4바이트를 읽는다.

3) signature와 일치하는지 확인한다.

4) 일치하지 않는 경우 파일의 상위로 파일포인터를 감아가면서 2) ~ 3)의 과정을 반복한다.


      end of central dir signature    4 bytes  (0x06054b50)
      number of this disk             2 bytes
      number of the disk with the
      start of the central directory  2 bytes
      total number of entries in the
      central directory on this disk  2 bytes
      total number of entries in
      the central directory           2 bytes
      size of the central directory   4 bytes
      offset of start of central
      directory with respect to
      the starting disk number        4 bytes
      .ZIP file comment length        2 bytes
      .ZIP file comment       (variable size)

End of Central Directory 구조


End of Central Directory의 시작점을 찾았다면 위에 서술된 구조를 참조하여, 차례대로 읽어드리면됩니다.

참고 : http://stackoverflow.com/questions/8593904/how-to-find-the-position-of-central-directory-in-a-zip-file

End of Central Directory에서 Central Directory들의 첫 시작 offset을 읽어 파일포인터를 이동시킴으로써 Central Directory를 읽을 수 있습니다.


2.2) Central Directory

Central Directory는 zip파일에 포함된 파일들의 정보를 가지고 있는 Local header의 정보(Local header의 offset, 파일명, 압축사이즈 등)를 가지고있습니다. End of Central Directory에서 얻은 offset을 통해 Central Directory들의 첫 시작 주소를 찾았다면, 이 또한 역시 4바이트를 읽어 signature(0x02014B50)와 비교하여 검증을 해볼 수 있습니다.  일치 하지 않는다면, 위에서 offset을 잘못찾은 것입니다. 

Central Directory들은 연속되어 존재합니다. 

ex) 첫 번째 파일의 Central Directory -> 두 번째 파일의 Central Directory -> ....... -> N 번째 파일의 Central Directory

Central Directory의 구조는 아래와 같습니다.

 central file header signature          4 bytes  (0x02014b50)
        version made by                 2 bytes
        version needed to extract       2 bytes
        general purpose bit flag        2 bytes
        compression method              2 bytes
        last mod file time              2 bytes
        last mod file date              2 bytes
        crc-32                          4 bytes
        compressed size                 4 bytes
        uncompressed size               4 bytes
        file name length                2 bytes
        extra field length              2 bytes
        file comment length             2 bytes
        disk number start               2 bytes
        internal file attributes        2 bytes
        external file attributes        4 bytes
        relative offset of local header 4 bytes

        file name (variable size)
        extra field (variable size)
        file comment (variable size)

Central Directory 구조


Central Directory역시 파일명, extra field, file comment등의 가변 크기의 변수를 갖지만 사이즈를 가지고 있으므로, 읽는데 어려움은 없습니다. file comment의 끝에 바로 다음 Central Directory가 시작 되기 때문에 다음 Central Directory의 offset이 따로 존재 하지 않는 것으로 추측됩니다.

Central Directory에서 local header offset을 얻었으면 비로소 실제 파일에 접근 할 수 있는 local header에 도달할 수 있습니다.


2.3) Local file header

Local file header는 파일의 0번부터 시작하며, 순차적으로 N번째 파일까지 이어집니다.

Local file header에는 Zip파일 내부에 존재하는 각 파일에 대한 정보들(파일 명, 압축 메서드 정보, crc-32 등)을 가지고 있습니다.

Local file header뒤에는 압축에 암호화가 되어있는 경우와 암호화가 되어있지 않은 경우로 뒤에 위치하는 데이터가 다릅니다.

암호화가 되어있는 경우에는 encryption header가 뒤에 온 후 file data(압축 되어있거나 압축되지 않은)

암호화가 되어 있지 않은 경우에는 바로 file data가 오게 됩니다.

      local file header signature     4 bytes  (0x04034b50)
      version needed to extract       2 bytes
      general purpose bit flag        2 bytes
      compression method              2 bytes
      last mod file time              2 bytes
      last mod file date              2 bytes
      crc-32                          4 bytes
      compressed size                 4 bytes
      uncompressed size               4 bytes
      file name length                2 bytes
      extra field length              2 bytes

      file name (variable size)
      extra field (variable size)

Local file header 구조


3. 결론

Zip파일 구조를 파악하기 위해 가장 중요한 세 가지 헤더를 알아보았는데, 아직 부족한 점이 많습니다.

encryption 여부를 파악하여 실제 file data를 찾아내는 방법, file data뒤에 이어지는 file description파트, zip64에 따른 내용 등

Zip파일 전체 구조를 확실히 파악하기 위해서는 조금 더 연구를 해보아야 할 것 같습니다.

개인적으로는 한글 자료가 상세하게 되어있는 것이 없어서 짦은 영어끈으로 머리 싸매가며 연구해본 첫 경험이라 매우 뜻깊었습니다.


참고

1) 위에 분석 방법을 C로 개발한 프로젝트를 git hub에 올려두었습니다.

링크 : https://github.com/uisooshin/ZipAnalyzer

2) 위 내용은 아래의 링크에 상세 내용이 있습니다.

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



+ Recent posts