zip 文件格式分析: 附实例介绍
2017-05-19 18:32
656 查看
zip 文件格式分析: 附实例介绍
ZIP formatByte 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种, 就不在本帖之内了。
相关文章推荐
- IOS 基础媒体文件格式语法描述和语意(MP4文件格式分析实例)
- 压缩文件格式介绍zip, rar, gz, tar.gz, tgz, bz2, Z, tar等
- BMP文件格式实例分析
- FLV文件格式——实例分析
- PHP文件缓存内容保存格式实例分析
- 【云解压】ZIP 文件格式分析-偏移计算和文件大小表示ZIP32 ZIP64
- AVI文件格式实例分析
- elf文件格式实例分析
- ZIP文件格式分析
- zip文件格式分析
- PHP文件缓存内容保存格式实例分析
- 以一个wav文件为实例分析wav文件格式
- FLV文件格式分析实例
- BMP文件格式实例分析
- excel(xls),doc,ppt,xml.zip,rar,pdf,jpeg等各种文件格式相关开源项目介绍
- ELF可执行格式文件实例分析
- java class 文件格式分析及实例完全标注
- 标准CSV格式的介绍和分析以及解析算法实例详解
- Icon文件格式分析
- SQLite数据库文件格式分析(B树的基本组织)