Автоматически "перебор" нескольких байт для восстановления поврежденного файла

Кто-нибудь знает способ подбора значений силы при определенном смещении в файле? Это 4 последовательных байта, которые должны быть грубо форсированы. Я знаю правильный SHA-1 поврежденного файла. Итак, я хотел бы сравнить полный файл SHA-1, каждый раз, когда он меняет значение байта.

Я знаю точные 4 байта, которые были изменены, потому что файл был предоставлен мне экспертом по восстановлению данных, как задача восстановления. Для тех, кто интересуется знанием, файл rar имеет 4 байта, которые были намеренно изменены. Мне сказали смещения измененных 4 байтов и оригинального SHA-1. Человек сказал, что невозможно восстановить точный файл в архиве после того, как 4 байта были изменены. Даже если бы было всего несколько байтов, и вы точно знали, где была обнаружена коррупция. Так как у него нет записи восстановления. Я пытаюсь увидеть, есть ли способ для правильного заполнения этих 4 байтов, чтобы файл распаковывался без ошибок. Размер файла составляет около 5 МБ.

Пример:

Я загрузил фотографии, чтобы они более четко определяли, что именно я хочу сделать. Я считаю, что кто-то может опубликовать их здесь для меня с большим количеством представителей.

Пример смещения, на котором я сосредоточился 0x78 где первый рис показывает значение как CA Я хочу, чтобы скрипт принял значение на 1, чтобы он стал CB как показано на втором рисунке. Я хочу, чтобы это продолжало увеличивать значение на 1 и затем сравнивайте весь файл SHA-1 каждый раз. Вносить изменения только в эти 4 байта с указанным смещением

Попробую CAC5C58A и сравните SHA-1. Если не совпадает, то попробую CBC5C58A.После того, как первое значение достигает FF Затем он перейдет к 00C6C58A и так далее. В принципе, я бы хотел, чтобы он мог 00000000-FFFFFFFF но также иметь возможность выбрать, где вы хотите, чтобы он начинался и заканчивался. Я знаю, что это может занять некоторое время, но я все еще хотел бы попробовать это. Имейте в виду, я знаю точное смещение байтов, которые повреждены. Мне просто нужны правильные значения.

Если вы ищете в Google: "Как исправить поврежденный файл с помощью грубой силы", то есть человек, который написал программу для Linux. Тем не менее, он работает только против файлов, включенных в программу. Я ищу способ использовать тот же процесс с моим файлом.

2 ответа

Решение

Вот небольшая программа на 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 до 232-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:]

Нет, нет, нет и снова НЕТ!

Редкий ответ, который вы получаете, не тот, который вы ожидаете.

Несколько вопросов для вас:

  • Возможно ли, что эксперт не знает, что можно грубо форсировать строку байтов и повторять попытку SHA-1, пока она не сойдет? нет
  • Возможно ли, что он забыл это? нет
  • Возможно ли, что вы не можете сделать это на RAR-файл? нет
  • Другой ответ неверен? абсолютно НЕТ

И что?... время

Дело в том, что вы должны изменить так мало байтов... только 4!

Что это значит? 2564, то есть 256x256x256x256 возможностей, действительно очень большое число.
Если бы ваш компьютер мог обрабатывать 1 операцию в секунду (подстановка в файле + sha1)...
Вам следует подождать более 136 лет, или, если вы предпочитаете более 49710 дней.

Вам повезло, предварительно кэшированный файл размером 5 МБ (уже загруженный в оперативную память и в кэш) запрашивает всего около 0,03 секунды (минимум 0,025 с) на старом компьютере. Это сокращает ваше ожидаемое время до 1242-1492 дней (что превышает 3 года).

Это правда, кстати, что по статистике у вас должен быть положительный ответ в половине случаев. Тем не менее, вам следует подождать, пока вы не попробуете все возможности, чтобы быть уверенным, что есть только одна замена, которая даст вам такую ​​же контрольную сумму SHA-1...

Теперь это НЕВОЗМОЖНО звучит как "невозможно в ДОСТОЙНОЕ количество времени".


Как действовать

Более правильный ответ на ваш технический вопрос: когда вы говорите о грубой силе, необязательно использовать слепую грубую силу.

  • В другом ответе просто указано, что вам не нужно вычислять контрольную сумму sha1 для детали до повреждения. Вы делаете 1-й раз и экономите время для каждой последующей итерации (может быть, фактор 2 зависит от позиции).

  • То, что может изменить бесполезные усилия, - это написать параллельный код, который будет работать на GPU. Если у вас хорошая графическая карта, у вас может быть около 1000 ядер, которые могут вычислять для вас параллельно (даже больше, но их частота ниже, чем у процессора, но все же их много). Если вы можете сократить время с 1400 до 1,4 дня, может быть, вы даже можете сделать это.

  • Другой подход может привести вас к более быстрому решению.
    Вы сказали, что это RAR файл. Структура файла rar разделена на блоки. Если вы примете это во внимание, вы увидите, куда падает коррупция. Если это на части данных, на части заголовков или на обоих. Тогда вы можете действовать соответственно. Для простоты предположим, что это по данным:
    Вы можете сделать грубую силу своего смещения, проверить для каждого положительного CRC этого блока, если это даже положительный SHA1 для всего файла. Снова вы можете сделать параллельный код.

Конечная нота

Если бы они были 6 байтов вместо 4, вы вышли из игры с существующей технологией.

Другие вопросы по тегам