わかったよ。libc 関数が別の libc 関数によって呼び出された場合、libc 関数を LD_PRELOAD でオーバーライドすることはできません。
Dante ソックスファイアーをいじっていて、bash /dev/udp FD では動作しないことに気付きました。次に、関数を使用して単純な .so ファイルを作成しましたがwrite
、bash でも機能しません:
libtest.c
:
#include <unistd.h>
ssize_t write(int fildes, const void *buf, size_t nbyte)
{
return nbyte;
}
test.c
:
#include <unistd.h>
int main(int argc, char *argv[]) {
write(1,"abc\n",4);
return 0;
}
_
$ gcc -g -O0 -fPIC -shared -o libtest.so libtest.c
$ gcc -g -O0 -o test test.c
$ ./test
abc
$ LD_PRELOAD=./libtest.so ./test
$ LD_PRELOAD=./libtest.so bash -c 'echo abc'
abc
upd: ensc によると、シンボルのバージョンと関係があります。
bash のように失敗するように、./test のリンクで何を変更する必要がありますか? つまり、同じ .so ファイルで、次のコマンド$ LD_PRELOAD=./libtest.so ./test
は "abc" を出力します。これは、glibc test
でバージョン管理されたファイルにバインドされるためです。write
私も反対のことを試みています-バージョン化された.soファイルを作成しますwrite
。version.script
:
GLIBC_2.2.5 {
write;
};
しかし、私のライブラリはまだwrite
bash でインターセプトできません
$ gcc -g -O0 -fPIC -shared -Wl,--version-script=./version.script -o libtest.so libtest.c
$ LD_PRELOAD=./libtest.so bash -c 'echo abc'
abc