时间:2023-05-02
如何恢复损坏的7z存档
试用最新版本的 7-Zip
新版本的7-Zip可能会解决7z存档的问题。因此,请下载最新版本的7-Zip并尝试使用该新版本。您也可以尝试最新的 alpha 或 beta 版本。如果新版本也没有帮助,请阅读本手册。
所需软件:
7-Zip(最新版本,可以是稳定版,alpha版或beta版)。
某些带有十六进制查看器或编辑器的程序,例如 FAR 管理器。
7Z存档结构
7Z存档由4个主要数据块组成:
开始标头(32字节):它包含签名和指向结束标头的链接
文件的压缩数据
文件的压缩元数据块:它包含指向压缩数据的链接,有关压缩方法,CRC,文件名,大小,时间戳等的信息。
结束标头:它包含指向压缩元数据块的链接。
注意:如果 7z 存档仅包含一个未加密的文件,则 7-Zip 以未压缩的形式将该文件的元数据存储在末尾标头中,在这种情况下只有 3 个主要块。
存档示例
存档示例:a.7z(3740字节),其中包含使用LZMA方法压缩的5个文件。
存档开始:
0000000000: 37 7A BC AF 27 1C 00 04 5B 38 BE F9 59 0E 00 00
0000000010: 00 00 00 00 23 00 00 00 00 00 00 00 7A 63 68 FD
0000000020: 00 21 16 89 6C 71 3D AB 7D 89 E6 3C 2E BE 60 24
00: 6 bytes: 37 7A BC AF 27 1C - Signature
06: 2 bytes: 00 04 - Format version
08: 4 bytes: 5B 38 BE F9 - CRC of the following 12 bytes
0C: 8 bytes: 59 0E 00 00 00 00 00 00 - relative offset of End Header
14: 8 bytes: 23 00 00 00 00 00 00 00 - the length of End Header
1C: 4 bytes: 7A 63 68 FD - CRC of the End Header
Relative offset of End Header is relative from the end of Start Header,
that is at offset 0x20 (32 in decimal).
Real offset of End Header in example archive = 0x20 + 0x0E59 = 0x0E79
20: 00 21 16 89 ... - start of compressed data.
Note: if the file was compressed with LZMA method, the first byte
is always 00. If first byte is not 00, then archive uses
another method (it can be LZMA2 or encrypted data with AES).
存档结束:
End Header (offset = 0x0E59, length = 0x23):
0000000E70: 17 06 8D AD 01 09 80
0000000E80: AC 00 07 0B 01 00 01 23 03 01 01 05 5D 00 10 00
0000000E90: 00 0C 81 1A 0A 01 3C 70 52 F7 00 00
Possible values for first byte in End Header:
17 - End Header contains the link to Metadata Block.
01 - Metadata block is stored in End Header.
损坏类型
存档损坏时,可能会出现以下情况:
您可以打开存档,可以看到文件列表,但是当您按提取或测试命令时,会出现一些错误:数据错误或CRC错误。
打开存档时,您会收到消息“无法打开文件'a.7z'作为存档”
损坏情况:存档内文件的数据错误或CRC错误
在这里,我们描述了这种情况,当您可以打开存档并看到文件列表时,但是当您按“提取”或“测试”命令时,会出现一些错误:数据错误或CRC错误。
在这种情况下恢复数据非常困难。
如果存档是在“固体”模式下压缩的,并且您拥有存档中某些文件的精确副本,则可以使用具有相同设置和相同顺序的文件的良好副本创建类似的存档,并将坏的“坏”部分.7z替换为另一个好的.7z的“好”部分。您必须查看不良和良好存档中的文件列表,“test”命令的日志,并考虑替换不良部分的方法。
这里不再针对该腐败案件的说明。
损坏情况:无法打开文件“a.7z”作为存档
如果您尝试打开或提取存档,并且看到消息“无法打开文件'a.7z'作为存档”,则表示7-Zip无法从存档的开头或结尾打开某些标头。
在这种情况下,您必须在十六进制编辑器中打开存档并查看“开始标题”和“结束标题”。
可能的情况:
案例:如果存档的开头已损坏,则没有指向结束标头的链接。但是,如果结束标头正常,并且存档的大小也正确,则可以将十六进制编辑器中“开始标头”中的数据替换为以下值:
0000000000: 37 7A BC AF 27 1C 00 04 00 00 00 00 00 00 00 00
0000000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
然后尝试打开存档,如果可以打开并且看到文件列表,请尝试测试或提取命令。另请参阅此页面中的“数据错误或CRC错误”部分。
情况:开始标头和结束标头正常,但存档的总大小不正常。您可以从“开始标题”中的值计算正确的存档大小。然后,您必须恢复正确的大小。您可以在存档中的某处插入或删除一些数据(例如,在存档结束前偏移几 MB 时)。
例如,如果您有多卷存档:a.7z.001、...、a.7z.009,但缺少一部分 a.7z.008,只需将 a.7z.007 复制到文件 a.7z.008,7-Zip 将看到正确的存档大小。或者,如果某个部分被减小,请查看另一个部分的大小并恢复“坏”部分的原始(正确)大小,因此总大小将再次正确,并且 7-zip 将能够打开标题。
案例:存档的末尾已损坏或丢失。以下文本描述了这种情况。
存档末尾没有正确的结束标头
7-Zip 仅在存档创建操作结束时写入完整的开始标头。
您可以查看开始标题。如果您在其他字段中看到带有版本和零的签名:
0000000000: 37 7A BC AF 27 1C 00 04 00 00 00 00 00 00 00 00
0000000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
然后存档创建操作可能由于某种原因而中断。在这种情况下,存档末尾可能没有元数据块和结束标头。
注意:如果存档是多卷,则在写入存档结束(最后一个卷)之前复制了第一个卷,则也可能使用未完成的开始标头。在这种情况下,存档不会损坏。7-Zip可以解压缩这样的存档,如果总大小正确并且有正确的结束标题。
如果“开始标头”正常,则可以计算正确的存档大小,并与拥有的存档大小进行比较。
如果没有结束标头,则无法恢复文件名,时间戳和其他元数据,但可能可以将某些数据恢复为原始文件,然后可以使用某些解析器从原始文件中恢复数据。
我们通过示例描述所有步骤:
创建良好的 7z 存档
损坏的存档
从损坏的存档中恢复文件
创建良好的存档
我们创建了一些很好的存档。我们使用自述文件.txt(1565 字节)表单 7-Zip 9.20 作为示例文件。
从 readme.txt 创建 readme.txt.bz2、readme.zip、readme.txt.gzip 和 readme.txt.xz 存档。
使用 LZMA 方法创建一个包含所有文件的.7z:
readme.txt.bz2
readme.txt.gz
readme.zip
readme.txt
readme.txt.xz
我们有一个.7z(3740字节)。您可以在十六进制编辑器中查看该文件。它必须具有类似于上述7z文件的结构。
损坏的存档
现在我们整理一个.7z存档。我们希望将存档分为两部分:
a.7z.001:启动标头,压缩数据的某些部分
a.7z.002:压缩数据、元数据、结束标头的某些部分
带有结束标头的元数据块对于我们的测试存档(小于 300 字节)来说并不大。
我们称之为“拆分文件...”命令,然后在“拆分为卷,字节:”字段中键入“7 3000G”(100G 表示第二部分不能大于 100 GB)。
我们有两个部分:a.7z.001(3000 字节)和 a.7z.002(740 字节)。然后我们将 a.7z.001 复制到 bad.7z并尝试打开 bad.7z。我们收到消息“无法打开文件'坏.7z'作为存档”,所以我们的存档已损坏。
恢复存档
我们打开坏.7z在十六进制编辑器中
0000000000: 37 7A BC AF 27 1C 00 04 5B 38 BE F9 59 0E 00 00
0000000010: 00 00 00 00 23 00 00 00 00 00 00 00 7A 63 68 FD
0000000020: 00 21 16 89 6C 71 3D AB 7D 89 E6 3C 2E BE 60 24
我们看到开始标头正常。
我们从“开始标头”字段值计算正确的存档大小:
0x0E59 + 0x20 + 0x23 = 0x0E9C = 3740
正确的大小是 3740 字节,但我们的“坏.7z”只有 3000 字节。
我们期待存档的结尾:
0000000B60: 55 73 EA 87 45 18 FC AD 67 0D 40 EF F4 41 49 63
0000000B70: 6A 87 54 70 32 6C B0 8F 76 2A 63 BF 12 5D 88 CD
0000000B80: 22 76 9F 97 05 3B 37 BE 49 CD F8 0A CC 67 FB FE
0000000B90: 17 2E 16 D5 1F 8C 5A 30 08 7F C6 E9 98 9F 00 F1
0000000BA0: A6 99 F9 ED 01 62 84 48 77 69 C7 65 21 21 42 66
0000000BB0: 48 F1 FE 79 06 08 25 68
而且我们在存档末尾看不到结束标头。
结论:存档可能被截断了。
现在我们要创建另一个“好”的 7z 存档,其中包含良好的开始标头、结束标头。我们希望将压缩数据块从坏.7z放在新的“好”存档中。
首先,我们看起来压缩数据块的开头很糟糕.7z:
0000000020: 00 21 16 89 6C 71 3D AB 7D 89 E6 3C 2E BE 60 24
如果使用 LZMA 方法,则压缩数据中的第一个字节始终为 0,第二个字节的高位也为 0。因此,如果我们在第一个字节中看到 00,在第二个字节中看到从 00 到 7F,则可能使用了 LZMA 方法(而不是 LZMA2)。
如果压缩数据中的第一个字节不是 0 或者第二个字节的值高于 7F,则它不是 LZMA 流。它可以是LZMA2(或AES加密流)。
我们必须使用与 bad.7z 中相同的方法创建新的“好”7z 存档,并且新存档必须比坏存档大得多.7z
因此,我们为该新存档选择了一些大文件。在某些情况下,您可以使用甚至糟糕的.7z作为大文件。但是我们使用7-zip.chm。我们将 7-zip.chm(91020 字节)重命名为文件 raw.dat并使用具有大字典大小值的 LZMA 方法将 raw.dat 压缩为原始.7z。字典大小必须等于或大于 bad.7z 中的字典大小。
raw.7z 是(84898 字节),根据需要比 bad.7z 大得多。如果 raw.7z 小于“bad.7z”,则必须使用另一个更大的 RAW 创建另一个 RAW.7z.dat 更大。
我们称之为“拆分文件...”函数为坏.7z并在“拆分为卷,字节:”字段中键入“32 100G”。
它创建 2 个部分:
错误.7z.001:32 字节:开始标头
bad.7z.002:2968字节:压缩数据的开始
我们称之为“拆分文件...”原始函数.7z并在“拆分为卷,字节:”字段中键入“32 2968 100G”。请注意,值 2968 等于大小“bad.7z.002”。当您恢复真正的存档时,您必须使用错误的确切大小.7z.002。
它创建 3 个部分:
raw.7z.001:32 字节:开始标头
raw.7z.002:2968 字节:压缩数据的开始
raw.7z.003:81898 字节:压缩数据末尾、元数据块、结束标头
然后我们将 bad.7z.002 文件重命名为 raw.7z.002
现在,多卷“raw.7z.*”存档包含来自原始.7z好的标头和来自“坏.7z”的压缩数据
我们对原始.7z.001文件按“Extact”。它将提取原始.dat文件,并且可能会显示“数据错误”消息。
现在我们有原始.dat文件,其中包含从坏.7z恢复的流。
大多数 7z 档案都是可靠的。如果坏.7z存档是可靠的,则恢复的流由串联的原始文件组成
如果损坏.7z则存档不是可靠的,则恢复的流包含一个文件的数据。它还可以在末尾包含一些垃圾数据。
解析恢复的实体存档的原始流
不,我们必须使用一些看起来原始.dat的解析器软件,搜索文件签名并从该文件中提取一些文件。
您可以尝试使用7-Zip的解析器。
您需要 7-Zip 9.34 alpha 或更高版本。
选择 raw.dat 并调用上下文菜单命令“7-Zip >打开存档> #”
它显示:
1.bz2
2.readme.txt.gz
3.zip
4
5.xz
按提取命令解压缩这些文件。
因此,我们恢复了一些原始文件,但没有原始名称。
7-Zip解析器可以在原始文件中查找存档。但它无法识别其他文件,如 xml、html、jpg、png 文件等。因此,您可能需要其他解析器软件来从原始文件中提取文件。
恢复非固体存档和具有多个实体块的存档
如果 7z 存档中有多个实心块,则必须检测实心块的确切结尾和下一个实心块的开始。
该案件的恢复程序将在将来描述
@2020-2099 闽ICP备12013430号