Einige Bytes automatisch brachial erzwingen, um eine beschädigte Datei wiederherzustellen

35

Kennt jemand eine Möglichkeit, Werte bei einem bestimmten Versatz in einer Datei zu brachialisieren? Es sind 4 aufeinanderfolgende Bytes, die brutal gezwungen werden müssten. Ich kenne das korrekte SHA-1 der beschädigten Datei. Ich möchte also die gesamte Datei SHA-1 jedes Mal vergleichen, wenn sie den Bytewert ändert.

Ich kenne die genauen 4 Bytes, die geändert wurden, weil mir die Datei von einem Datenwiederherstellungsexperten als Wiederherstellungsaufforderung übergeben wurde. Für diejenigen, die wissen wollen, hat die rar-Datei 4 Bytes, die absichtlich geändert wurden. Mir wurde der Versatz der geänderten 4 Bytes und des ursprünglichen SHA-1 mitgeteilt. Die Person sagte, es sei UNMÖGLICH, die genaue Datei im Archiv wiederherzustellen, sobald die 4 Bytes geändert wurden. Auch wenn es nur wenige Bytes waren und Sie genau wussten, wo sich die Beschädigung befand. Da es keinen Wiederherstellungsdatensatz gibt. Ich versuche zu sehen, ob es eine Möglichkeit gibt, diese 4 Bytes korrekt auszufüllen, damit die Datei fehlerfrei dekomprimiert wird. Die Dateigröße beträgt ca. 5 MB.

Beispiel :

Ich habe Fotos hochgeladen, damit klarer definiert ist, was ich tun möchte. Ich glaube, jemand kann sie hier für mich mit mehr Repräsentanten posten.

Screenshot Eins

Screenshot Zwei

Der Beispieloffset, auf den ich mich konzentriere, ist 0x78der Punkt, an dem das erste Bild den Wert anzeigt, da CA ich möchte, dass das Skript den Wert um 1 CBerhöht, so dass er dem Wert im zweiten Bild entspricht. Ich möchte, dass es den Wert immer weiter erhöht 1und dann jedes Mal die gesamte Datei SHA-1 vergleicht. Nehmen Sie nur Änderungen an diesen 4 Bytes am angegebenen Versatz vor.

Es wird versucht CAC5C58A, den SHA-1 zu vergleichen. Wenn dies nicht CBC5C58Azutrifft , wird versucht. Wenn der erste Wert erreicht FFist, geht er zu 00C6C58Aund so weiter. Grundsätzlich möchte ich, dass es geht, 00000000-FFFFFFFFaber auch die Möglichkeit hat zu wählen, wo Sie es beginnen und enden möchten. Ich weiß, dass es einige Zeit dauern könnte, aber ich würde es trotzdem gerne versuchen. Denken Sie daran, ich kenne den genauen Versatz der Bytes, die beschädigt sind. Ich brauche nur die richtigen Werte.

Wenn Sie auf Google suchen: "So beheben Sie eine beschädigte Datei mit brachialer Gewalt" Es gibt eine Person, die ein Linux-Programm geschrieben hat. Es funktioniert jedoch nur mit den im Programm enthaltenen Dateien. Ich suche nach einer Möglichkeit, den gleichen Prozess mit meiner Datei zu verwenden.

Sbt19
quelle
3
Willkommen bei Super User! Ich habe Ihre Frage bearbeitet, um die Anfrage nach einem Programm zu entfernen, das nicht zum Thema gehört. Können Sie Ihre Frage so bearbeiten , dass sie einige der Beispiele enthält, die Sie gesehen haben? Es ist gut, dass Sie Nachforschungen angestellt haben, aber genau zu zeigen, welche Nachforschungen hilfreich wären :)
bertieb
20
Kann ich fragen, wie Sie zu dieser Datei gekommen sind und wie Sie sicher sein können, dass dies die einzigen 4 korrupten Bytes sind?
Edoardo
1
Kennen Sie das Dateiformat? Wenn Sie dies tun, können Sie möglicherweise die korrekten Werte ermitteln oder die Bereiche begrenzen, anstatt zu versuchen, sie brutal zu erzwingen. Im Allgemeinen würde ich jedoch vorschlagen, dass beschädigte Dateien aus Sicherheitsgründen gesichert werden.
StephenG
11
@eddyce Mich interessiert wirklich der zweite Teil deiner Frage - warum diese 4 Bytes?
Craig Otis
2
Wie wurde die Datei aus Neugier beschädigt? Und woher weißt du, dass es diese vier Bytes waren?
JohnEye

Antworten:

27

Hier ist ein kleines Python-Programm, das genau das tut, was Sie zu beschreiben scheinen.

#!/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')

UnNur kurz getestet; Bitte ping mich an, wenn du Tippfehler findest.

Das basegibt an, wo versucht werden soll, die vier Bytes anzuwenden, und die lange Zeichenfolge '996873... ist die hexadezimale Darstellung des erwarteten SHA1. Die Zeile for seq in... definiert die zu versuchenden Bytes. und natürlich durch 'binaryfile'den Pfad zu der Datei ersetzen , die Sie retten möchten.

Sie können die Literal-Liste [[0xCA, 0xC5,... ]]durch etwas ersetzen, das tatsächlich alle möglichen Werte durchläuft, aber im Grunde genommen ist es nur ein Platzhalter für etwas Nützlicheres, da ich nicht sicher bin, was genau Sie dort wollen.

So etwas for seq in itertools.product(range(256), repeat=4)):durchläuft alle möglichen Werte von 0 bis 2 32 -1. (Sie müssen dann in der import itertoolsNähe des oberen Randes hinzufügen.) Oder Sie können einfach einen Versatz hinzufügen. Aktualisieren Sie das Skript, um das aktuelle for seq indurch das folgende zu ersetzen (wobei wiederum importdas Hauptprogramm vorgezogen werden muss).

import struct

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

Ich umgekehrt die Reihenfolge des Bytes , so dass es natürlich Schritte von 0x8AC5C5CA zu 0x8AC5C5CB aber dann dem nächsten Inkrement werden 0x8AC5C5CC usw. Die structMagie dies eine Folge von Bytes zu konvertieren ist (hatte es nachzuschlagen von https: // Stackoverflow. com / a / 26920983/874188 ). Dies beginnt bei 0x8AC5C5CA und geht zu 0xFFFFFFFF, umschließt dann 0x00000000 und steigt wieder auf 0x8AC5C5C9 auf.

Wenn Sie mehrere Kandidatenbereiche haben, die Sie in einer bestimmten Reihenfolge untersuchen möchten, z

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

Aber dann müssen Sie sich vergewissern, dass die (Start-, End-) Paare den rgegesamten Raum zwischen 0x00000000 und 0xFFFFFFFF abdecken, wenn Sie wirklich alles untersuchen möchten. (Beachten Sie auch hier, dass der Bereich das letzte Byte inkrementiert und seqdie Bytes des Werts entsprechend Ihren angegebenen Anforderungen umgekehrt angewendet werden.)

Wenn Sie zwei verschiedene baseAdressen verwenden möchten, stoßen Sie schnell an die Grenzen dessen, was in Ihrem Leben mit brachialer Gewalt machbar ist. Sie können jedoch beispielsweise die 4-Byte-Zahl in zwei 2-Byte-Teile aufteilen und diese an verschiedenen Offsets anwenden.

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:]
Tripleee
quelle
Kommentare sind nicht für eine längere Diskussion gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Geselle Geek
4

Nein, nein, nein und wieder NEIN!

Selten erhalten Sie eine Antwort, die nicht Ihren Erwartungen entspricht.

Einige Fragen an Sie:

  • Ist es möglich, dass ein Experte nicht weiß, dass es möglich ist, eine Zeichenfolge für Bytes zu erzwingen und den SHA-1 iterativ zu testen, bis er konvergiert? Nein
  • Ist es möglich, dass er es vergisst? Nein
  • Ist es möglich, dass Sie dies nicht mit einer rar-Datei tun können? Nein
  • Ist die andere Antwort falsch? absolut NEIN

Na und? ... Zeit.

Der Punkt ist, dass Sie so wenige Bytes ändern müssen ... nur 4!

Was bedeutet das? 256 4 das sind 256x256x256x256 Möglichkeiten, eine wirklich sehr große Zahl.
Wenn Ihr Computer 1 Operation pro Sekunde verarbeiten konnte (Ersetzung in der Datei + sha1) ...
sollten Sie mehr als 136 Jahre warten , oder wenn Sie mehr als 49710 Tage bevorzugen.

Sie haben genug Glück, eine 5 MB große vorab zwischengespeicherte Datei (die bereits im RAM und im Cache geladen ist) benötigt auf einem alten Computer nur etwa 0,03 Sekunden (min. 0,025 Sekunden). Das verkürzt Ihre erwartete Zeit auf 1242-1492 Tage (etwas mehr als 3 Jahre).

Es ist wahr, BTW, dass statistisch gesehen Sie in der Hälfte der Zeit eine positive Antwort haben sollten . Trotzdem sollten Sie warten, bis Sie alle Möglichkeiten ausprobiert haben, um sicherzugehen, dass es nur eine Substitution gibt, die Ihnen dieselbe SHA-1-Prüfsumme gibt ...

Nun, da UNMÖGLICH klingt als "nicht möglich in einer bestimmten Zeit".


Wie geht es weiter?

Richtigere Antwort auf Ihre technische Frage: Wenn Sie über rohe Gewalt sprechen, muss es nicht unbedingt blinde rohe Gewalt sein.

  • In einem Kommentar in der anderen Antwort heißt es lediglich, dass Sie die sha1-Prüfsumme für das Teil vor der Beschädigung nicht berechnen müssen. Sie machen das 1. Mal und Sie sparen Zeit für jede nachfolgende Iteration (möglicherweise ein Faktor 2, der von der Position abhängt).

  • Etwas, das den Wert der Anstrengung ändern kann, ist das Schreiben eines parallelen Codes , der auf der GPU ausgeführt wird. Wenn Sie eine gute Grafikkarte haben, haben Sie möglicherweise ungefähr 1000 Kerne, die für Sie parallel rechnen können (sogar mehr, aber sie haben eine niedrigere Frequenz als die CPU, aber sie sind immer noch viel). Wenn Sie in der Lage sind, die Zeit von 1400 auf 1,4 Tage zu verkürzen, können Sie es vielleicht sogar tun.

  • Ein anderer Ansatz kann zu einer schnelleren Lösung führen.
    Sie sagten, es ist eine Rar-Datei. Die rar-Dateistruktur ist in Blöcke unterteilt. Wenn Sie es zählen, können Sie sehen, wo die Korruption fällt. Wenn es sich um einen Teil der Daten handelt, um einen Teil der Überschriften oder um beide. Dann können Sie konsequent handeln. Nehmen wir der Einfachheit halber an, es
    sind keine Daten mehr vorhanden: Sie können die Brute Force Ihres Offsets ausführen und für jeden positiven CRC dieses Blocks überprüfen, ob der SHA1 für die gesamte Datei sogar positiv ist. Auch hier können Sie einen parallelen Code ausführen.

Schlussbemerkung

Wenn sie 6 Bytes statt 4 waren, warst du mit der gegenwärtigen Technologie aus dem Spiel.

Hastur
quelle
Tolle Antwort - man müsste jedoch nicht unbedingt den gesamten Speicherplatz ausschöpfen, da die rar selbst in diesem Beispiel aufgrund interner Prüfungen nicht dekomprimiert würden, selbst wenn die sha1 mit einem doppelten Hash gearbeitet hätte. Es wäre sehr, sehr unwahrscheinlich, 4 Bytes zu treffen, die das sha1 falsch lösten UND ein internes crc falsch.
Rrauenza
@ Rrauenza Danke. Übrigens nicht nur (die doppelte Prüfung). In der Tat sollte der Block kürzer sein als der gesamte Teil von den beschädigten Bytes bis zum Ende der Datei, und der CRC sollte leichter zu berechnen sein als der sha1-Algorithmus ...
Hastur
@rrauenza Weißt du, wie ich vorgehen würde, um den eigentlichen Parallelcode auf der GPU laufen zu lassen? Ich habe eine gute GPU. Vielen Dank.
Sbt19
Nein, tue ich nicht. Sie können jedoch mehrere CPUs verwenden, indem Sie den Suchbereich partitionieren.
Rrauenza
@ Sbt19 Was auch immer sie dir darüber gesagt haben google ist nicht so erschreckend zu bedienen ;-). Suche nach (wenn nvidia) Cuda, brute force, sha1und du wirst viele Hinweise haben, zB Quellcode . BTW Ihre Aufmerksamkeit hoch halten , weil aus , dass Google Weg gerade, oh mein Junge, können Sie auf eine der dunklen Seiten des Netzes führen ... :-). (Nicht auf Github ... auf einer anderen Seite, die Sie mit dieser Art von Recherchen treffen können). PS> Es gibt eine Menge wissenschaftlicher Artikel zu verwandten Themen, z. B. diesen ...
Hastur