8

私は現在、いくつかのシステムコールと、、、などの低レベル関数の使用状況を追跡する必要があるプロジェクトに取り組んでmmapbrkますsbrkmmapこれまで、関数の介在を使用してこれを行ってきました。たとえば、置き換える関数と同じ名前のラッパー関数を記述し、LD_PRELOAD環境変数を設定してプログラムにロードします。でロードするポインターを介して実際の関数を呼び出しますdlsym

残念ながら、ラップしたい関数の1つである、sbrkは、によって内部的に使用されdlsymているため、シンボルをロードしようとするとプログラムがクラッシュします。sbrkLinuxではシステムコールではないので、単にsyscall間接的に呼び出すために使用することはできません。

だから私の質問は、使用せずに同じ名前のラッパー関数からライブラリ関数を呼び出すにはどうすればよいdlsymですか?元の関数を参照できるコンパイラのトリック(gccを使用)はありますか?

4

4 に答える 4

15

ldのオプションを参照してください--wrap symbol。マニュアルページから:

--wrapsymbolシンボルのラッパー関数を使用します。シンボルへの未定義の参照はすべて" __wrap_symbol"に解決されます。""への未定義の参照は__real_symbol、シンボルに解決されます。

これは、システム関数のラッパーを提供するために使用できます。ラッパー関数は「__wrap_symbol」と呼ばれる必要があります。システム関数を呼び出したい場合は、「__real_symbol」を呼び出す必要があります。

簡単な例を次に示します。

void *
__wrap_malloc (size_t c)
{
    printf ("malloc called with %zu\n", c);
    return __real_malloc (c);
}

--wrap mallocを使用して他のコードをこのファイルにリンクすると、「」へのすべての呼び出しは代わりにmalloc関数「」を呼び出します__wrap_malloc
""の" __real_malloc"__wrap_mallocを呼び出すと、実際の" malloc"関数が呼び出されます。

__real_malloc--wrapオプションのないリンクが成功するように、「」関数も提供することをお勧めします。これを行う場合は、「」の定義を「__real_malloc」と同じファイルに入れないでください__wrap_malloc。そうした場合、リンカが呼び出しを「malloc」にラップする前に、アセンブラが呼び出しを解決する可能性があります。

他のオプションはおそらくltraceのソースを調べることです、それは多かれ少なかれ同じことをします:-P。

ただし、ここにアイデアがあります。LD_PRELOAD'edライブラリにPLTエントリを変更して、コードを指すようにすることができます。これは技術的には、sbrk()関数はコードから自然に呼び出すことができます。

于 2009-06-15T21:28:12.610 に答える
2

次のようなツールを使用して、目立たないように関数の呼び出しを調べることができます。

  • gdb
  • ltrace
  • systemtap

これらのツールを使用すると、監視プログラムは関数が呼び出されたときに通知し、引数を調べることができます。

主な違いは次のとおりです。

  • gdbはインタラクティブですが、強力です
  • ltraceは簡単に使用できますが、出力できるのは関数名のみです。
  • systemtapはインタラクティブではありませんが、非常に高速で強力です。
于 2009-06-15T21:36:31.327 に答える
0

glibcでホストシステムを実行している場合、libcには、以前使用したランタイムダイナミックリンカーへの内部バックエンドがあります。正しく思い出せば、「__libc_dlsym」と呼ばれていると思います。(確認するには、 "$ readelf -s /usr/lib/libc.a | grep dlsym"が役立ちます。)dlsymと同じ引数と戻り値を持つ外部リンク関数として宣言し、それを使用してdlsym自体をラップします。

于 2009-08-14T03:34:44.507 に答える
0

お使いのシステムで動作しませtrussんか?これは、Solarisでこの種のことに対して完全に機能します。

于 2011-06-21T19:32:23.483 に答える