2

Variatic functions such as printf can be wrapped using dlsym because it has a va_list version vprintf. So,

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

citing https://stackoverflow.com/a/51627404/6353189 which shows exactly this.

But since I don't see a va_list version of the clone syscall on linux, don't know how to wrap it.

antrix
  • 41
  • 2
  • "*Variatic functions such as printf can be wrapped*". You seem to be implying that *only* variadic functions can be wrapped. But that is not the case - the post you reference does not say that. Please describe your original problem and what you want to achieve with this "wrapping". – kaylum Sep 20 '21 at 03:13
  • @kaylum: glibc `clone` is a variadic function – Ry- Sep 20 '21 at 03:16

1 Answers1

2

But since I don't see a va_list version of the clone syscall on linux, don't know how to wrap it.

The clone system call is not (and can't be) variadic. It always takes exactly 5 parameters (some of which may be ignored, depending on other values passed in).

You can wrap the function in a 7-parameter wrapper. If the caller doesn't supply all 7 arguments, the values which were not passed in will be "garbage", but that shouldn't matter, since these parameters were (presumably) unused when using the non-wrapped version.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • That's false. The clone system call does take only 5 arguments. Notably (and quite obviously) there are no "function" or "arg" arguments. –  Sep 20 '21 at 09:00
  • Many system calls ignore 1-7 parameters from the total 7. – Zsigmond Lőrinczy Sep 20 '21 at 09:15
  • @ktzap You are mistaken. Just disassemble the `clone` in `libc.so.6` and convince yourself that it _always_ passes 7 arguments to the kernel. – Employed Russian Sep 20 '21 at 14:40
  • I did it and it's exactly as I said. You can look at the x86_64 source [here](https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86_64/clone.S;h=7418154c4b76bb3f277f962a8428c030c6ae7d71;hb=HEAD#l52). It's only passing 5 arguments (or 6, if you also count the system call number in `eax`). The "function" and "argument" args are inserted into the stack (which is passed in the 2nd arg, in the `rsi` register). The kernel doesn't know nor care about that "fake return" trick. And I don't think there is *any* system call which takes more than 6 arguments on x86_64 or i386. –  Sep 20 '21 at 16:26
  • @ktzap I see what you mean. I've edited the answer. – Employed Russian Sep 20 '21 at 19:59