1

我正在尝试挂钩一些适用于文件名的 glibc 函数。基本上我需要稍微修改文件名,然后将它与其他参数一起传递给原始 glibc 函数。

代码如下所示:

FILE *fopen(const char *filename, const char *modes) {
  filename = modify(filename); // assuming we don't need to free the new filename pointer for now
  using FuncT = FILE*(*) (const char *, const char *);
  static FuncT originalFunc = (FuncT)dlsym(RTLD_NEXT, "fopen");
  return originalFunc(filename, modes);
}

这在大多数情况下都可以正常工作,但是当涉及到函数的可变参数时int execl(const char *path, const char *arg, ...),我该如何正确地做到这一点?

4

2 回答 2

1

基本上,您不能 - 无法复制您获得的(未解析的)参数列表并将其传递给另一个 varargs 函数。这就是为什么所有 varags 函数都有两种形式的原因——一种接受...参数,另一种接受更具体的参数(显式va_list或数组指针)。

在 的情况下execl,对应的函数是execv-- 如果你想拦截和“换行” execl,你的替换函数需要从 va_list 中提取参数,然后execv用结果数组调用。

请注意,库中的所有 execX 函数通常只是编写为调用 execve 的包装器,因此您可能只需要拦截 execve 就可以有效地拦截所有这些函数。

于 2020-01-04T04:58:09.950 回答
0

要传递可变编号参数,您需要知道您期望的参数数量或具有特殊值的参数(如下例所示 - NULL 结束参数列表)。printf例如,知道从格式字符串中可以期待什么。

此函数连接字符串。

#include <stdio.h>
#include <stdarg.h>

char *concat(char *s1, ...)
{
    char *saved = s1;
    char *s2;
    va_list ap;
    va_start(ap, s1);
    if(s1)
    {
        while(*s1) s1++;
        while((s2 = va_arg(ap, char *))) while(*s2) *s1++ = *s2++;
    }
    va_end(ap);
    return saved;
}

int main()
{
    char s1[64] = "Hello";
    printf("%s\n", concat(s1," World", " !12345!", " QWWERTY ", "@@", NULL));

    return 0;
}

你可以在这里自己玩和试验这个例子:https ://onlinegdb.com/HkY5a7pJL

于 2020-01-03T21:09:29.320 回答