如何为 ptrace 子项设置 LD_PRELOAD 环境变量

问题描述

我正在尝试使用环境变量将预加载库加载到 ptrace 子进程。但不知何故,我在创建子进程时出错:

int main(int argc,char **argv)
{
    char *env[] = {"LD_PRELOAD=/<path-to-the-preload-library>/preload.so"};
    pid_t pid = fork();
    switch (pid) {
        case -1: /* error */
            log_fatal("%s. pid -1",strerror(errno));
            break;
        case 0:  /* child,executing the tracee */
            ptrace(PTRACE_TRACEME,0);
            execve(argv[1],argv + 1,env); // Fail to launch ptrace child!
            //execvp(argv[1],argv + 1);    // It works fine!
            log_fatal("%s. child",strerror(errno));
    }

    waitpid(pid,0); // sync with PTRACE_TRACEME
    ptrace(PTRACE_SetoPTIONS,pid,PTRACE_O_EXITKILL);

简单的预加载代码

$ cat preload.c
#include <stdio.h>

static void _init() __attribute__((constructor));
void _init() {
    printf("I'm a constructor\n");
}

知道为什么会失败吗?

解决方法

如果您能告诉我们错误信息是什么就好了,但我想我可以猜到:“地址错误”?

传递给 envexecve 向量需要以 NULL 指针终止,就像 argv 向量一样。所以你想要

char *env[] = {"LD_PRELOAD=/<path-to-the-preload-library>/preload.so",NULL};