「調用過程映像中沒有atexit()註冊的功能註冊到新過程映像中」。在atexit()的Execv註冊問題()
這裏是代碼:
pid = fork();
if (pid == 0) {
atexit(check_mem);
return execv(...);
}
check_mem功能execv後沒有得到所謂的()。由於上面的「線」。任何黑客獲得execv調用後註冊函數?
在此先感謝您的幫助。
「調用過程映像中沒有atexit()註冊的功能註冊到新過程映像中」。在atexit()的Execv註冊問題()
這裏是代碼:
pid = fork();
if (pid == 0) {
atexit(check_mem);
return execv(...);
}
check_mem功能execv後沒有得到所謂的()。由於上面的「線」。任何黑客獲得execv調用後註冊函數?
在此先感謝您的幫助。
完美的解決方案是使用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);
當你執行*某事時,atexit處理程序將不會執行。
execv取代了當前的過程映像,包括你已經註冊的任何atexit處理程序,所以實際上你可以做的事情不多 - 你的代碼已經沒有了。
就像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. */
}
有點棘手,但可行的 - 創建一個像這樣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程序工作。我仍然認爲它很有可能會覆蓋你的用例。
它也不適用於setuid或setgid程序。 –
那麼,什麼是另一種方法做同樣的 – Mohyt
@Mohyt那你需要做什麼完全取決於。你的checkmem()函數做了什麼,這對另一個進程是否有興趣? – nos