ソースコードなしでx86 C++アプリケーションを監査(リバースエンジニアリング)しています。静的分析により、アプリケーションがほとんどすべての場合にIsBadReadPtr
およびIsBadWritePtr
Win32関数を使用して、関数パラメーターを確認していることが判明しました。したがって、これらの2つの関数は、アプリケーションにあるほとんどすべての関数から呼び出されます。
IsBadXXXPtr関数は使用しないでくださいと言って、次の投稿を見つけました。上記の機能を使用することのセキュリティリスクを理解できませんでした。誰かに説明してもらえますか?
TL; DR
それらが悪い理由は、あなたが提供したリンクにリストされています。 Windows OSの設計方法、関数のコーディング方法、およびメモリが有効かどうかを判断することが難しいため、これらの関数は本質的に不安定になり、使用できません。
ポインタがメモリの有効な部分を使用しているかどうかを判断する良い方法はありません。解放されたメモリは、必ずしもゼロ化またはリセットされるわけではありません。不正なポインタが浮かんでいる場合、それはメモリの有効な部分にあるデータを指す可能性があります。ポインタを逆参照できるからといって、データ自体が有効であるとは限りません。
これら2つの関数は、ページガード例外を使用して、メモリが有効かどうかを判断します。これらの例外の設計は、「有効なメモリアドレス」チェックとして使用することを想定していません。最初のリンクで説明されているように:
IsBadXxxPtr関数は例外をキャッチし、「無効なポインタ」を返します。ただし、ガードページの例外は1回だけ発生します。あなたはたった一度のチャンスを吹き飛ばしました。ガードページを管理しているコードが初めて(実際には2回目)と思っているメモリにアクセスすると、ガードページの例外は発生せず、通常のアクセス違反が発生します。
基本的にこれらの関数を使用しても、Windows OSの全体的な設計とこれらの関数のコーディング方法が原因で、アクセス違反が発生する可能性があります。ページガードを使用していない場合でも、ロードしている他の共有ライブラリがページガードを使用していないという保証はありません。
物事がひどく間違っていることを伝えようとしているOSからの例外をキャッチしようとするのは悪い考えです。どこかにプログラミングエラーがあり、クラッシュするのが最善の方法です。物事がうまくいかないときに良い状態に戻ろうとすると、不確定な動作を引き起こす可能性があります。
肝心なのは、メモリの問題を修正できないことです。実行を継続すると、後でやけどするだけです。