为什么似乎并LD_ preLOAD不与厕所写工作
问题描述:
我在玩弄LD_ preLOAD拦截的libc电话,看来写调用不会与WC拦截,但它似乎与猫的工作。这个问题的一个精简版显示如下。
I was playing around with LD_PRELOAD to intercept libc calls, it appears that the write call doesn't get intercepted with wc, though it does seem to work with cat. A stripped down version of the problem appears below.
RedHat Linux上2.6.9-42.ELsmp
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:
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);
}
already = 1;
}
ret = (*libc_write)(fd,"LD_PRELOAD\n",11);
return len; // not ret so cat doesn't take forever
}
输出:
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
任何解释吗?
答
这是因为当猫
使用写
, 厕所
使用的printf
,这可能是使用任内联版本写
,或它引用写
势必的libc
,所以不能插入。
That's because while cat
uses write
, wc
uses printf
, which is probably using either an inlined version of write
, or its reference to write
is bound to libc
, so cannot be interposed.
这可以很容易地使用可见 ltrace
:
This can easily be 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