2

以前objdump -x ...は、PE ファイルのセクションをチェックしていました。

約 90,000 行の reloc エントリがあります。

reloc   92 offset  bc0 [524bc0] HIGHLOW
reloc   93 offset  bc4 [524bc4] HIGHLOW
    ....

ほとんどの PE ファイルの大部分のスペースが上記のような reloc エントリで構成されているというのは本当ですか?

それらのエントリは何のためですか?

アップデート

上記のように再配置エントリがどのように機能するかを説明できる人はいますか?

4

1 に答える 1

12

メモリにベースの競合がある場合、再配置が必要です。ダイナミック リンク ライブラリがそのコード セクションを特定のメモリ空間にロードしたいが、別のモジュールによって既に占有されている場合は、別の場所にロードする必要があります。ただし、別のアドレス空間にロードすると、ライブラリが参照していたすべての絶対参照が台無しになります。たとえば、実行可能ファイルに というグローバル変数がint dummy;あり、その変数が 0x602315 にあるとします。この変数がアクセス/書き込まれるたびに、プログラムは次のオペコードを実行します(コードが0x524BBEにあると仮定すると、あなたが言及したエントリと同じです):

0x524BBE: MOV EAX, DWORD PTR DS:[0x602315];//move dummy to eax register to do stuff

ライブラリが別の空間にロードされると、アドレス空間 0x602315 が他のモジュールによって既に使用されているため、0x602315 は変数を指しません。|new base address-expected base address|したがって、この問題を回避するには、この値 (0x602315) に変位 ( ) を加算/減算するように PE ローダーに指示する必要があります。これを行うために、各 PE には再配置テーブルと呼ばれるテーブルが含まれており、このテーブルには、この変数を参照するコード内のすべてのオフセットが含まれています。

したがって、0x524000 (予想されるベースオフセット) の代わりに、ライブラリが 0x700000 にロードされたとしましょう。次に、PE ローダーが行うことは、テーブル内のエントリを検索し、オフセット (0x700000-0x524000=0x1DC000) をオフセット (0x602315) に追加して、ロードされたコードが次のようになるようにすることです。

0x700BBE: MOV EAX, DWORD PTR DS:[0x7DE315];//move dummy to eax register to do stuff

変数の正しい場所を指しているため、正常に実行されますdummy

質問に戻ると、objdump の出力には、このテーブルの各エントリが表示されています。92 はおそらくエントリのインデックスを意味し、BC0 は変数にアクセスするコードの相対アドレスです。[524BC0] は相対アドレス + 予想されるベース オフセットの結果です。HIGHLOW は単なる再配置のタイプです (これは基本的に将来の使用のために予約されています。現在、使用されている再配置のタイプ (HIGHLOW) は 1 つだけなので、他のタイプについて心配する必要はありません)。ローダーがこのエントリを読み取ると、この変更を反映するために 0x524BC0 の値が変更されます。

.relocテーブルで構成された PE の大多数のスペースについての質問に対して、答えはそれ次第です。プログラムがグローバル変数と定数に頻繁にアクセスする場合、ローダーが更新しなければならない場所が非常に多いため、巨大な再配置テーブルが作成されます。

于 2011-05-23T04:16:42.143 に答える