【问题标题】:Why can't I intercept write(2) in bash with LD_PRELOAD?为什么我不能使用 LD_PRELOAD 在 bash 中拦截 write(2)?
【发布时间】:2013-10-26 10:55:46
【问题描述】:

好的,我明白了。当另一个 libc 函数调用它时,您不能用 LD_PRELOAD 覆盖一个 libc 函数。


我在玩 Dante socksifier,发现它不适用于 bash /dev/udp FD。然后我用write 函数编写了一个简单的.so 文件,它也不适用于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,它与符号版本有关。

在链接 ./test 时需要更改哪些内容,以便它会像 bash 一样失败?我的意思是,对于相同的 .so 文件,命令:$ LD_PRELOAD=./libtest.so ./test 将打印“abc”,因为test 将绑定到 glibc 中的版本化write

我也在尝试相反的方法 - 使用版本化的 write 创建一个 .so 文件。 version.script

GLIBC_2.2.5 {
    write;
};

但我的库仍然无法在 bash 中拦截 write

$ gcc -g -O0 -fPIC -shared -Wl,--version-script=./version.script -o libtest.so libtest.c
$ LD_PRELOAD=./libtest.so bash -c 'echo abc'
abc

【问题讨论】:

  • write(2) 在第 2 节中为syscalls(2) - 没有write(3);顺便说一句,一些聪明的程序可能会做一个直接的系统调用 -e.g.使用syscall(2)SYSENTER 机器指令,甚至不使用瘦write(2) 包装器。那你需要ptrace(2)
  • @BasileStarynkevitch 顺便说一句,C 函数 write() 的签名不是模仿 1:1 的 write 系统调用吗?
  • 或多或少是的,但是原始系统调用(通过SYSENTER)获取其参数的方式不同(通过寄存器)并且给出的错误代码完全不同。我的观点是LD_PRELOAD 解决方案不是防弹的。

标签: c linux shared-libraries


【解决方案1】:

当您查看使用的符号时,您可能会看到版本化符号用于write

$ readelf -a test | grep write
48: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND write@@GLIBC_2.2.5

您必须编写带有 VERSION 部分的链接描述文件(info ld -> "Version command")。

您的情况(操纵 bash 行为)更复杂,因为 bash 调用 printf(3),而后者又使用 libc 的一些内部函数。当你运气好并且调用了一个弱内部函数(afais,只有'__write'),你可以在你的库中重载它。

否则,您必须覆盖 bash 调用的 printf();你可以用'ltrace'找到它;例如:

$ ltrace  bash -c 'echo abc'
__printf_chk(1, "%s", "abc")                                  = 3
_IO_putc('\n', 0x7fc5eeac3420abc

或通过设置 LD_DEBUG (--> man ld.so)

【讨论】:

  • 我不知道链接器脚本
  • 在链接./test 时需要改变什么,这样它就会像 bash 一样失败?
  • 我检查了 gdb。最后write是从libc调用的。
猜你喜欢
  • 2015-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-14
  • 1970-01-01
  • 2016-02-12
相关资源
最近更新 更多