创建一个flag.txt,内容为blog.yakumoran.top,并用7z压缩为zip,密码为123546,以下学习内容均以该zip为对象,以下学习内容适用于单个原文件大小不超过4g
zip实体文件头(Local File Header)
以下为实体文件头内容
| 偏移 | 偏移(hex) | 字节数 | 字段名称 |
|---|---|---|---|
| 0 | 0 | 4 | 签名 |
| 4 | 0x4 | 2 | 版本 |
| 6 | 0x6 | 2 | 通用位标志 |
| 8 | 0x8 | 2 | 压缩方法 |
| 10 | 0xA | 2 | 文件最后修改时间 |
| 12 | 0xC | 2 | 文件最后修改日期 |
| 14 | 0xE | 4 | CRC32校验 |
| 18 | 0x12 | 4 | 压缩后大小 |
| 22 | 0x16 | 4 | 压缩前大小 |
| 26 | 0x1A | 2 | 文件名称长度(n) |
| 28 | 0x1C | 2 | 扩展字段长度(m) |
| 30 | 0x1E | n | 文件名称 |
| 30+n | 0x1E+n | m | 扩展字段 |
以flag.zip为例

0x0~0x3字节固定为50 4B 03 04
0x4~0x5字节为14 00,为最低解压所需zip版本,这里为1.4
0x6~0x7字节为01 00通用位标识符,按小段存储转为二进制为 0000 0000 0000 0001,其中每一位二进制都代表一种信息,详细可以参考下表。示例zip只有bit0有内容为1意思就是压缩包加密
| 位编号(bit) | 含义 | 说明 |
|---|---|---|
| 0 | 加密标志 | 1为加密,0为未加密 |
| 1–2 | 压缩选项 | 对应压缩算法的附加选项 |
| 3 | 数据描述符标志 | 1 = CRC32、大小字段在数据后(Data Descriptor)而不是头部 |
| 4 | 增强压缩标志 | 仅用于 Deflate,指示采用更高的压缩算法 |
| 5 | 压缩方式 | 由特定算法定义 |
| 6 | 压缩方式 | 由特定算法定义 |
| 7 | 保留 | 未使用 |
| 8 | 文件名编码标志(UTF-8) | 1 = 文件名与注释字段使用 UTF-8 编码 |
| 9 | 强加密标志 | 1 = 使用 PKWare Strong Encryption |
| 10–11 | 压缩选项扩展 | 与压缩方式相关(如 AES) |
| 12 | 压缩补充标志 | 与 bzip2 等算法相关 |
| 13 | 加密头数据存在 | 一般在 AES 加密时设置 |
| 14–15 | 保留 | 通常为 0 |
0x8~0x9字节为00 00表示压缩算法,0为不压缩,常见的压缩算法包括:8 (Deflate)最常用的 ZIP 压缩方式,9 (Deflate64)改进版 Deflate,12 (BZIP2)压缩率较高,速度较慢,14 (LZMA)高压缩率,7-Zip 使用的核心算法,20 (Zstandard)现代高性能算法,ZIP 6.3+ 引入
0xA~0xB字节为3A 83表示文件最后修改时间,使用DOS 时间格式,这里为16时25分52秒
0xC~0xD字节为59 5B表示文件最后修改日期,使用DOS 时间格式,这里为2025.10.25
0xE~0x11字节为F4 25 20 07为压缩前源文件的crc32校验
0x12~0x15字节为26 00 00 00为压缩后大小0x26字节
0x16~0x19字节为1A 00 00 00为压缩前大小0x1A字节
0x1A~0x1B字节为08 00 为文件名称长度
0x1C~0x1D字节为00 00 为拓展字段长度
0x1E~0x25字节为66 6C 61 67 2E 74 78 74,共8字节,即为1A~1B所表示的长度,内容按ASCII进行转义极为flag.txt
之后的内容就是文件压缩后的内容
中心目录区(Central Directory)
以下为中心目录区的内容
| 偏移 | 偏移(hex) | 字节数 | 名称 |
|---|---|---|---|
| 0 | 0x0 | 4 | 签名 |
| 4 | 0x4 | 2 | 制作版本 |
| 6 | 0x6 | 2 | 需要的解压版本 |
| 8 | 0x8 | 2 | 通用位标志 |
| 10 | 0xA | 2 | 压缩方式 |
| 12 | 0xC | 2 | 文件最后修改时间 |
| 14 | 0xE | 2 | 文件最后修改日期 |
| 16 | 0x10 | 4 | CRC-32 校验 |
| 20 | 0x14 | 4 | 压缩后大小 |
| 24 | 0x18 | 4 | 未压缩大小 |
| 28 | 0x1C | 2 | 文件名长度 |
| 30 | 0x1E | 2 | 额外字段长度 |
| 32 | 0x20 | 2 | 文件注释长度 |
| 34 | 0x22 | 2 | 磁盘编号起始 |
| 36 | 0x24 | 2 | 内部文件属性 |
| 38 | 0x26 | 4 | 外部文件属性 |
| 42 | 0x2A | 4 | 本地文件头偏移量 |
| 46 | 0x2E | n | 文件名称 |
| 46+n | 0x2E+n | 附加字段 |
同样以flag.zip为例

0x4C~0x4F字节为50 4B 01 02 为中心目录区的固定签名
0x50~0x51字节为3F 00,前一个字节表示压缩用的zip版本,这里为6.3,后一个字节表示压缩用的系统类型,以下为常见系统:0MS-DOS / FAT Windows 系统常见(默认),3 UNIX Linux / macOS 常见,7 Macintosh 旧 Mac OS,10 Windows NTFS Windows NT/2000/XP 。
0x52~0x53字节为14 00,为解压所需最低ZIP版本,这里为2.0
0x54~0x55字节为01 00,为通用标识符,详细可以参考上文
0x56~0x57字节为00 00,为压缩方式,详细可以参考上文
0x58~0x59字节为3A 83文件最后修改时间,详细可以参考上文
0x5A~0x5B字节为59 5B文件最后修改日期,详细可以参考上文
0x5C~0x5F字节为F4 25 20 07CRC-32校验,详细可以参考上文
0x60~0x63字节为26 00 00 00压缩后大小,详细可以参考上文
0x64~0x67字节为1A 00 00 00压缩前大小,详细可以参考上文
0x68~0x69字节为08 00文件名长度,详细可以参考上文
0x6A~0x6B字节为24 00额外字段长度,即长度为36
0x6C~0x6D字节为00 00文件注释长度
0x6E~0x6F字节为00 00磁盘编号起始,问卷压缩时会使用到,暂不涉及
0x70~0x71字节为00 00 为内部文件属性,bit0为文件是否为文本文件,0 = binary,1 = text,其他的一般不用
0x72~0x75字节为20 00 00 00为外部文件属性,与文件rwx权限有关,暂不涉及
0x76~0x79字节为00 00 00 00为实体文件头偏移量,也就是50 4B 03 04那一块的位置,也就是开头
0x7A~0x81字节为66 6C 61 67 2E 74 78 74为文件名,即flag.txt
0x82~0xA5为附加字段,暂不涉及
目录结束标识
以下为目录结束标识内容
| 偏移量 | 偏移量(hex) | 长度 | 说明 |
|---|---|---|---|
| 0 | 0x0 | 4 | 固定值为0x504b0506 |
| 4 | 0x4 | 2 | 当前磁盘编号 |
| 6 | 0x6 | 2 | 含中央目录开头的磁盘编号 |
| 8 | 0x8 | 2 | 当前磁盘上中央目录项数量 |
| 10 | 0xA | 2 | ZIP 文件中所有的目录项数量 |
| 12 | 0xC | 4 | 以字节为单位的中央目录区大小 |
| 16 | 0x10 | 4 | 相对于文件开头的中央目录起始偏移 |
| 20 | 0x14 | 2 | ZIP 文件注释的长度 |
| 22 | 0x16 | ZIP 文件注释内容 |
同样以flag.zip为例

0xA6~0xA9字节为50 4B 05 06为固定字节
0xAA~0xAB字节为00 00为当前磁盘编号
0xAC~0xAD字节为00 00为含中央目录开头的磁盘编号
0xAE~0xAF字节为01 00为当前磁盘上中央目录项数量
0xB0~0xB1字节为01 00为ZIP 文件中所有的目录项数量
0xB2~0xB5字节为5A 00 00 00为以字节为单位的中央目录区大小
0xB6~0xB9字节为4C 00 00 00为相对于文件开头的中央目录起始偏移
0xBA~0xBB字节为00 00为ZIP 文件注释的长度