プロセスの特定のパスを偽造することは可能ですか?

プロセスの特定のパスを偽造することは可能ですか?

複数のユーザーを持つLinuxサーバーでADBを実行しようとしていますが、ルートではありません(Androidエミュレータを使用するため)。 adbデーモンはログをファイルに書き込みますが、/tmp/adb.log残念ながらそのファイルはADBにハードコードされているようです。変わらないだろう

したがって、adbは実行されず、明らかなエラーが発生しますcannot open '/tmp/adb.log': Permission denied。ファイルは他のユーザーによって生成され、/tmp固定ビットがあります。 adbを起動してadb nodaemon serverstdoutに書き込むとエラーは発生しません(衝突を避けるために、そのポートも一意の値に設定しました)。

私の質問は:ADBが他のファイルに書き込む方法はありますか/tmp/adb.logより一般的には、一種のプロセス固有のシンボリックリンクを作成する方法はありますか?/tmp/adb.logすべてのファイルアクセスをfileにリダイレクトしたいと思います~/tmp/adb.log

繰り返しますが、私はサーバーのルートではないのでchrootmount -o rbindおよびchmodは有効なオプションではありません。 ADBソースコードは可能であれば修正したくありませんが、他の解決策がない場合は必ず修正します。

PS固有のADBケースでは、リダイレクトを実行してadb nodaemon server出力nohupできますが、一般的な質問は依然として関連しています。

ベストアンサー1

LD_PRELOADはそれほど難しくなく、root権限は必要ありません。open()Cライブラリの実際のルーチンの代わりに呼び出される一意のCルーチンを挿入します。ルーチンは、開こうとしているファイルが「/tmp/adb.log」であることを確認し、別のファイル名で実際のオープンを呼び出します。これはshim_open.cです:

/*
 * capture calls to a routine and replace with your code
 * gcc -Wall -O2 -fpic -shared -ldl -o shim_open.so shim_open.c
 * LD_PRELOAD=/.../shim_open.so cat /tmp/adb.log
 */
#define _FCNTL_H 1 /* hack for open() prototype */
#define _GNU_SOURCE /* needed to get RTLD_NEXT defined in dlfcn.h */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#define OLDNAME "/tmp/adb.log"
#define NEWNAME "/tmp/myadb.log"

int open(const char *pathname, int flags, mode_t mode){
    static int (*real_open)(const char *pathname, int flags, mode_t mode) = NULL;

    if (!real_open) {
        real_open = dlsym(RTLD_NEXT, "open");
        char *error = dlerror();
        if (error != NULL) {
            fprintf(stderr, "%s\n", error);
            exit(1);
        }
    }
    if (strcmp(pathname,OLDNAME)==0) pathname = NEWNAME;
    fprintf(stderr, "opening: %s\n", pathname);
    return real_open(pathname, flags, mode);
}

コンパイルgcc -Wall -O2 -fpic -shared -ldl -o shim_open.so shim_open.cし、いくつかの項目を入れて/tmp/myadb.log実行してテストしてみてくださいLD_PRELOAD=/.../shim_open.so cat /tmp/adb.log。次に、adbでLD_PRELOADを試してください。

おすすめ記事