繁体   English   中英

执行寄存器在atexit()上的问题

[英]Execv register issue at atexit()

“在调用过程映像中没有由atexit()注册的功能被注册到新过程映像中”。

这是代码:

pid = fork();
if (pid == 0) {
    atexit(check_mem);
    return execv(...);
}

execv()之后未调用check_mem函数。 因为上面的“行”。 任何黑客都会在execv调用后获得注册的功能?

在此先感谢您的帮助。

当您执行某些操作时,atexit处理程序将不会执行。

execv替换当前的过程映像,包括您已注册的所有atexit处理程序,因此您实际上无能为力-您的代码已消失。

有点棘手,但可行的-使用aa函数创建共享库(我们将其称为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函数。

它仅在您正在执行的程序动态链接时才有效,但是AFAIK是唯一的限制。

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

就像nos所说的那样,exec取代了您的流程。 您可以尝试使用<stdlib.h>的int system (char *s)函数来启动带有args的程序。 与execve不同,系统在生成的进程退出时返回,例如

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

完美的解决方案是使用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);

致谢: www.wienand.org/junkcode/linux/stopper.c

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM