3

Mac OS X は、dyld と呼ばれる動的ロード用の便利なライブラリを提供します。動的読み込み処理のための多くの興味深い関数の中には、画像がロードまたはアンロードされるたびに dyld によって呼び出されるコールバックをインストールできるようにする関数がありdlopenますdlclose。これらの機能はvoid _dyld_register_func_for_add_image(void (*func)(const struct mach_header* mh, intptr_t vmaddr_slide))void _dyld_register_func_for_remove_image(void (*func)(const struct mach_header* mh, intptr_t vmaddr_slide))それぞれ と です。

dyld 関数は mach-o ファイルを処理し、Linux は ELF ファイルを使用するため、Linux 用の正確なポートを持つことができないことはわかっています。

では、Linux 用の dyld ライブラリに相当するものはありますか。または、少なくとも、これら 2 つの関数に相当する と は_dyld_register_func_for_add_imageLinux_dyld_register_func_for_remove_imageライブラリにあるのでしょうか? または、これら 2 つの独自のバージョンを自分で実装する必要がありますが、それほど難しくはありませんがdlopendlcloseコールバック関数が呼び出されるたびに作成して呼び出す方法を見つける必要があります。

編集

より明確にするために、外部ライブラリが によって動的にロードされるたびに呼び出す必要があるコールバック関数を持つライブラリを作成する必要がありますdlopen。私のコールバック関数は、動的に読み込まれたライブラリに対していくつかの操作を実行する必要があります。

4

1 に答える 1

2

はい、標準ライブラリを使用して dlopen(3)と呼ばれます-ldl

より正確に:

  • フラグを使用してプラグインのソース コードをコンパイルし、-fPIC位置に依存しないコード オブジェクト ファイルを取得します。*.pic.o
  • gcc -sharedファイルとリンクして共有ライブラリ プラグインを作成し*.pic.oます (別の共有ライブラリをリンクすることもできます)。
  • GCC function attributes、特にconstructorand destructorfunctions (または明示的なコンストラクターとデストラクタを持つ静的 C++ データ、したがって名前) を使用します。の関数はプラグインの実行__attribute__((constructor))中に呼び出され、プラグインの の関数は実行中に呼び出されますdlopen__attribute__((destructor))dlclose
  • -rdynamicプラグインがメインプログラムでいくつかの関数を呼び出すとすぐに、メインプログラムを属性とリンクすると便利で必要になります。
  • extern "C"C++ プラグイン関数を宣言することを忘れないでください(プログラムに必要です)。
  • メイン プログラム内で使用dlsymして、プラグイン内の関数またはデータ アドレスをフェッチします。

実際、dlopenlike dos のフックはあり_dyld_register_func_for_add_imageません。コンストラクター関数やdl_iterate_phdr(3)を使用してそれを模倣したい場合があります。

プラグイン (共有オブジェクト) を変更できる場合は、そのdlopenようなフックを模倣するために内部でコンストラクターのトリックを実行できます。それ以外の場合は、独自の規則を使用します (たとえば、関数を持つプラグインmodule_startはそのmodule_start関数を直後に呼び出すdlopenなど...)。

dlopen一部のライブラリは、より高いレベルのものにラップされています。たとえば、QtにはQPluginLoaderQLibraryなどがあります...

LD_PRELOAD トリックもありdlopenます(おそらくdlclose、そのようなトリックを使用して独自の関数を再定義し、変更した関数にフックを実行させることができます)。ifunc 関数属性も関連している可能性があります。

また、Gnu LibcはMUSL Libcも提供するフリー ソフトウェアであるため、必要に応じてパッチを適用できます。dladdr(3)も役に立つかもしれません!dlopen

補遺

Objective-C 用に独自のランタイムを作成している場合は、そのランタイムを使用する Objective-C コンパイラの規則をよく知っている必要があります。おそらく、オーバーロードする代わりに独自のモジュール ローダーを使用できますdlopen

于 2013-03-29T12:51:52.540 に答える