ZIP伪加密看似简单,实则也是大有学问在里面

这里细节讲解一下伪加密和相关工具的使用

首先我们需要了解一下zip文件结构

zip文件结构

zip文件结构大致分为三个部分

一个record区,一个dirEntry区,一个endLocator区

三个部分相互依存,这里是010下的zip文件对照表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
+ ZIPFILERECORD record # 压缩源文件数据区
- char frSignature[4] # 压缩源文件标志
- ushort frVersion # 压缩源文件版本
- ushort frFlags # 压缩源文件标志 (有无加密,这个更改这里进行伪加密,改为01 00打开就会提示有密码了)
- enum COMPTYPE frCompression
- DOSTIME frFileTime # 压缩源文件时间
- DOSDATE frFileDate # 压缩源文件日期
- uint frCrc # 压缩源文件CRC32校验值
- uint frCompressedSize # 压缩源文件压缩后大小
- uint frUncompressedSize # 压缩源文件压缩前大小
- ushort frFileNameLength # 压缩源文件名长度
- ushort frExtraFieldLength # 压缩源文件扩展域长度
- char frFileName[frFileNameLength] # 压缩源文件名
- uchar frData[frCompressedSize] # 压缩源文件数据
+ ZIPDIRENTRY dirEntry # 压缩源文件目录区
- char deSignature[4] # 目录标志
- ushort deVersionMadeBy # 创建该条目的版本
- ushort deVersionNeeded # 解压该条目所需的版本
- ushort deFlags # 标志位 (判断是不是伪加密的位置,如果是真加密则两个都是0900,伪加密这个则是0000或0100)
- enum COMPTYPE deCompression # 压缩方法
- DOSTIME deFileTime # 最后修改时间
- DOSDATE deFileDate # 最后修改日期
- uint deCrc # CRC32校验值
- uint deCompressedSize # 压缩后的大小
- uint deUncompressedSize # 压缩前的大小
- ushort deFileNameLength # 文件名长度
- ushort deExtraFieldLength # 扩展域长度
- ushort deFileCommentLength # 文件评论长度
- ushort deDiskNumberStart # 起始磁盘编号
- ushort deInternalAttributes # 内部属性
- uint deExternalAttributes # 外部属性
- uint deRelativeOffset # 该条目在 ZIP 文件中的偏移位置
- char deFileName[deFileNameLength] # 文件名
- char deExtraField[deExtraFieldLength] # 扩展域
- char deFileComment[deFileCommentLength] # 文件评论
+ ZIPENDLOCATOR endLocator # 压缩源文件目录结束标志
- char elSignature[4] # 结束标志
- ushort elDiskNumber # 当前磁盘编号
- ushort elStartDiskNumber # 目录开始的磁盘编号
- ushort elEntriesOnDisk # 当前磁盘上的条目数量
- ushort elEntriesTotal # 总条目数量
- uint elSizeOfDirectory # 目录的总大小
- uint elOffsetOfDirectory # 目录开始的偏移位置
- ushort elCommentLength # 注释长度
- char elComment[elCommentLength] # 注释

可以发现最重要的就是两个标志位了,他们是判断伪加密的标准

其实其余部分也很重要,因为如果不对应的话直接解压会发现报错——CRC校验错误

首先我们要知道

全局方式位标记的四个数字中只有第二个数字对其有影响,其它的不管为何值,都不影响它的加密属性,即:
第二个数字为奇数时 –>加密
第二个数字为偶数时 –>未加密

也就是说,0900/0100代表着加密,0000/0800代表着无加密

伪加密就是把本来无加密的文件修改了标志位从而显示出加密的样子

那我们怎么修改伪加密呢?为什么有些工具可以直接解压有些却不行呢?

工具选择

010editor

010editor肯定是最普遍和最准确的修改伪加密的东西了

如果是伪加密的话直接010修改0900为0000

如果两区(record和dirEntry)都是0900直接全改即可

bandizip

经过测试,bandizip识别一个文件是否加密是通过看dirEntry记录中的deflag位

如果deFlag位是加密的话无论另一个frflag是否是加密bandizip都会识别为加密

winRAR

winRAR和bandizip一样,都是识别dirEntry记录中的deflag位

7zip

7z就很神奇,它与上面两个工具不同。

7zip判断是否为加密的方式是看record记录中的frflag位

因此有些明明是伪加密的zip 7z却能直接解压

所以那句“不会出的出题人只修改一个struct区”是因为换个工具就能解压

随波逐流

经过测试,随波逐流提供的伪加密修复只会修改dirEntry记录中的deflag位,而不管frFlag位

ZipCenOp

不好用!!

运行

1
java -jar ZipCenOp.jar -r 111.zip

会显示

success 1 flag(s) found

但是它不帮我改,有啥用?。。

其他工具

传闻2345好压改两个区也能直接开。而且还有360解压缩

然而我不敢尝试,怕删不干净。。