RAR 恢复记录的 NEWSUB_HEAD 中的 FileCRC 基于哪些数据?

发布于 2024-12-15 18:27:03 字数 1168 浏览 2 评论 0 原文

我试图找出 RAR 标头中的 crc32 字段的数据 恢复记录为依据。我正在尝试根据以前的 RAR 卷和提取的内容重新创建 RAR 卷。我已经达到了与正确/原始卷只有 12 个字节不同的程度。

这些名称基于 unrar 源代码 (arcread.cpp )或 RAR 技术说明

RAR 文件由块组成。它们有一个标头和一个主体:

[header][body]

标头包含描述主体的元数据。这些块之一是 HEAD_TYPE=0x74 文件头(存档中的文件)。

[header:a...FILE_CRC...z][body]

字段 FILE_CRC(4 字节)是根据 [body] 中的所有可用数据计算的,[body] 是存储或压缩的文件。

恢复记录的块(HEAD_TYPE=0x7a 子块)与文件块非常相似,但它在标头中包含三个额外字段:

[header:a...FILE_CRC...z, "Protect+", rsc, dsc][body]
    rsc: recovery sector count (4 bytes)
    dsc: data sector count (8 bytes)
assert dsc*2 + rsc*512 == size([body])

您可能会认为该块的 FILE_CRC 是基于数据的在正文中,就像文件块一样,但事实并非如此。 (由其他人独立验证) 那么我的问题是,这个crc32是用什么数据来计算的呢?

我已经尝试过一些事情:

  • 从 Protect+ 等开始。接下来是
  • RR 子块开始之前的正文,
  • 我已经暴力破解了一个小 RAR 文件上的所有可能范围。

I am trying to figure out on which data the crc32 field in the header of a RAR Recovery Record is based. I am trying to recreate a RAR volume based on a previous RAR volume and the extracted contents. I am up to the point where only 12 bytes differ from the correct/original volume.

The names are based on the unrar source code (arcread.cpp) or the RAR technote.

A RAR file consists of blocks. They have a header and a body:

[header][body]

The header contains metadata that describes the body. One of these blocks is HEAD_TYPE=0x74 File header (File in archive).

[header:a...FILE_CRC...z][body]

The field FILE_CRC (4 bytes) is calculated on all the data available in the [body], which is a stored or compressed file.

The block of a Recovery Record (HEAD_TYPE=0x7a subblock) is very similar to a file block, but it contains three extra fields in the header:

[header:a...FILE_CRC...z, "Protect+", rsc, dsc][body]
    rsc: recovery sector count (4 bytes)
    dsc: data sector count (8 bytes)
assert dsc*2 + rsc*512 == size([body])

You would think the FILE_CRC of this block is based on the data in the body, just like the file block, but this isn't the case. (verified independently by an other person)
So my question is, what data is used to calculate this crc32?

Some things I have tried already:

  • starting from Protect+ ect. followed by the body
  • everything before the start of the RR subblock
  • I have brute-forced all possible ranges on a small RAR file.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

败给现实 2024-12-22 18:27:03

不使用默认种子(-0x1 或 0xFFFFFFFF):

crc = crc32(data)
crc = crc32(data, ~0xffffffff)

删除 F(-0x10000000):

crc = crc32(data, ~0x0fffffff)

已向作者发送一封电子邮件,回复如下:

据我快速查看 RAR 代码,这是所有 CRC16 数据和所有恢复记录奇偶校验扇区的 CRC32(列表中的“所有 RR 数据”)。

请注意,虽然 RAR 存储此校验和,但它不会在任何地方使用它。恢复时不需要。即使恢复记录部分损坏,其有效部分仍然可以用来恢复数据。我们可以使用 CRC16 以每个扇区为基础检查修复是否成功,因此在恢复过程中不需要覆盖所有数据的 CRC32。

尤金

就像最初想到的那样,块的 FILE_CRC 是基于主体中的数据的。 RAR 代码中似乎有一个拼写错误。

TheUnarchiver2.7.1_src 的 XADRARParser.m 有以下注释代码:

    // Removed CRC checking because RAR uses it completely inconsitently
/*  if(block.crc!=0x6152||block.type!=0x72||block.flags!=0x1a21||block.headersize!=7)
...

差不多 3 年后我发现其他人已经找到了这个问题的解决方案 当年早些时候

# Why is this odd CRC initialiser used?
crc = crc32(rr_crcs, 0xF0000000)

Instead of using the default seed (-0x1 or 0xFFFFFFFF):

crc = crc32(data)
crc = crc32(data, ~0xffffffff)

an F was dropped (-0x10000000):

crc = crc32(data, ~0x0fffffff)

An email to the author was sent with the following response:

As far as I can see quickly looking into RAR code, this is CRC32 of all CRC16 data and all recovery record parity sectors ("All the RR data" in your list).

Note that while RAR stores this checksum, it does not use it anywhere. It is not necessary when recovering. Even if recovery record is partially damaged, its valid parts still can be used to recover data. We can check the repair success on per sector basis using CRC16, so one CRC32 covering all data is not required in recovery process.

Eugene

Like first thought, the FILE_CRC of the block is based on the data in the body. It looks as if there is a typo somewhere in the RAR code.

XADRARParser.m of TheUnarchiver2.7.1_src has the following commented code:

    // Removed CRC checking because RAR uses it completely inconsitently
/*  if(block.crc!=0x6152||block.type!=0x72||block.flags!=0x1a21||block.headersize!=7)
...

Almost 3 years later I found out that someone else had already found the solution to this problem earlier that year.

# Why is this odd CRC initialiser used?
crc = crc32(rr_crcs, 0xF0000000)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文