2

そのため、Linux では、gcc でコンパイル/リンクされた C++ プログラムの実行可能ファイルが読み込まれると、次のことが起こります。

  1. exec* システムコール
  2. ロードされた LD 動的ライブラリー
  3. C++ 静的初期化
  4. メインのエントリーポイント

プロトタイプを使用した関数があるとしますvoid f()

ステップ 1 と 2 の間で実行されるように、実行可能ファイルを f にリンクする (ソースの変更、属性、コンパイラ/リンカー オプションなどを介して) 方法はありますか?

ステップ2と3の間はどうですか?

(明らかに、これを行う標準的な方法はありません。最近のバージョンの gcc/linux/x86_64/glibc/binutils に対して、プラットフォーム固有、コンパイラ固有の方法を求めています)

4

2 に答える 2

2

はい、(1) と (2) の間、または (2) と (3) の間でこれを行うことができます。ステップ 2 「ld 動的ライブラリーのロード」は、実際には動的リンカーを呼び出すことによって行われld.soます。通常、これは/lib64/ld-linux-x86-64.so.2または同様です。glibc の一部です。ただし、パスは実際には実行可能ファイルで指定されているため、任意のパスを使用できます。

$ readelf -l `which bash`
⋮
Program Headers:
⋮
  INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238
                 0x000000000000001c 0x000000000000001c  R      1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

⋮

これはLD_PRELOAD/のようなことを行うことに加えてLD_AUDITです。

(2) と (3) の間では、エントリポイントのアドレスを変更したいだけのように思えます。

于 2012-05-24T16:56:37.217 に答える
-1

基本的にいいえ。execve()システムコールは環境を消去します。アドレス空間で何をしても、新しいアドレス空間に生き残る方法はありません。ファイル記述子 (もちろん、CLOEXEC のフラグが付いたものを除く) を新しいプロセスに送信することが許可されており、環境を介して引数を渡すことができます。

...これは、あなたが望むことをするかもしれない何かをあなたに与えます。LD_PRELOAD を設定して、ターゲット実行可能ファイルからコードが実行される前、および共有リンカーによってシンボルが解決される前に、共有ライブラリを「最初に」ロードすることができます。これがあなたの要件を満たしているかどうかは、あなたの質問からは明らかではありません。

于 2012-05-24T16:51:37.657 に答える