【发布时间】:2020-06-12 11:05:28
【问题描述】:
LD_PRELOAD的思想是在原始共享库之前加载一个共享库,例如我可以编译mylib.so在libc.so之前加载它,所以当进程想要使用printf时它会在so 一个一个加载并在mylib.so 中找到它(因为首先加载了这个so)而不是libc.so,所以它使用mylib.so 中的printf 而不是@987654333 中的printf @。
我理解为什么这适用于在 so 中实现的函数,例如 libc.so 中的 printf。
但是当我想挂钩write 函数或另一个syscall 函数时,它为什么会起作用?进程不搜索so中的函数,直接进入内核。
LD_PRELOAD是否适用于静态编译的二进制文件?为什么? 在此重播中,https://stackoverflow.com/a/13866611 提到LD PRELOAD不适用于静态二进制为什么
LD_PRELOAD在动态编译的二进制文件上工作以对系统调用进行挂钩?
架构是 ARM。
【问题讨论】:
-
当您编码调用
write时,它不是直接调用系统调用。它正在调用一个设置系统调用然后陷入内核的包装器。所以 LD_PRELOAD 可以通过覆盖包装调用来工作。 -
@kaylum 你确定吗,write 是系统调用,没有包装,我可以在汇编中看到它。所以 LD_PLELOAD 也需要在静态二进制上工作??
-
有一个名为 write 的系统调用,但这不是您直接调用的。 libc 中有系统调用包装器。预加载仅适用于动态链接的 exec。
-
我已经调整了你的问题的措辞,让它更清楚,让我知道这样是否可以。
-
简短回答:你被骗了。好的,这有点强,但是“系统调用”和“库函数”之间的区别是人为的,并不是很准确。它们实际上都是库函数,所谓的“系统调用”不再真正直接映射到实际的系统调用——实际的系统调用已经改变。例如,
open()可能会进行openat()系统调用。
标签: c linux arm system-calls ld-preload