web-dev-qa-db-ja.com

破損したファイルを回復するために自動的に数バイトの「総当たり」

誰かがファイルの特定のオフセットで力の値をブルートする方法を知っていますか?それはブルートフォースされる必要があるだろう4連続バイトです。破損したファイルの正しいSHA-1を知っています。だから、私がやりたいのは、それがバイト値を変更するたびに、完全なファイルSHA-1を比較することです。

ファイルがデータ復旧の専門家によって復旧の課題として提供されたため、変更された正確な4バイトがわかります。知ることに興味がある人のために、rarファイルは意図的に変更された4バイトを持っています。変更された4バイトと元のSHA-1のオフセットを聞かれました。 4バイトが変更されたらアーカイブの正確なファイルを回復することは不可能であると人は言った。たとえそれがほんの数バイトで、あなたがその破損がどこにあるのかを正確に知っていたとしても。回復記録がないので。私は、ファイルがエラーなしで解凍されるようにそれらの特定の4バイトが正しく埋められる方法があるかどうかを確かめようとしています。ファイルサイズは約5MBです。

私が写真をアップロードしたので、それは私がしたいことを正確に明確に定義されています。誰かが私のためにもっと多くの担当者と一緒にここに投稿できると信じています。

Screenshot One

Screenshot Two

私が注目しているオフセットの例は0x78です。ここで最初の写真はCAとして値を表示します。スクリプトに値を1だけ引き上げて、2番目の写真のようにCBにします。値を1ずつ増加させ続け、そのたびにファイルSHA-1全体を比較するようにします。指定されたオフセットでこれらの4バイトに変更を加えるだけです。

それはCAC5C58Aを試して、SHA-1を比較します。一致しない場合は、CBC5C58Aを試み、最初の値がFFに達すると、00C6C58Aに進みます。基本的には、00000000-FFFFFFFFから移動できるようにしたいのですが、開始位置と終了位置を選択することもできます。私はそれが時間がかかるかもしれないことを知っていますが、私はまだそれを試してみたいと思います。私は破損しているバイトの正確なオフセットを知っていることを覚えておいてください。正しい値が必要です。

Googleで検索した場合:「破損したファイルを総当たりで修正する方法」Linuxプログラムを書いた人がいます。ただし、プログラムに含まれるファイルに対してのみ機能します。私は私のファイルと同じプロセスを使用するいくつかの方法を探しています。

35
Sbt19

これはあなたが記述しているように見える小さな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')

国連簡単にテスト済み。あなたがタイプミスを見つけたら私にpingを送ってください。

baseは4バイトを適用する場所を指定し、長い文字列'996873...は予想されるSHA1の16進表現です。行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が指定された要件に従って値のバイトを逆に適用することに注意してください。)

2つの異なるbaseアドレスを使用したい場合は、生涯に実行可能なことの限界に間に合わず、すぐに力を尽くします。しかし、例えば、4バイトの数値を2つの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:]
27
tripleee

いいえ、いいえ、いいえ、またNOです。

あなたが得る答えはあなたが期待するものではありません。

あなたへのいくつかの質問:

  • expert がforの文字列をブルートフォースして収束するまで繰り返しSHA-1を試すことが可能であることを知らないという可能性はありますか?いいえ
  • 彼がそれを忘れることは可能ですか?いいえ
  • Rarファイルではできないのでしょうか。いいえ
  • 他の答え は間違っていますか?絶対にNO

だから何?...時間。

重要なのは、数バイトだけ変更する必要があるということです。

どういう意味ですか? 2564 それは256x256x256x256の可能性です、本当に本当に大きい数です。
お使いのコンピュータが毎秒1回の処理を処理できた場合(ファイルへの代入+ sha1)...
136年以上待つ必要があります、または49710日を超える期間がある場合.

幸運にも、5MBのプリキャッシュされたファイル(既にramとキャッシュにロードされています)は古いコンピュータでたった約0.03秒(最小0.025秒)を要求します。それはあなたの期待する時間を1242 - 1492日(3年以上に何か)に短縮します。

それは本当です、ところで、統計的にあなたは半分の時間で正の答えを持つべきです。それにもかかわらず、あなたがあなたに同じSHA-1チェックサムを与えるであろう唯一の置換があることを確かめるためにすべての可能性を試みるまで待つべきである...

これで _不可能_ は「 _価値のある_ 時間内には不可能」と聞こえます。


どうやって進める

あなたの技術的な質問に対するより適切な答え:あなたがブルートフォースについて話すとき、それは必要な盲目的ブルートフォースである必要はありません。

  • それはちょうどあなたが破損の前に部品のsha1チェックサムを計算する必要はないという他の答えのコメントに述べられています。あなたは1回目をやって、あなたはそれぞれの連続した繰り返しのための時間を節約するでしょう(多分それは位置から2倍になります)。

  • 無駄な努力を変えることができる何かはGPUで動くparallel codeを書くことです。あなたが良いグラフィックカードを持っているなら、あなたは並行してあなたのために計算することができるおよそ1000のコアを持っているかもしれません(もっともっと彼らはCPUより低い頻度を持っています、それでもまだたくさんあります)。あなたが1400から1.4日に時間を減らすことができるなら多分あなたはそれをすることさえできます。

  • 別のアプローチを使用すると、より早い解決策を見つけることができます。
    あなたはそれがRARファイルだと言った。 rarファイル構造 はブロックに分割されています。あなたがそれを数えるならば、あなたは汚職がどこに落ちるかを見ることができます。それがデータの一部、ヘッダーの一部、またはその両方にある場合。それであなたは結果的に行動することができます。簡単にするために、データ上にあるとしましょう。
    あなたはあなたのオフセットの力ずくの力をすることができます、それがファイル全体のSHA1さえ正ならばそのブロックのそれぞれの正のCRCをチェックしてください。また、並列コードを実行することができます。

最後のメモ

4バイトではなく6バイトであれば、現在のテクノロジではゲーム外となりました。

4
Hastur