すべてのDllが競合しないベースアドレスを持っていることを確認することは、今日ではどのように重要ですか?
レイモンド
月20日, 2017
当時、あなたが勧めたことの1つは、Dllをリベースして、すべてのアドレス範囲がオーバーラップしないようにし、ランタイムの再配置のコストを回避するこ これは今日でも重要ですか?
この状況は、良いアドバイスが悪いアドバイスになったときに伝えることができるように、理論的根拠を持って来ることがどのように重要であるかを示すもう一つのデモンストレーションです。
リベースの根拠は次のようになります:DLLが優先ベースアドレスでロードされている場合、修正を必要とせずにバッキングストアから直接イメージをペー これは、各プロセスが同一のコピーを取得するため、ページをプロセス間で共有できることを意味します。 (もちろん、誰かがページに書き込み、そのコピーを共有コピーとは異なるものにすると、共有は停止します。)
DLLがその優先アドレスでロードできない場合、イメージは再配置され、再配置されたDLL全体がページファイルによってバックアップされます。1これは、DLLをディスクから読み込んで固定する必要があり、固定されたページを書き込むスペースがあることを確認するために、ページファイルへのコミッ さらに、2つのプロセスがDLLを再配置し、偶然にそれらを同じ場所に再配置すると、Windows NTは再配置されたイメージを共有しようとしません。 ページファイルには複数のコピーがあります。
この動的な再配置のコストは、リベースが回避しようとするものです。 これを”移転ペナルティ”と呼びましょう。”
ASLRを入力します。
ASLRは、dllを擬似ランダムなアドレスにロードします。 その結果、DLLは、驚くべき偶然の場合にのみ、その優先ベースアドレスでロードされます。さて、それがまだ適用されるかどうかを確認するために理論的根拠に戻りましょう。
DLLが優先ベースアドレスから離れてロードされている場合、再配置のペナルティが発生しますか? あなたがそれについて考えるならば、ASLRはDLLがその優先アドレスにロードされることはないことを意味しますが、aslrを受けたDllがまだページを共有できるようにカーネルがこのための調整を行い、最初のロード時にDLL全体を強制的に再配置することなくそうすることもわかりました。 したがって、DLLがASLRによって再配置された場合には、再配置のペナルティはありません。
しかし、DLLが他の理由で再配置された場合はどうなりますか? たとえば、ASLRが選択したベースアドレスは、プロセスがその場所にすでに何かを割り当てているため、プロセスでは使用できない可能性があります。 その場合、伝統的な移転が行われなければならず、移転のペナルティを支払う必要があります。
ああ、しかしここに事があります:DLLがロードされると、ASLRはまだ使用されていない利用可能なベースアドレスの中からランダムにベースアドレスを割ASLRが利用可能なベースアドレスの中からDLLのベースアドレスを選択するため、「ASLRが選択したベースアドレスは利用できません」シナリオには入りません。3
さて、あなたはまだ紛争状況に入ることができますが、あなたは本当にそれで働かなければなりません。 たとえば、DLLを1つのプロセスにロードし、ASLRに割り当てられたベースアドレスを取得できます。 次に、2番目のプロセスを開始し、そのアドレスに意図的にメモリを割り当てて(衝突を強制するために)、DLLをロードします。 この場合、ASLRがDLLを置きたい場所にしゃがんだため、再配置があります。 しかし、これはあなたがASLRの前に持っていたものよりも悪いことではありません:ASLRの前の世界では、DLLの優先ベースアドレスにしゃがんで、とにかく再配置
だから、話が何であるかを見てみましょう。 リベースするか、リベースしないか?
ASLRが存在する場合、ASLRはベースアドレスを無視し、DLLを擬似ランダム選択の場所に再配置するため、Dllをリベースしても効果はありません。
気にしてください、リベースは効果がないにもかかわらず、それも傷つけません。
ASLRのないシステムを使用している場合(ASLRより前のシステム、または何らかの理由でASLRが無効になっているため)、従来の理由からリベースが役立ちます。
あなたを気にして、ASLRのないシステムは、今日では本当に見つけるのが難しいので、リベースは圧倒的多数のケースでは利益を提供しません。 しかし、あなたがASLRを持っていない場合のその消滅するほど小さな割合では、リベースが役立ちます。
結論:念のためにリベースすることは害はありませんが、ペイオフは非常にまれであることを理解しています。 /DYNAMICBASE
を有効にして(および適切な対策のために/HIGHENTROPYVA
を使用して)DLLをビルドし、ASLRにベースアドレスの衝突が発生しないようにする作業をさせます。 それは現実世界のシナリオのほとんどすべてをカバーします。 ASLRが利用できない非常にまれなケースの1つに陥った場合でも、プログラムは引き続き機能します。 それはちょうど移転のペナルティのために少し遅く実行されるかもしれません。
1より正確には、フィックスアップを含むすべてのページがページファイルに入れられます。 前回はこの細かい点について議論しました。
2さて、ASLRが単にベースアドレスを使い果たしている場所である第三のケースがあります。 しかし、再び、これはあなたがASLRの前に持っていたものよりも悪いことではありません:あなたがベースアドレスを使い果たした場合、それは自分のた 新しいDLLがロードされるたびに、カーネルはDLLをロードするのに十分な大きさの利用可能なアドレス空間のチャンクを探し回る必要があります。
3その結果、ASLRはシステム全体を表示できるため、ASLRは実際には手動リベースよりも衝突を回避する優れた仕事をしますが、手動リベースではプロセスにロードされているすべてのDllを知る必要があり、複数のベンダー間でベースアドレスを調整することは一般的には不可能です。
レイモンド-チェン
フォロー
Leave a Reply