为什么 LD_PRELOAD 与系统调用一起工作?的
Why does LD_PRELOAD work with syscalls?
LD_PRELOAD
的想法是在原来的共享库之前加载一个共享库,比如我可以编译mylib.so
在libc.so
之前加载它,所以当进程想要使用 printf
它在一个一个加载的 so
中搜索并在 mylib.so
中找到它(因为这个 so
首先加载)而不是 libc.so
,所以它使用 mylib.so
中的 printf
而不是 libc.so
中的 printf
。
我理解为什么这适用于 so
中实现的函数,例如 libc.so
中的 printf
。
但是当我想挂钩 write
函数或另一个 syscall
函数时,为什么它可以工作?进程不搜索so
中的函数,直接进入内核
LD_PRELOAD
是否适用于静态编译的二进制文件?为什么?
在此回放中 提到 LD PRELOAD
不适用于静态二进制
为什么 LD_PRELOAD
在动态编译的二进制文件上工作以挂钩系统调用?
架构为ARM。
The process does not search the function in the so
, it goes directly to the kernel.
错了,您使用的系统调用函数(read()
、write()
、...)都是围绕真实系统调用的 libc wrappers,甚至通用 syscall()
函数。 Here's the code 例如 write()
函数。从你的程序直接进入内核的唯一方法是手动发出系统调用(见下文)。
Does LD_PRELOAD
work on a binary that is compiled statically? Why?
不,不是。静态二进制文件不需要动态解析任何符号,因此不会调用动态加载程序来解析通常的库函数符号。
Why does LD_PRELOAD
work on a binary compiled dynamically to make hooks on syscalls?
因为那些只是普通的 libc 函数,仅此而已。
除了静态编译之外,在不通过 C 库(因此不进行符号解析)的情况下手动调用系统调用的唯一方法是使用 inline assembly. You can take a look at man 2 syscall
查看要使用的寄存器和指令。例如,在 ARM AArch64 上,您可以通过在寄存器 x8
中加载系统调用编号,在 x0
到 x5
中加载参数,然后执行 svc #0
指令来调用系统调用。 =27=]
LD_PRELOAD
的想法是在原来的共享库之前加载一个共享库,比如我可以编译mylib.so
在libc.so
之前加载它,所以当进程想要使用 printf
它在一个一个加载的 so
中搜索并在 mylib.so
中找到它(因为这个 so
首先加载)而不是 libc.so
,所以它使用 mylib.so
中的 printf
而不是 libc.so
中的 printf
。
我理解为什么这适用于 so
中实现的函数,例如 libc.so
中的 printf
。
但是当我想挂钩 write
函数或另一个 syscall
函数时,为什么它可以工作?进程不搜索so
中的函数,直接进入内核
LD_PRELOAD
是否适用于静态编译的二进制文件?为什么? 在此回放中 提到LD PRELOAD
不适用于静态二进制为什么
LD_PRELOAD
在动态编译的二进制文件上工作以挂钩系统调用?
架构为ARM。
The process does not search the function in the
so
, it goes directly to the kernel.
错了,您使用的系统调用函数(read()
、write()
、...)都是围绕真实系统调用的 libc wrappers,甚至通用 syscall()
函数。 Here's the code 例如 write()
函数。从你的程序直接进入内核的唯一方法是手动发出系统调用(见下文)。
Does
LD_PRELOAD
work on a binary that is compiled statically? Why?
不,不是。静态二进制文件不需要动态解析任何符号,因此不会调用动态加载程序来解析通常的库函数符号。
Why does
LD_PRELOAD
work on a binary compiled dynamically to make hooks on syscalls?
因为那些只是普通的 libc 函数,仅此而已。
除了静态编译之外,在不通过 C 库(因此不进行符号解析)的情况下手动调用系统调用的唯一方法是使用 inline assembly. You can take a look at man 2 syscall
查看要使用的寄存器和指令。例如,在 ARM AArch64 上,您可以通过在寄存器 x8
中加载系统调用编号,在 x0
到 x5
中加载参数,然后执行 svc #0
指令来调用系统调用。 =27=]