3

状況は次のとおりです。

ioctl()システムコールをフックするLD_PRELOADedモジュールを使用して、プログラムとドライバーの相互作用を分析しています。私が使用しているシステム(組み込みLinux 2.6.18カーネル)は、幸いにも「request」パラメーターにエンコードされたデータの長さを持っているので、適切な長さでioctlデータをうまくダンプできます。

ただし、このデータのかなりの部分に他の構造へのポインターがあり、これらの長さはわかりません(結局、これが私が調査しているものです)。そのため、データをスキャンしてポインターを探し、その位置にデータをダンプしています。ポインターがセグメント境界に近い場合、これによってコードがsegfaultsにさらされる可能性があるのではないかと心配しています(初期のテストでは、これが当てはまるようです)。

それで、逆参照を試みる前に、現在のプロセスが特定のオフセットを所有しているかどうかを先制的にチェックするために何ができるのか疑問に思いましたか?これも可能ですか?

編集:非常に重要な可能性があることについて言及するのを忘れたので、更新しました。ターゲットシステムはMIPSベースですが、x86マシンでモジュールもテストしています。

4

4 に答える 4

3

にファイル記述子を開いて、/dev/nullを試してくださいwrite(null_fd, ptr, size)errnoに設定して-1を返す場合EFAULT、メモリは無効です。が返された場合size、メモリは安全に読み取ることができます。いくつかのPOSIXの発明を使用して、メモリの有効性/許可を照会するためのより洗練された方法があるかもしれませんが、これは古典的な単純な方法です。

于 2010-11-28T19:16:52.240 に答える
1

組み込みLinuxに/proc/ファイルシステムがマウントされている場合は、/ proc / self / mapsファイルを解析し、それに対してポインター/オフセットを検証できます。マップファイルには、プロセスのメモリマッピングが含まれています。ここを参照してください

于 2010-11-28T18:56:25.800 に答える
0

私はそのような可能性を知りません。しかし、あなたは似たようなことを達成できるかもしれません。man 7 signal言及したように、捕まえるSIGSEGVことができます。したがって、私はあなたができると思います

  1. ポインタであることがわかっているバイトシーケンスの逆参照から始めます
  2. 次々にアクセスし、ある時点でトリガーしますSIGSEGV
  3. SIGSEGVのハンドラーで、ステップ2のループでチェックされる変数をマークします。
  4. ループを終了します。このページは完了です。

それにはいくつかの問題があります。

  • 複数のバッファが同じページに存在する可能性があるため、実際には複数の1つのバッファであると思われるものを出力する場合があります。電気柵を使用することで、これを支援できる場合がありますLD_PRELOAD。これにより、AFAIKにより、動的に割り当てられたすべてのバッファーにページ全体が割り当てられます。したがって、1つだけだと思って複数のバッファを出力することはありませんが、バッファがどこで終了するかはわかりません。最後に大量のガベージが出力されます。また、スタックベースのバッファはこの方法では役に立ちません。
  • バッファがどこで終了するかわかりません。

テストされていません。

于 2010-11-28T18:41:28.610 に答える
0

セグメントの境界を確認するだけではいけませんか?(私はあなたがページ境界を意味するセグメント境界によって推測していますか?)

その場合、ページ境界は適切に区切られているため(4Kまたは8K)、アドレスを単純にマスキングすることで対処できます。

于 2010-11-28T19:33:05.920 に答える