自动'暴力'几个字节来恢复损坏的文件


35

有没有人知道在文件中的特定偏移处使用强制值的方法?这是4个连续的字节,需要暴力强制。我知道损坏文件的正确SHA-1。所以,我想做的是每次更改字节值时比较完整的文件SHA-1。

我知道确切的4个字节已被更改,因为该文件是由数据恢复专家提供给我的,作为恢复挑战。对于那些有兴趣知道的人来说,rar文件有4个字节是故意改变的。我被告知更改的4个字节和原始SHA-1的偏移量。该人说,一旦4个字节被更改,恢复存档中的确切文件是不可能的。即使它只有几个字节,你就知道腐败的确切位置。因为它没有恢复记录。我正在尝试查看是否有一种方法可以正确填充这些特定的4个字节,因此文件将无错误地解压缩。文件大小约为5mb。

示例

我上传了照片,因此更清楚地定义了我正在寻找的内容。我相信有人可以在这里为我发布更多代表。

截图一

截图二

我关注的示例偏移是0x78第一张图片显示值的地方,因为CA 我希望脚本将值增加1,因此它变为CB第二张图片所示。我希望它继续增加值1,然后每次比较整个文件SHA-1。仅更改指定偏移处的4个字节。

它会尝试CAC5C58A比较SHA-1。如果不匹配,那么它将尝试CBC5C58A。然后一旦第一个值到达FF它将继续00C6C58A,依此类推。基本上,我希望它能够从,00000000-FFFFFFFF但也可以选择你想要它的开始和结束。我知道这可能需要一些时间,但我还是想尝试一下。请记住,我知道损坏的字节的确切偏移量。我只需要正确的值。

如果你在谷歌上搜索:“如何通过蛮力修复损坏的文件”有一个人写了一个Linux程序。但是,它仅适用于程序附带的文件。我正在寻找一些方法来使用我的文件相同的过程。


3
欢迎来到超级用户!我已经编辑了您的问题以删除对程序的请求,这将是偏离主题的。你能否编辑你的问题以包括你看到的一些例子?你做完研究很好,但向我们展示了哪些研究会有所帮助:)
bertieb

20
我可以问你如何最终得到这个文件,以及如何确定那些是唯一的4个损坏的字节?
Edoardo

1
你知道文件格式吗?如果你这样做,你可能能够计算出正确的值或限制范围,而不是试图强制它们。但是,一般情况下,出于安全原因,我建议应该转储任何损坏的文件。
StephenG

11
@eddyce我真的对你问题的第二部分感兴趣 - 为什么这4个字节?
克雷格·奥蒂斯

2
出于好奇,该文件是如何被破坏的?你怎么知道那是四个字节?
JohnEye

Answers:


27

这是一个小型的Python程序,可以完成您所描述的内容。

#!/usr/bin/env python3
from hashlib import sha1

with open('binaryfile', 'rb') as bin:
    binary = bin.read()

base = 0x0078
# ... is not valid Python; add more sequences, or take it out (or see below)
for seq in [[0xCA, 0xC5, 0xC5, 0x8A], [0xCB, 0xC5, 0xC5, 0x8A], ...]:
    copy = binary[0:base]
    copy += bytes(seq)
    copy += binary[base+len(seq):]
    if sha1(copy).hexdigest() == '9968733ce3ff0893bbb0a19e75faaf2fb0000e19':
        print('success with bytes {0}'.format(seq))
        break
else:
    print('no success')

联合国只是简单测试; 如果你发现错别字,请打电话给我。

base指定要尝试应用四个字节,长字符串'996873...是预期的SHA1的十六进制表示。行for seq in...定义要尝试的字节; 当然要替换'binaryfile'为您要尝试抢救的文件的路径。

您可以替换文字列表[[0xCA, 0xC5,... ]]用实际循环覆盖所有可能值的东西,但它基本上只是一个占位符,用于更有用的东西,因为我不确定您到底想要什么。

类似的东西for seq in itertools.product(range(256), repeat=4)):会循环遍历从0到2 32 -1的所有可能值。(你需要import itertools在顶部附近添加。)或者你可以简单地添加一个偏移; 更新脚本以用for seq in以下内容替换当前(在import主程序之前需要再次进行);

import struct

for n in range(2**32):
    val=(n+0x8AC5C5CA) % 2**32  # notice reverse order
    seq=list(reversed(struct.pack(">I", val)))
    copy = ...

我颠倒了字节的顺序,以便它自然地从0x8AC5C5CA递增到0x8AC5C5CB,但接下来的增量将是0x8AC5C5CC等。struct神奇的是将其转换为字节序列(必须从https:// stackoverflow查找它)。 com / a / 26920983/874188)。这将从0x8AC5C5CA开始并转到0xFFFFFFFF,然后回绕到0x00000000并向上爬回到0x8AC5C5C9。

如果您有多个候选范围,您希望按特定顺序检查,可能是类似的

for rge in [(0x8AC5C5CA, 0x8AFFFFFF), (0x00C6C58A, 0x00FFFFFF),
        (0x00000000, 0x00C6C589), (0x01000000, 0x8AC5C5C9)]:
    for val in range(*rge):
        seq=list(reversed(struct.pack(">I", val)))
        copy = ...

但是你需要确保自己(开始,结束)rge覆盖0x00000000和0xFFFFFFFF之间的所有空间,如果你真的想要检查它的全部。(再次注意,范围会增加最后一个字节seq,并根据您的规定要求反向应用值的字节。)

如果你想使用两个不同的base地址,你很快就会遇到蛮力的生活中可行的极限; 但是,例如,您可以将4字节数字拆分为两个2字节的部分,并应用不同的偏移量。

base1 = 0x1234
base2 = 0x2345

for seq in range(whatever):
    copy = binary[0:base1]
    copy += bytes(seq[0:1])
    copy += binary[base1+2:base1+base2]
    copy += bytes(seq[2:3])
    copy += binary[base2+2:]

评论不适用于扩展讨论; 这个对话已经转移到了聊天中
Journeyman Geek

4

不,不,不,不,不!

你得到的答案很少不是你所期望的。

有些问题要问你:

  • 专家是否有可能不知道有可能对字节串强制执行并迭代尝试SHA-1直到收敛为止?没有
  • 他有可能忘记它吗?没有
  • 您是否有可能无法在rar文件中执行此操作?没有
  • 对方的回答错了吗?绝对没有

所以呢?... 时间。

关键是你必须改变这么少的字节...只有4!

这是什么意思?256 4即256x256x256x256可能性,真是一个非常大的数字。
如果您的计算机每秒能够处理1次操作(在文件+ sha1中替换)......
您应该等待超过136年,或者如果您更喜欢49710天。

你很幸运,一台5MB的预缓存文件(已经在ram和缓存中加载)在旧计算机上只需要大约0.03秒(最小0.025秒)。这会将您的预期时间缩短至1242-1492天(超过3年)。

顺便说一句,从统计上来说,你应该在一半的时间里得到肯定的回答。尽管如此,你应该等到你将尝试所有的可能性,以确保只有一个替换将给你相同的SHA-1校验和...

现在,不可能的声音“在可爱的时间内不可能”。


如何进行

对你的技术问题更恰当的回答:当你谈论蛮力时,它就没有必要盲目蛮力。

  • 在另一个答案的评论中只是说明您不需要在损坏之前计算部件上的sha1校验和。你是第一次做,你为每次连续的迭代节省了时间(可能是因为它取决于位置)。

  • 可以改变毫无价值的东西的是编写将在GPU上运行的并行代码。如果你有一个好的图形卡,你可能有大约1000个内核可以并行计算(更多但它们的频率低于cpu,但它们仍然很多)。如果你能把时间从1400天缩短到1.4天,你甚至可以做到。

  • 一个不同的方法可以带你到一个更快的解决方案。
    你说这是一个rar文件。的RAR文件结构被划分成块。如果你掌握它,你可以看到腐败的地方。如果它是数据的一部分,在标题的一部分或两者。然后你可以采取行动。为了简单起见,我们假设它超过了数据:
    你可以做你的偏移的强力,检查该块的每个正CRC,如果它对整个文件的SHA1是正的。您可以再次执行并行代码。

最后的说明

如果它们是6个字节而不是4个字节,那么你就不能使用现有的技术了。


很好的答案 - 人们不一定需要耗尽整个空间,因为即使sha1使用重复哈希,本例中的rar本身也不会因内部检查而解压缩。命中4个字节错误地解决了sha1而内部crc错误地解决了。
rrauenza

@rrauenza谢谢。BTW不仅(双重检查)。实际上块应该比从损坏的字节到文件末尾的整个部分更短,并且CRC应该更轻,然后计算sha1算法...
Hastur

@rrauenza你知道如何让实际的并行代码在GPU上运行吗?我有一个很好的GPU。谢谢。
Sbt19年

不,我没有。您可以通过分区搜索空间来使用多个cpu。
rrauenza

@ Sbt19无论他们怎么说你谷歌都不是那么害怕使用;-)。搜索(如果是nvidia)Cuda, brute force, sha1,你会得到很多提示,例如源代码。BTW保持你的注意力高,因为从,谷歌浏览路径,噢,我的孩子,可能会导致你在网络上的阴暗面之一 ...... :-)。(不在github上...在其他网站上你可以遇到这种研究)。PS>有很多关于相关主题的科学论文,例如这一篇 ......
Hastur
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.