web-dev-qa-db-ja.com

プログラムは、プロセスメモリの特定の領域へのメモリアクセスをトラップできますか?

プログラムのメモリの特定の読み取り専用セクションにアクセスするときに、イベントがトリガーされてトラップされるようにする方法を探しています。具体的には、多数の定数値(読み取り専用)を含むプログラムメモリのセクションがあり、それらの値のいずれかにアクセスしたときにイベントをトラップしたい場合、イベントハンドラーは何らかの処理(ある種の拡張)を実行できますデータに)、代わりに拡張値を返します。だから、私はいくつかの質問があります:

  1. これは可能ですか?
  2. もしそうなら、どのようにそれを行うのですか?
  3. どのような種類の特権が必要になりますか(別のプロセスメモリにアクセスする必要はありません)?
  4. 使用できるテクニックに関するドキュメントはありますか?

アップデート1

ここにもう少し情報がありますが、私はまだ正確に詳細を理解しようとしています。

私がやろうとしているのは、プログラムで、またはコンパイル/リンク時に、メモリの領域(おそらく1ページ以上)にマークを付けて、アクセスするとイベントがトリガーされ、作成したイベントハンドラーが呼び出されるようにすることです。イベントの原因となった問題を「修正」して、アクセスしようとしていた値を返すことができます。目標は、実行中のコードを取得できるようにすることです。問題のメモリにアクセスしようとすると、イベントハンドラーが呼び出され、アクセスが解決され、アクセスが修正/修正された元のコードに戻ることができます。元のコードを変更する必要はありません。 printfフォーマット文字列について考えてみましょう。イベントを呼び出してフォーマット文字列を調整または置換し、printfコードを順調に続行できるようにしたい場合です。

それは理にかなっていますか?

1
JonBelanger
  1. はい

  2. おそらくリンカースクリプトを使用して、変数をメモリの別のページに配置します。 mprotectを使用して、ページをno accessとしてマークします。 sigactionを使用してSIGSEGVのハンドラーを設定し、SA_SIGINFOを指定して、関連するアドレスに関する情報が渡されるようにします。

  3. 特別な特権は必要ありません。

  4. これは何度も行われています。オリジナルのBourneShellは、メモリ処理を行うためにSIGSEGVをキャッチしましたが、それはsigactionの時代の前でした。ハンドラーでは、問題を修正して戻るために必要なことは何でもできます。通常、これには、アクセスパターンと生成されたマシンコードに関するある程度の知識が必要です。

1
icarus