您的位置:首页 > 其它

zip 文件格式分析: 附实例介绍

2017-05-19 18:32 656 查看

zip 文件格式分析: 附实例介绍

ZIP format

Byte order: Little-endian

Overall zipfile format:

[Local file header + Compressed data [+ Extended local header]?]*

[Central directory]*

[End of central directory record]

1. Local file header & Extended local header

1.1 Local file header

Offset   Length   Contents
0      4 bytes  Local file header signature (0x04034b50)
4      2 bytes  Version needed to extract
6      2 bytes  General purpose bit flag
8      2 bytes  Compression method
10      2 bytes  Last mod file time
12      2 bytes  Last mod file date
14      4 bytes  CRC-32
18      4 bytes  Compressed size (n)
22      4 bytes  Uncompressed size
26      2 bytes  Filename length (f)
28      2 bytes  Extra field length (e)
(f)bytes  Filename
(e)bytes  Extra field
(n)bytes  Compressed data


1.2 Extended local header:

Offset   Length   Contents
0      4 bytes  Extended Local file header signature (0x08074b50)
4      4 bytes  CRC-32
8      4 bytes  Compressed size
12      4 bytes  Uncompressed size


2. Central directory:

Offset   Length   Contents
0      4 bytes  Central file header signature (0x02014b50)
4      2 bytes  Version made by
6      2 bytes  Version needed to extract
8      2 bytes  General purpose bit flag
10      2 bytes  Compression method
12      2 bytes  Last mod file time
14      2 bytes  Last mod file date
16      4 bytes  CRC-32
20      4 bytes  Compressed size
24      4 bytes  Uncompressed size
28      2 bytes  Filename length (f)
30      2 bytes  Extra field length (e)
32      2 bytes  File comment length (c)
34      2 bytes  Disk number start
36      2 bytes  Internal file attributes
38      4 bytes  External file attributes
42      4 bytes  Relative offset of local header
46     (f)bytes  Filename
(e)bytes  Extra field
(c)bytes  File comment


2.1 compression method: (2 bytes)

0 - The file is stored (no compression)
1 - The file is Shrunk
2 - The file is Reduced with compression factor 1
3 - The file is Reduced with compression factor 2
4 - The file is Reduced with compression factor 3
5 - The file is Reduced with compression factor 4
6 - The file is Imploded
7 - Reserved for Tokenizing compression algorithm
8 - The file is Deflated


3. End of central directory record:

Offset   Length   Contents
0      4 bytes  End of central dir signature (0x06054b50)
4      2 bytes  Number of this disk
6      2 bytes  Number of the disk with the start of the central directory
8      2 bytes  Total number of entries in the central dir on this disk
10      2 bytes  Total number of entries in the central dir
12      4 bytes  Size of the central directory
16      4 bytes  Offset of start of central directory with respect to the starting disk number
20      2 bytes  zipfile comment length (c)
22     (c)bytes  zipfile comment


单看上面的介绍不会有多少印象,也可能不知道它在说什么,

下面以一个android 的apk 来举例分析, 它包含289个文件,文件大小7.4M,是个真枪实弹的东西。

看完实例,结合上面介绍,就理解了数据结构!

我把central directory 翻译为中央目录, 为什么这么翻译呢?

因为目录区是一块连续的区域(由一系列pk0102区块构成),位于文件的尾部。

但最后的文件尾部由(pk0506)占据

文件前部是一系列pk0304开头+压缩数据+pk0708结尾的区域。

所以可以说目录区算中央。

原来我把它翻译为核心,后来觉得没有”核心”这个意思,由翻译为”中心”,也觉得不妥,

还是觉得中央目录或者中部目录更贴贴吧,或者简单就叫目录,个人之见!

先说说最尾部目录,

这个东西是全局唯一的,位置在尾部,因此特别重要。

结构长度:22 bytes

举例:

0761e70: 6c61 7368 5f68 2e6a 7067 504b 0506 0000  lash_h.jpgPK....
0761e80: 0000 2101 2101 2a54 0000 50ca 7500 0000  ..!.!.*T..P.u...


它的signature 是0x50,0x4b,0x05,0x06

后面2byte: 0x00,0x00 //当前磁盘编号,现在都不用了,

后面2byte: 0x00,0x00 //中央目录开始的磁盘编号,现在都不用了,

后面2byte: 0x21,0x01 //小端序,实际为0x0121,下同. 该磁盘的中央目录个数

后面2byte: 0x21,0x01 //0x0121, 中央目录结构总数, 现在硬盘时代,数值跟上面一样了。

后面4byte: 0x2a,0x54,0x00,0x00 //0x542a, 中央目录大小

后面4byte: 0x50,0xca,0x75,0x00 //0x75ca50, 中央目录的偏移

后面4byte: 0x00,0x00 //注释长度为0

可见它交代了中央目录的大小和位置,也告诉了你中央目录的个数。

再看看0x75ca50处中央目录数据: 大小0x542a

075ca50: 504b 0102 1400 1400 0800 0800 7965 d344  PK..........ye.D
075ca60: ebde ad91 221f 0000 785b 0000 1400 0000  ...."...x[......
075ca70: 0000 0000 0000 0000 0000 0000 0000 4d45  ..............ME
075ca80: 5441 2d49 4e46 2f4d 414e 4946 4553 542e  TA-INF/MANIFEST.
075ca90: 4d46 504b 0102 1400 1400 0800 0800 7965  MFPK..........ye
075caa0: d344 b39e 168c 5421 0000 f15b 0000 1200  .D....T!...[....
075cab0: 0000 0000 0000 0000 0000 0000 641f 0000  ............d...
075cac0: 4d45 5441 2d49 4e46 2f55 4e49 434f 4d2e  META-INF/UNICOM.
075cad0: 5346 504b 0102 1400 1400 0800 0800 7965  SFPK..........ye
075cae0: d344 efc7 cd57 ed0b 0000 fe12 0000 1300  .D...W..........
075caf0: 0000 0000 0000 0000 0000 0000 f840 0000  .............@..
075cb00: 4d45 5441 2d49 4e46 2f55 4e49 434f 4d2e  META-INF/UNICOM.
075cb10: 5253 4150 4b01 0214 0014 0008 0008 0078  RSAPK..........x
075cb20: 65d3 4444 e759 a3b6 0500 00e0 1300 0013  e.DD.Y..........
075cb30: 0004 0000 0000 0000 0000 0000 0026 4d00  .............&M.
075cb40: 0041 6e64 726f 6964 4d61 6e69 6665 7374  .AndroidManifest
075cb50: 2e78 6d6c feca 0000 504b 0102 1400 1400  .xml....PK......
075cb60: 0800 0800 7865 d344 ........ (忽略)


每个结构长度46bytes,

signature: 0x50,0x4b,0x01,0x02

后边2btes: 0x14,0x00 //压缩时的版本

后边2btes: 0x14,0x00 //解压缩需要的最低版本

后边2btes: 0x08,0x00 //通用位标记

后边2btes: 0x08,0x00 //压缩方法标记

后边2btes: 0x79,0x65 //文件修改时间

后边2btes: 0xd3,0x44 //文件修改日期

后边4btes: 0xeb,0xde,0xad,0x91 //crc-32

后边4btes: 0x22,0x1f,0x00,0x00 //压缩后大小

后边4btes: 0x78,0x5b,0x00,0x00 //未压缩大小

后边2btes: 0x14,0x00 //文件名长度

后边2btes: 0x00,0x00 //扩展域长度

后边2btes: 0x00,0x00 //文件注释长度

后边2btes: 0x00,0x00 //磁盘号开始,已经不用了

后边2btes: 0x00,0x00 //内部文件属性

后边4btes: 0x00,0x00,0x00,0x00 //外部文件属性

后边4btes: 0x00,0x00,0x00,0x00 //本地文件头的相对偏移

META-INF/MANIFEST.MF //文件名

每一个目录项对应一个文件,记录了压缩,解压的版本,压缩方法。

文件日期,时间,文件名,文件大小,压缩大小,文件偏移地址,crc32等

下一个中央目录记录:

signature: 0x50,0x4b,0x01,0x02

后边2btes: 0x14,0x00 //压缩时的版本

后边2btes: 0x14,0x00 //解压缩需要的最低版本

后边2btes: 0x08,0x00 //通用位标记

后边2btes: 0x08,0x00 //压缩方法标记

后边2btes: 0x79,0x65 //文件修改时间

后边2btes: 0xd3,0x44 //文件修改日期

后边4btes: 0xb3,0x9e,0x16,0x8c //crc-32

后边4btes: 0x54,0x21,0x00,0x00 //压缩后大小

后边4btes: 0xf1,0x5b,0x00,0x00 //未压缩大小

后边2btes: 0x12,0x00 //文件名长度

后边2btes: 0x00,0x00 //扩展域长度

后边2btes: 0x00,0x00 //文件注释长度

后边2btes: 0x00,0x00 //磁盘号开始,已经不用了

后边2btes: 0x00,0x00 //内部文件属性

后边4btes: 0x00,0x00,0x00,0x00 //外部文件属性

后边4btes: 0x64,0x1f,0x00,0x00 //本地文件头的相对偏移

META-INF/UNICOM.SF //文件名

下同…… 忽略

第一个目录提到了,文件头偏移位置为0

第二个目录提到了,文件头偏移位置为0x1f64,

下面分析一下中央目录所指向的数据:

0000000: 504b 0304 1400 0800 0800 7965 d344 0000  PK........ye.D..
0000010: 0000 0000 0000 0000 0000 1400 0000 4d45  ..............ME
0000020: 5441 2d49 4e46 2f4d 414e 4946 4553 542e  TA-INF/MANIFEST.
0000030: 4d46 b57c c9ae db58 b2ed bc80 fa87 1cbe  MF.|...X........


本地文件头结构: 30bytes

signature: 0x50,0x4b,0x03,0x03

后边2btes: 0x14,0x00 //解压缩时的最低版本

后边2btes: 0x08,0x00 //通用位标记

后边2btes: 0x08,0x00 //压缩方法标记

后边2btes: 0x79,0x65 //文件修改时间

后边2btes: 0xd3,0x44 //文件修改日期

后边4btes: 0x00,0x00,0x00,0x00 //crc-32

后边4btes: 0x00,0x00,0x00,0x00 //压缩后大小

后边4btes: 0x00,0x00,0x00,0x00 //未压缩大小

后边2btes: 0x14,0x00 //文件名长度

后边2btes: 0x00,0x00 //扩展域长度

META-INF/MANIFEST.MF + zipData

可见本地文件头和目录结构信息是有冗余的。

此时压缩后大小,未压缩大小还是0 在本地扩展头中会填充

.....
0001f50: cffa f7bf 504b 0708 ebde ad91 221f 0000  ....PK......"...
0001f60: 785b 0000 504b 0304 1400 0800 0800 7965  x[..PK........ye


注意:在本地文件尾部我们看到了PK0708,这是本地扩展头,由12byte组成

signature: 0x50,0x4b,0x07,0x08

后边4btes: 0xeb,0xde,0xad,0x91 //crc-32

后边4btes: 0x22,0x1f,0x00,0x00 //压缩后大小

后边4btes: 0x78,0x5b,0x00,0x00 //未压缩大小

我们看到一个本地头加上一个扩展本地头可以构成一个中央目录项.

再分析一下第二个文件:

0001f50: cffa f7bf 504b 0708 ebde ad91 221f 0000  ....PK......"...
0001f60: 785b 0000 504b 0304 1400 0800 0800 7965  x[..PK........ye
0001f70: d344 0000 0000 0000 0000 0000 0000 1200  .D..............
0001f80: 0000 4d45 5441 2d49 4e46 2f55 4e49 434f  ..META-INF/UNICO
0001f90: 4d2e 5346 957c c7b2 a3d8 b66d ff46 dc7f  M.SF.|.....m.F..


本地文件头结构: 30bytes

signature: 0x50,0x4b,0x03,0x03

后边2btes: 0x14,0x00 //解压缩时的最低版本

后边2btes: 0x08,0x00 //通用位标记

后边2btes: 0x08,0x00 //压缩方法标记

后边2btes: 0x79,0x65 //文件修改时间

后边2btes: 0xd3,0x44 //文件修改日期

后边4btes: 0x00,0x00,0x00,0x00 //crc-32

后边4btes: 0x00,0x00,0x00,0x00 //压缩后大小

后边4btes: 0x00,0x00,0x00,0x00 //未压缩大小

后边2btes: 0x12,0x00 //文件名长度

后边2btes: 0x00,0x00 //扩展域长度

META-INF/UNICOM.SF + zipData

至此,压缩的数据格式就分析清楚了,至于压缩算法,

如上述9种,实际7种, 就不在本帖之内了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: