0

TL;DR

リンカーが間違った決定を下すため、正しいアドレスを指すように上書き したいと考えています。.got, .got.plt,...


コードで2 つの異なる動的割り当て関数 (つまり、malloc(),...) を使用する必要があります。プログラムの実行中に何らかの条件に基づいて適切なものが選択されます。したがって、私は 2 つのglibcインスタンスを提供し、LD_PRELOADトリックを使用しました。LD_PRELOAD値は次のようなものです。

LD_PRELOAD=multiplexer_library.so:glibc1.so:glibc2.so

ここでmultiplexer_library.so、正しいライブラリを選択します。glibc1.soを使用dlsym(RTLD_NEXT, "malloc")glibc2.soてアクセスし、dlopen()その後にを使用してアクセスしますdlsym()。同じことが言えますcalloc(),...

問題は、2 番目の malloc が最初のmalloc に干渉することです。これは、後者のすべての動的再配置がリンカーによって前者にマップされるために発生します。たとえば、がグローバル関数ポインタを呼び出すと、とそのターゲット ( の関数) にマップされます。このグローバル変数の再配置エントリは次のとおりです。glibc2.somorecoremorecore__default_morecore()glibc1.soglibc2.so

0000003addc0  085600000006 R_X86_64_GLOB_DAT 00000000003af4d8 __morecore@@GLIBC_2.2.5 + 0

で実行をトレースしましたPin1370を超える再配置エントリのうち125が、動的割り当て中に私のコードでアクセスされました。たとえば、重要なエントリは、動的割り当ての境界を決定するグローバル変数です(システム コール レベルでライブラリごとに分離されたbrk 領域を提供したことに注意してください)。両方のアロケーターが同じ を使用するため、これは明らかに割り当てを破損します。inの再配置エントリを以下に示します。__curbrkbrk__curbrk__curbrkglibc1.so

0000003adeb8  044400000006 R_X86_64_GLOB_DAT 00000000003b10b8 __curbrk@@GLIBC_2.2.5 + 0

これらの競合する名前の名前を変更しようとしましたが、125膨大であり、コードを把握するのは困難です。ネストされたマクロでいっぱいであるため、手動の名前変更ソリューションは実際には実行不可能です。

IIUC では、再配置エントリごとに、リンカーターゲットの再配置アドレスを配置するメモリ アドレス(たとえば のどこかに.got,...)が存在し、このアドレスは共有ライブラリ専用です。そのアドレスをTARGET HOLDERと呼びます。たとえば、この場合、リンカーは の変数の実行時アドレスをと の両方でのターゲット ホルダーに配置しました。これが正しければ、実行時に値を更新する必要があります__curbrk__curbrkglibc1.so__curbrk glibc1.soglibc2.soの変数の実行時アドレスを保持する__curbrkinのターゲット ホルダー。この問題を完全に解決するには、によってアクセスされる125 個の再配置エントリすべてに対してこれを行う必要があります。出来ますか?glibc2.so__curbrkglibc2.somalloc(),...

どんな助けでも大歓迎です!

4

1 に答える 1