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 を試します。
util-linux
を使用した非常に簡単な例を次に示します。 の unshare
プロセスをプライベート マウント名前空間に配置し、その親が現在持っているのと同じファイル システムの別のビューをプロセスに与えるには:
{ cd /tmp #usually a safe place for this stuff
echo hey >file #some
echo there >file2 #evidence
sudo unshare -m sh -c ' #unshare requires root by default
mount -B file2 file #bind mount there over hey
cat file #show it
kill -TSTP "$$" #suspend root shell and switch back to parent
umount file #unbind there
cat file' #show it
cat file #root shell just suspended
fg #bring it back
cat file2 #round it off
}
there #root shell
hey #root shell suspended
hey #root shell restored
there #rounded
unshare
を使用して、プロセスにファイルシステムのプライベートビューを与えることができます ただし、マウント名前空間機能自体は、3.x カーネル シリーズ全体でかなり成熟しています。 nsenter
を使用して、あらゆる種類の既存の名前空間を入力できます 同じパッケージのユーティリティであり、 man
で詳細を確認できます .