atexit上的Execv寄存器问题()

atexit上的Execv寄存器问题(),c,linux,exec,atexit,C,Linux,Exec,Atexit,“新进程映像中未注册由调用进程映像中的atexit()注册的函数” 以下是代码: pid = fork(); if (pid == 0) { atexit(check_mem); return execv(...); } 检查execv()后未调用的函数。因为上面的“线”。在execv调用后注册函数的任何黑客行为 提前感谢你的帮助 atexit处理程序在您执行*某些内容时将不会执行 execv将替换当前进程映像,包括您注册的任何atexit处理程序,因此您可以做的事情真的不多-

“新进程映像中未注册由调用进程映像中的atexit()注册的函数”

以下是代码:

pid = fork();
if (pid == 0) {
    atexit(check_mem);
    return execv(...);
}
检查execv()后未调用的函数。因为上面的“线”。在execv调用后注册函数的任何黑客行为


提前感谢你的帮助

atexit处理程序在您执行*某些内容时将不会执行


execv将替换当前进程映像,包括您注册的任何atexit处理程序,因此您可以做的事情真的不多-您的代码消失了。

正如nos所说,exec将替换您的进程。您可以尝试使用
intsystem(char*s)
函数来启动带有args的程序。与execve不同,系统在派生进程退出时返回,例如

pid = fork();
if (pid == 0) {
    atexit(check_mem);
    system ("program arg1 arg2 ...");
    exit (0); /* Calls atexit handlers. */
}

有点棘手但可行-使用如下函数创建一个共享库(我们称之为check_mem.so):

__attribute__((constructor)) void runs_first(void) {
  atexit(check_mem);
};
请注意,check_mem需要在库中定义,而不是在程序中定义

现在在execve中,将LD_PRELOAD=/path/to/check_mem.so放入传递给程序的环境变量中(execve的最后一个参数)

当新程序运行时,它将加载您的check_mem库,并在(几乎)每隔一段代码之前运行runs_first函数

它只有在你正在执行的程序是动态链接的情况下才能工作,但这是唯一的限制


编辑:正如注释正确指出的那样,它在setuid程序上也不起作用。我仍然认为它很有可能涵盖您的用例。

完美的解决方案是使用ptrace(),如下所示:

pid = fork();
if (pid == 0) {
    ptrace(PTRACE_TRACEME, 0, 0, 0);
    return execve(...);
}

wait(NULL);
ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACEEXIT);
ptrace(PTRACE_CONT, pid, 0, (void*)0);

    while(1){
    waitpid(pid, &status, 0);
    if((WSTOPSIG(status) == SIGTRAP) && (status & (PTRACE_EVENT_EXIT << 8)))
        break;

    ptrace(PTRACE_CONT, pid, 0, WSTOPSIG(status));
}

check_mem();

ptrace(PTRACE_CONT, pid, 0, 0);
pid=fork();
如果(pid==0){
ptrace(ptrace_TRACEME,0,0,0);
返回execve(…);
}
等待(空);
ptrace(ptrace_SETOPTIONS,pid,0,ptrace_O_TRACEEXIT);
ptrace(ptrace_CONT,pid,0,(void*)0);
而(1){
waitpid(pid和status,0);

如果((WSTOPSIG(status)==SIGTRAP)&(status&(PTRACE_EVENT_)退出,那么另一种方法是什么same@Mohyt这完全取决于您需要做什么。checkmem()函数做什么,这是另一个进程感兴趣的?