【问题标题】:Wrap clone syscall using LD_PRELOAD使用 LD_PRELOAD 包装克隆系统调用
【发布时间】:2021-09-20 02:49:05
【问题描述】:

可以使用 dlsym 包装诸如 printf 之类的变体函数,因为它具有 va_list 版本 vprintf。 所以,

int printf(const char *format, ...); //is equivalent to
int vprintf(const char *format, va_list ap);

引用https://stackoverflow.com/a/51627404/6353189 正好说明了这一点。

但是由于我在 linux 上没有看到克隆系统调用的 va_list 版本,所以不知道如何 把它包起来。

【问题讨论】:

  • "可以包装诸如 printf 之类的变体函数"。您似乎暗示 only 可变参数函数可以被包装。但事实并非如此——你引用的帖子并没有这么说。请描述您的原始问题以及您希望通过这种“包装”实现什么。
  • @kaylum: glibc clone 是一个可变参数函数

标签: c glibc ld-preload dlsym


【解决方案1】:

但由于我在 linux 上没有看到克隆系统调用的 va_list 版本,所以不知道如何包装它。

clone 系统调用不是(并且不能是)可变参数。它总是只需要 5 个参数(其中一些可能会被忽略,具体取决于传入的其他值)。

您可以将函数包装在 7 参数包装器中。如果调用者不提供所有 7 个参数,则未传入的值将是“垃圾”,但这无关紧要,因为在使用非包装版本时(可能)未使用这些参数。

【讨论】:

  • 那是错误的。克隆系统调用确实只需要 5 个参数。值得注意的是(而且很明显)没有“函数”或“arg”参数。
  • 许多系统调用忽略了总共 7 个参数中的 1-7 个。
  • @ktzap 你错了。只需反汇编 libc.so.6 中的 clone 并说服自己它总是将 7 个参数传递给内核。
  • 我做到了,正如我所说的那样。您可以查看 x86_64 源代码here。它只传递 5 个参数(或 6 个,如果您还计算 eax 中的系统调用号)。 “函数”和“参数”参数被插入堆栈(在第二个参数中传递,在rsi 寄存器中)。内核不知道也不关心那个“假返回”的把戏。而且我认为在 x86_64 或 i386 上没有 any 系统调用需要超过 6 个参数。
  • @ktzap 我明白你的意思。我已经编辑了答案。
猜你喜欢
  • 1970-01-01
  • 2019-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-04
  • 2012-09-08
  • 1970-01-01
相关资源
最近更新 更多