0

私は、E01 ビットストリーム イメージを分析するソフトウェアに取り組んでいます。基本的に、これらはユーザーがディスク上のすべてのデータを単一のファイルに圧縮できるようにするフォレンジック データ ファイルです。E01 形式には、ソース データの MD5 ハッシュや結果データなど、元のデータに関するデータが埋め込まれます。私の問題に:

e01 ファイルには、実際のデータ チャンクが配置されている e01 ファイル内の他の場所へのオフセットである一連の 32 ビット数値である「テーブル」セクションが含まれています。このデータを次のようにしてリストに解析することに成功しました。

this.ChunkLocations = new List<int>();
//hack:Will this overflow?  We are adding to integers to a long?
long currentReadLocation = TableSectionDescriptorRef.OffsetFromFileStart + c_SECTION_DESCRIPTOR_LENGTH + c_TABLE_HEADER_LENGTH;
byte[] currReadBytes;
using (var fs = new FileStream(E01File.FullName, FileMode.Open))
      {
      fs.Seek(currentReadLocation, 0);
      for (int i = 0; i < NumberOfEntries; i++)
                {
                    currReadBytes = new byte[c_CHUNK_DATA_OFFSET_LENGTH];
                    fs.Read(currReadBytes,0, c_CHUNK_DATA_OFFSET_LENGTH);
                    this.ChunkLocations.Add(BitConverter.ToUInt32(currReadBytes, 0));
                }
       }

c_CHUNK_DATA_OFFSET_LENGTH は 4 バイト/「32 ビット」の数値です。

ewf/e01 仕様によると、「チャンク データ オフセットの最上位ビットは、チャンクが圧縮されているか (1) 圧縮されていないか (0) を示します」。これは、オフセットを int に変換すると、結果に大きな負の数が含まれるという事実によって証明されているように見えますが (圧縮されていないチャンクの場合は間違いありません)、他のほとんどのオフセットは正しくインクリメントされているように見えますが、すべてのたまにクレイジーなデータがあります。ChunkLocations のデータは次のようになります。

346256
379028
-2147071848
444556
477328
510100

-2147071848 の場合、圧縮/圧縮の欠如を示すために MSB が反転したように見えます。

質問: MSB が圧縮の存在を示すために使用されている場合、実際には 31 ビット数で扱っていますよね?
1. オフセット値を計算する際に、MSB を無視して 31 ビット数を計算するにはどうすればよいですか?
2.これは奇妙な標準のようです。なぜなら、それはあなたが持つことができるオフセットのサイズを大幅に制限するように思われるからです。e01 ファイル内のこれらの場所に移動すると、これらのオフセットが正しいように見えます。

助けてくれてありがとう!

4

2 に答える 2

3

この種のことは、バイナリ形式を扱う場合によく見られます。dtb が指摘したように、31 ビットは、最大 2 GiB のオフセットに対応できるため、このアプリケーションにはおそらく十分な大きさです。そのため、余分なビットをフラグとして使用してスペースを節約します。

ビット単位の AND を使用してビットをマスクするだけです。

const UInt32 COMPRESSED = 0x80000000;   // Only bit 31 on

UInt32 raw_value = 0x80004000;          // test value

bool compressed = (raw_value & COMPRESSED) > 0;
UInt32 offset = raw_value & ~COMPRESSED;

Console.WriteLine("Compressed={0}  Offset=0x{1:X}", compressed, offset);

出力:

Compressed=True  Offset=0x4000
于 2013-01-06T20:49:31.177 に答える
1

先頭のビットだけを取り除きたい場合は、0x7FFFFFFF を使用して値のビットごとの AND (&) を実行します。

于 2013-01-06T20:51:21.203 に答える