2017-10-01 10 views
0

mmapとmunmapにフックしたいと思います。通常、メモリアロケータ関数でlibcの中で呼び出されます。 1つの方法はLD_PRELOADです - これをプログラムで行うにはどうしますか?アプリケーションからではなく、libc内のmmap/munmapにフックしたいのです。フックmmap/munmap without LD_PRELOAD

+0

Linuxでは、 'ptrace'を使用してください... –

答えて

1

LD_PRELOADは、アロケータに関連する関数の小さなセット(mallocfreeなど)に対してglibc内の関数呼び出しのみをリダイレクトできます。特にシステムコールはインライン展開されることが多いため、関数呼び出しはまったく必要ありません。 Antti Haapalaが言ったように、ptraceを使用するか、systemtapまたは手作業で書かれたカーネルモジュールを使用することもできます。

0

これをプログラムで実行するにはどうすればよいですか?

ありますが、それほど美味しくありません。

あなたはCALL __mmap命令、つまり探して、libc.so.6.textを走査することができる:次の命令と__mmap間のデルタに等しい4つのバイトが続く0xE8(または他のCALLオペコード)。

このような命令を見つけたら、mprotectページを書き込み可能にしてCALLに別のルーチンをパッチし、mprotectに戻します。

いくつかの欠点があります。

  1. これはハックです。
  2. パッチ適用中に同時に実行されるスレッドがないようにすることをお勧めします。
  3. malloc(またはパッチ適用中のコードと呼ぶことができるもの)に電話をかけないようにしてください。
  4. 偽陽性が可能です(CALLのようなバイトシーケンスは、実際にはCALLではありません)。私のexpirienceでこれは決して起こった。
  5. 64ビットプロセスでは、ターゲットルーチンはCALLから離れている可能性があり、オフセットは、CALL命令に埋め込むことができます。これを解決するには、トランプラインにCALLを入れてください。の内部にlibc.so.6の十分な長さのシーケンス内に設定することができます;トランポリンは任意のアドレスにJMPを実行できます)。

私はこれがきれいではないと言いましたか?

もう1つの方法は、__mmap__munmapルーチンをPLTで公開して独自のlibc.so.6を構築することです。これを行うためのパッチは非常に小さいですが、これはあなたが走っているどこでも独自のGLIBCビルドを使うことに依存することができる場合にのみ機能します。

0

必要なものによって異なります。 envまたはputenv()を使用していつでも代替環境を設定してから、ターゲットプログラムを実行することができます。同様に、gdbを使用してプロセスにブレークポイントを追加することもできます。

あなたの本当の仕事を説明してみませんか?