質問: 破損したファイルを回復するために自動的に数バイトの「総当たり」 誰かがファイルの特定のオフセットで力の値をブルートする方法を知っていますか?それはブルートフォースされる必要があるだろう4連続バイトです。破損したファイルの正しいsha-1を知っています。だから、私がやりたいのは、それがバイト値を変更するたびに、完全なファイルsha-1を比較することです。ファイルがデータ復旧の専門家によって復旧の課題として提供されたため、変更された正確な4バイトがわかります。知ることに興味がある人のために、rarファイルは意図的に変更された4バイトを持っています。変更された4バイトと元のsha-1のオフセットを聞かれました。 4バイトが変更されたらアーカイブの正確なファイルを回復することは不可能であると人は言った。たとえそれがほんの数バイトで、あなたがその破損がどこにあるのかを正確に知っていたとしても。回復記録がないので。私は、ファイルがエラーなしで解凍されるようにそれらの特定の4バイトが正しく埋められる方法があるかどうかを確かめようとしています。ファイルサイズは約5mbです。例:私が写真をアップロードしたので、それは私がしたいことを正確に明確に定義されています。誰かが私のためにもっと多くの担当者と一緒にここに投稿できると信じています。 私が注目しているオフセットの例は0x78です。ここで最初の写真はcaとして値を表示します。スクリプトに値を1だけ引き上げて、2番目の写真のようにcbにします。値を1ずつ増加させ続け、そのたびにファイルsha-1全体を比較するようにします。指定されたオフセットでこれらの4バイトに変更を加えるだけです。それはcac5c58aを試して、sha-1を比較します。一致しない場合は、cbc5c58aを試み、最初の値がffに達すると、00c6c58aに進みます。基本的には、00000000-ffffffffから移動できるようにしたいのですが、開始位置と終了位置を選択することもできます。私はそれが時間がかかるかもしれないことを知っていますが、私はまだそれを試してみたいと思います。私は破損しているバイトの正確なオフセットを知っていることを覚えておいてください。正しい値が必要です。googleで検索した場合:「破損したファイルを総当たりで修正する方法」linuxプログラムを書いた人がいます。ただし、プログラムに含まれるファイルに対してのみ機能します。私は私のファイルと同じプロセスを使用するいくつかの方法を探しています。
回答: これはあなたが記述しているように見える小さな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:]