9

動的にリンクされたELFバイナリがあり、特定のライブラリ呼び出しをオーバーライド/リダイレクトしたいとします。でこれを実行できることはわかっていますLD_PRELOADが、環境に依存せずにバイナリで永続的であり、setuid / setgidバイナリで機能するソリューションが必要ですが、いずれもLD_PRELOAD実現できません。

私がやりたいのは、追加のオブジェクトファイルからコードを追加し(必要に応じて新しいセクションで)、これらのオブジェクトファイルのシンボルをバイナリのシンボルテーブルに追加して、新しく追加されたバージョンのコードが代わりに使用されるようにすることです。共有ライブラリコード。これは、既存のコードで実際に再配置を実行しなくても可能であると思います。それらが同じファイルにある場合でも、これらは実行時に通常のPLTの方法で解決できるはずです(データではなく関数のみを気にする価値があります)。

「これはやりたくない!」という言葉に沿って答えないでください。または「それはポータブルではありません!」私が取り組んでいるのは、バイナリをわずかにABIと互換性のない代替共有ライブラリ実装とインターフェースする方法です。問題のプラットフォームは、重要な場合はi386-linux(つまり、32ビット)です。何が可能かを間違えない限り、ELFファイルを解析してハックを実行するツールをいくつか書くことはできますが、GNUリンカーやその他のツールを使用して、新しいコードを記述せずにこれを実現する素晴らしい方法があると思います。

4

4 に答える 4

5

elfsh私は他を提案します。ELFファイル自体をインストルメント化する場合は、 ERESIプロジェクトのツール。私自身も同じ目的で使っているので、i386-linuxとの互換性は問題ではありません。

関連するハウツーはここにあります。

于 2010-10-27T06:36:35.170 に答える
2

ldを呼び出す--wrapシンボルのように、特定のシンボルを置き換えることができるオプションがあります。これで、関心のある関数のスタブをいくつか作成し、それを問題のライブラリにリンクすることができます。malloc__wrap_malloc

于 2010-10-27T06:30:13.600 に答える
1

プログラム自体で動的リンクの一部を処理できます。特にdlsym(3)のマニュアルページを読み、残りのダイナミックリンクインターフェイスについてはdlopen(3)、dlerror(3)、およびdlclose(3)を読んでください。

簡単な例-libcからdup2(2)をオーバーライドしたいとします。次のコードを使用できます(「dltest.c」と呼びましょう)。

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dlfcn.h>

int (*prev_dup2)(int oldfd, int newfd);

int dup2(int oldfd, int newfd) {
    printf("DUP2: %d --> %d\n", oldfd, newfd);
    return prev_dup2(oldfd, newfd);
}

int main(void) {
    int i;

    prev_dup2 = dlsym(RTLD_NEXT, "dup2");
    if (!prev_dup2) {
        printf("dlsym failed to find 'dup2' function!\n");
        return 1;
    }
    if (prev_dup2 == dup2) {
        printf("dlsym found our own 'dup2' function!\n");
        return 1;
    }

    i = dup2(1,3);
    if (i == -1) {
        perror("dup2() failed");
    }

    return 0;
}

コンパイル:

gcc -o dltest dltest.c -ldl

静的にリンクされたdup2()関数は、ライブラリのdup2()をオーバーライドします。これは、関数が別の.cファイルにある(そして別の.oとしてコンパイルされている)場合でも機能します。

オーバーライドする関数自体が動的にリンクされている場合は、リンカーを信頼してライブラリを正しい順序で取得するのではなく、dlopen()を使用することをお勧めします。

編集:オーバーライドされたライブラリ内の別の関数がオーバーライドされた関数を呼び出す場合、オーバーライドではなく元の関数が呼び出されると思われます。あるダイナミックライブラリが別のダイナミックライブラリを呼び出すとどうなるかわかりません。

于 2010-10-27T05:37:02.570 に答える
1

この質問にコメントを追加するだけではいけないようですので、「回答」として投稿してください。申し訳ありませんが、答えを検索する他の人々を助けるためだけにそうしています。

だから、私は似たようなユースケースを持っているようですが、既存のバイナリへの変更は(私にとっては)受け入れられないことが明示的にわかっているので、スタンドアロンのプロキシアプローチを探しています:ELFのプロキシ共有ライブラリ(sharedlib、shlibなど)?

于 2012-01-20T02:42:44.653 に答える