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