問題タブ [ld-preload]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - mkdir を LD_PRELOAD で上書きする
システムコール mkdir() を変更して、ディレクトリを作成させたくない一部のユーザーをフィルタリングしようとしています。これは最もエレガントな方法ではないかもしれませんが、なぜ機能しないのか知りたいです。
mkdir() の置き換えコードは次のとおりです。
-Wall -std=c99 -fPIC -lconfig -ldl -shared でコンパイル
mkdirバイナリで使用すると、完全に機能します
LD_PRELOAD=wrapper.so /bin/mkdir ディレクトリ
しかし、私がこのように使用すると:
LD_PRELOAD=wrapper.so bindfs AB my mkdir() は使用されません。
この実装を試してみましたが、私のニーズをカバーしていませんが、binfs で動作します
c - LD_PRELOAD と弱い参照の最小限の例が機能しない
これはおそらく恥ずかしいでしょう:
私は他のプロジェクトでライブラリのプリロードを使用していますが、この最小限の例を機能させることができません:
弱参照.h:
弱いref.c:
test_weakref.c:
これが私がすることです:
最後のコマンドの期待される出力は
私は何が欠けていますか?
c++ - fstream での LD_PRELOAD の使用
LD_PRELOAD を使用してオーバーロードsystem()
などfopen()
を行っています。 fstream を独自の実装に置き換えたいのですが、どこから始めればよいかわかりません。Web を検索しましたが、クラスの一部または全体のオーバーロードに関する良い例が見つかりません。どんな助けでも大歓迎です。
ありがとう。
linux - ハードコーディングされたファイルシステムのパスを透過的に調整するにはどうすればよいですか?
さまざまなファイルシステム パスをハードコードするコンパイル済みプログラムを実行する必要があり、それらのパスには異なる値が使用されます。実際的な理由から、プログラムのソース コードを調整して再コンパイルすることはできません。さらに、ハードコードされたファイルをシンボリックリンクに置き換えたり、ハードコードされたファイルを他の方法で変更したりすることは認められません。
LD_PRELOAD フックとバイナリへのパッチの 2 つの解決策しか思いつきません。前者はより簡単で信頼性が高いようです。より良い解決策、またはこの問題を解決することを目的とした既存のソフトウェアはありますか?
PS私は恐ろしいハックについて話していることを知っています. 問題のハードコードされたソフトウェアは、Linux ディストリビューションで広く配布されていますが、完全にメンテナンスされていないように見えます。また、私が許容できる時間内にパッチを配布するどころか、ディストリビューションにパッチを適用する可能性もありません。
macos - 任意のプログラムにシグナルを無視させることは可能ですか?
特に Mac OS X では、プログラムが DYLD_INSERT_LIBRARIES を介して SIGTERM を無視するようにすることは可能ですか?
これをコンパイルして挿入しようとしました:
でも、
問題なく kill -15 できました。
c - LD_PRELOAD フリー/malloc/realloc/calloc フリーが機能しない
malloc/calloc/realloc/free 関数を書き直しています。今のところ、私はmallocを終了し、テストのために、次のような「無料」関数を書きます:
そして、さまざまなソフトウェアで機能をテストし、ls/firefox/man で動作します...
しかし、GIMPのようなソフトウェアを使用すると、次のことができます:
SO、何もしない無料でこの問題が発生する理由がわかりません。(私の無料の関数が呼び出され、「printf」でテストしました)
誰かがそれがどこから来たのか知っていますか?
読んでくれてありがとう
linux - LD_PRELOAD を使用してアプリケーションにバックグラウンド スレッドを挿入するにはどうすればよいですか?
LD_PRELOAD を使用して、共有ライブラリ内の関数の呼び出しをインターセプトできることを知っています (アプリが静的にリンクされていない場合)。ただし、追加機能やバックグラウンド スレッドをアプリケーションに追加するためにどのように使用できるかはわかりません。
たとえば、バークレー研究所のチェックポイント/再起動では、このメソッドを使用して、後でチェックポイントが設定される可能性のあるバックグラウンド スレッドをアプリケーションに追加していると思います。
では、問題は、どの共有ライブラリの関数がこのアプリから呼び出されているかを事前に知らずに、LD_PRELOAD を使用してコンパイル済みのアプリにスレッドを挿入する方法です。
c++ - 静的ライブラリを共有ライブラリにリンクし、エクスポートされたシンボルを非表示にします
リンカーに厄介な問題があります。いくつかのシンボルを共有ライブラリから静的ライブラリにリンクしたいが、そのシンボルをエクスポートしたくない (つまり、単純にライブラリをマージしたり とリンクしたりすることはできない--whole-archive
)。私が欲しいのは、共有ライブラリを静的なものにリンクし(実行可能ファイルをリンクする、未定義のシンボルを解決するなど)、未定義のシンボルを削除することです。
私が探しているのはおそらく単なるリンカー オプションですが、指を置くことはできません。
問題をできる限り説明し (それほど簡単ではありません)、おもちゃで最小限の例を示して遊んでみます。
編集:問題は解決されました。解決策は質問の最後に投稿されました
簡単な説明:
LD_PRELOAD
このトリックを使用して、一部の関数呼び出しを実行可能ファイルにトラップしたいと考えています。この実行可能ファイルは、トラップしたい関数の関数定義を含むサード パーティの共有ライブラリに対してリンクされています。
このサードパーティのライブラリには、別のライブラリのシンボルも含まれています。これは、自分のライブラリでも使用していますが、別の (互換性のない) バージョンです。
私がやりたいことは、共有ライブラリをコンパイルし、コンパイル時にシンボルをエクスポートせずに最後の (静的) ライブラリの定義とリンクして、共有ライブラリがトラップしたいバージョンとは異なるバージョンを使用するようにすることです。
簡素化された問題の説明
というサードパーティ ライブラリlibext.so
がありますが、そのソース コードはありません。これは関数を定義し、別のライブラリbar
の関数を使用しますが、シンボルは両方ともそこで定義されています。foo
前述foo
したように、新しいバージョンを使用したい外部依存関係です。私はそれのために更新されたライブラリを持っています、それを呼びましょうlibfoo.a
:
問題は、 を再定義する動的ライブラリを作成したいのですが、ライブラリでfrombar
の定義を使用し、 from の関数でfromの関数を呼び出したいことです。言い換えれば、ライブラリのコンパイル時のリンケージが必要です。foo
libfoo.a
libext.so
foo
libext.so
libfoo.a
私が探しているのはlibfoo.a
、シンボルを使用するがエクスポートしないライブラリを定義することです。ライブラリを にリンクするとlibfoo.a
、次のようになります。
つまり、 と の両方をオーバーロードfoo
しbar
ます ( をオーバーライドしたくありませんfoo
)。ライブラリをlibfoo.a
にリンクしないと、次のようになります。
したがって、私のライブラリは のバージョンを使用しますがfoo
、これも望ましくありません。私が欲しいのは:
コンパイルfoo
時にリンクされ、そのシンボルはエクスポートされません。
最小限の例
これを読む必要はありませんが、これを使って遊んで解決策を見つけることができます。
bar.cpp
: コードを持っていないサードパーティのアプリを表します:
foo.cpp
: 私のライブラリとサードパーティの両方で使用される関数の新しいバージョンを表します:
trap.cpp
:私のライブラリからのコード、それはトラップbar
し、新しいものを呼び出してfoo
転送します:
exec.cpp
: 呼び出すダミーの実行可能ファイルbar
:
Makefile
: Unix のみ、申し訳ありません
この場合、;をbar
呼び出します。foo
通常の実行は次のとおりです。
ライブラリをプリロードすると、interceptsbar
が呼び出され、myfoo
および forwardsが呼び出されますbar
。現在の実行は次のとおりです。
最後の行が間違っています。目的の出力は次のとおりです。
解決
1) 受け入れられた回答で指摘されているように、リンカー バージョン スクリプトを使用して、望ましくないシンボルのスコープをグローバルからローカルに変更できます。
リンカー バージョンのショーでのコンパイルfoo
はローカルであり、プログラムは期待どおりに動作するようになりました。
libfoo.a
2) 別の方法は、属性を使用して再コンパイルし、-fvisibility=hidden
それに対してリンクすることです。エクスポートされたシンボルの可視性もローカルであり、動作は上記と同じです。