2011-10-15 3 views
0

"호출 프로세스 이미지에서 atexit()에 의해 등록 된 함수가 새 프로세스 이미지에 등록되지 않았습니다". 여기atexit()에서 Execv 레지스터 문제

코드입니다 :하지 execv와 다음에 호출하기

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

check_mem 기능(). 위의 "선"때문입니다. execv 호출 후 등록 된 기능을 얻으려면 해킹이 필요하십니까 ??

미리 도움을 주셔서 감사합니다.

답변

1

완벽한 솔루션은 아래로의 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

7

exec * 무언가를 할 때 atexit 핸들러가 실행되지 않습니다.

execv는 등록한 atexit 핸들러를 포함하여 현재 프로세스 이미지를 대체하므로 실제로 할 수있는 일은 많지 않습니다. 코드가 사라졌습니다.

+0

그래서 당신이 무엇을해야하는지에 달려 @Mohyt 같은 – Mohyt

+2

을 할 수있는 또 다른 방법이 무엇인지. checkmem() 함수는 무엇을 하는가? 그것은 다른 프로세스에 관심이 있습니까? – nos

1

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. */ 
} 
2

약간 까다로운하지만 행할 - 그래서 같은 AA 기능을 가진 공유 라이브러리 (의이 check_mem.so를 부르 자) 작성 : check_mem 라이브러리에 정의 될 필요가 있다고

__attribute__((constructor)) void runs_first(void) { 
    atexit(check_mem); 
}; 

주,하지를 귀하의 프로그램.

이제 execve에서 프로그램에 전달 된 환경 변수에 LD_PRELOAD =/path/to/check_mem.so를 입력합니다 (execve의 마지막 인수).

새로운 프로그램이 실행될 때 check_mem 라이브러리를로드하고 (거의) 다른 코드보다 먼저 runs_first 함수를 실행합니다.

execve'ing하는 프로그램이 동적으로 링크되어 있지만 AFAIK가 유일한 제한 인 경우에만 작동합니다.

편집 : 주석이 정당하게 명시된 바와 같이 setuid 프로그램에서도 작동하지 않습니다. 그래도 여전히 유스 케이스를 커버 할 수있는 좋은 기회가 있다고 생각합니다.

+1

setuid 또는 setgid 프로그램에서 작동하지 않습니다. –