c - Why does LD_PRELOAD not seem to work for write with wc -
i playing around ld_preload intercept libc calls, appears write call doesn't intercepted wc, though seem work cat. stripped down version of problem appears below.
redhat linux 2.6.9-42.elsmp
makefile
writelib: gcc -wall -rdynamic -fpic -c write.c gcc -shared -wl,-soname,libwrite.so -wl,-export-dynamic -o libwrite.so write.o -ldl
write.c:
#include <stdio.h> #include <string.h> #ifndef __use_gnu #define __use_gnu #define __use_gnu_defined #endif #include <dlfcn.h> #ifdef __use_gnu_defined #undef __use_gnu #undef __use_gnu_defined #endif #include <unistd.h> #include <stdlib.h> static ssize_t (*libc_write)(int fd, const void *buf, size_t len); ssize_t write(int fd, const void *buf, size_t len) { static int already; ssize_t ret; if (!already) { if ((libc_write = dlsym(rtld_next, "write")) == null) { exit(1); } = 1; } ret = (*libc_write)(fd,"ld_preload\n",11); return len; // not ret cat doesn't take forever }
output:
prompt: make gcc -wall -rdynamic -fpic -c write.c gcc -shared -wl,-soname,libwrite.so -wl,-export-dynamic -o libwrite.so write.o -ldl prompt: ld_preload=./libwrite.so /bin/cat write.c ld_preload prompt: ld_preload=./libwrite.so /usr/bin/wc write.c 32 70 572 write.c
any explanations ?
that's because while cat
uses write
, wc
uses printf
, using either inlined version of write
, or reference write
bound libc
, cannot interposed.
this can seen using ltrace
:
$ echo foo | ltrace wc 2>&1 | grep 'write\|print' printf("%*s", 7, "1") = 7 printf(" %*s", 7, "1") = 8 printf(" %*s", 7, "4") = 8 $ echo foo | ltrace cat 2>&1 | grep 'write\|print' write(1, "foo\n", 4foo
Comments
Post a Comment