メモリに基本競合がある場合、再配置が必要です。ダイナミックリンクライブラリがコードセクションを特定のメモリ空間にロードしたいが、別のモジュールにすでにアクセスしている場合は、別の場所にロードする必要があります。しかし、それを別のアドレス空間にロードすることによって、ライブラリが参照しているすべての絶対参照が失われます。たとえば、実行可能ファイルにint dummy;
というグローバル変数があり、変数が0x602315にあるとします。この変数が書か/アクセスされるたびに、プログラムは(あなたが言及したエントリと同じコードが0x524BBEに位置していると仮定し、)は、次のオペコードを実行します。
0x524BBE: MOV EAX, DWORD PTR DS:[0x602315];//move dummy to eax register to do stuff
ライブラリが異なるにロードされると0x602315は既にアドレス空間0x602315が他のモジュールによって取得されているため、変数を指しません。したがって、この問題を回避するには、PEローダーに変位(|new base address-expected base address|
)を加算/減算するようにこの値(0x602315)を通知する必要があります。これを行うために、各PEには再配置テーブルと呼ばれるテーブルが含まれています。このテーブルには、この変数を参照するコード内のすべてのオフセットが含まれています。
だから、0x524000(予想ベースオフセット)の代わりに、ライブラリが0x700000でロードされたとします。
0x700BBE: MOV EAX, DWORD PTR DS:[0x7DE315];//move dummy to eax register to do stuff
:その後、何をするかPEローダがロードされたコードは次のようになりますよう、テーブル内のエントリを検索し、オフセット(0x602315)への変位を(0x700000-0x524000 = 0x1DC000)を追加で
これは変数dummy
の正しい場所を指しているため正常に動作します。
質問に戻ると、objdumpの出力にはこのテーブルの各エントリが表示されています。 92はおそらくエントリのインデックスを意味し、BC0は変数にアクセスするコードの相対アドレスであり、[524BC0]は相対アドレス+期待ベースオフセットの結果になります。 HIGHLOWは再配置の一種にすぎません(これは将来の使用のために本質的に予約されています)。現在、再配置(HIGHLOW)タイプが1つしかないため、他のタイプについて心配する必要はありません。ローダーがこのエントリを読み取ると、この変更を反映するために0x524BC0の値が変更されます。
.reloc
テーブルで構成されたPEの大半のスペースについてのご質問は、です。これはに依存しています。プログラムがグローバル変数や定数に頻繁にアクセスすると、ローダーが更新する必要がある場所が膨大になるため、巨大な再配置テーブルが必要になります。
移転。いいえ、本当に。 –
@Ignacio Vazquez-Abrams、あなたは詳しく述べることができますか? –
リロケーションアイテムで構成されたマルウェアサンプル(明示的なコードやデータはありませんが、代わりに再配置のシーケンスが同じメモリ位置に繰り返し適用されて最終的な値を形成します)がありますが、コード+データは再配置の回数を超えています。イメージが要求されたアドレスにロードできない場合、メモリ内の絶対アドレスを参照する値には、対応する再配置項目が必要です。 –