2010-02-07 60 views
9

子進程可以使用ptrace系統調用來跟蹤它的父進程嗎?ptrace'ing父進程

在Linux操作系統上2.6

感謝。

upd1: 我想從「本身」跟蹤process1。這是不可能的,所以我做叉,並嘗試從子進程做ptrace(process1_pid, PTRACE_ATTACH)。但是我不能,有一個奇怪的錯誤,像內核禁止孩子追蹤他們的父進程

UPD2:這樣的跟蹤可以被安全策略禁止。哪些政策可以做到這一點?內核中的檢查代碼在哪裏?

UPD3:我的嵌入式linux我沒有錯誤與PEEKDATA,但不與GETREGS:

child: getregs parent: -1 
errno is 1, strerror is Operation not permitted 

錯誤號= EPERM

+0

什麼是您所看到的奇怪的錯誤後的誤差('errno')? – jschmier 2010-02-07 06:30:40

+0

osgx,是我在下面正確測試父進程跟蹤的答案嗎? – 2010-02-07 10:15:56

+1

既然你正在分叉,爲什麼不做相反的事情,即從父母那兒追溯到孩子? – shodanex 2010-02-08 08:06:45

回答

6

這個問題我很感興趣。所以我寫了一些代碼來試用它。

首先要記住,在跟蹤一個進程時,除了名字(例如getppid())之外,跟蹤進程成爲大多數用途的父進程。首先,手冊的PTRACE_ATTACH部分的片段是有用的:

PTRACE_ATTACH 
      Attaches to the process specified in pid, making it a traced 
      "child" of the calling process; the behavior of the child is as 
      if it had done a PTRACE_TRACEME. The calling process actually 
      becomes the parent of the child process for most purposes (e.g., 
      it will receive notification of child events and appears in 
      ps(1) output as the child's parent), but a getppid(2) by the 
      child will still return the PID of the original parent. The 
      child is sent a SIGSTOP, but will not necessarily have stopped 
      by the completion of this call; use wait(2) to wait for the 
      child to stop. (addr and data are ignored.) 

現在,這裏是我寫的測試和驗證通過在爲之傾倒,你其實可以ptrace()你的父母(你可以建立這樣的代碼文件名爲blah.c和運行make blah

#include <assert.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/ptrace.h> 

int main() 
{ 
    pid_t pid = fork(); 
    assert(pid != -1); 
    int status; 
    long readme = 0; 
    if (pid) 
    { 
     readme = 42; 
     printf("parent: child pid is %d\n", pid); 
     assert(pid == wait(&status)); 
     printf("parent: child terminated?\n"); 
     assert(0 == status); 
    } 
    else 
    { 
     pid_t tracee = getppid(); 
     printf("child: parent pid is %d\n", tracee); 
     sleep(1); // give parent time to set readme 
     assert(0 == ptrace(PTRACE_ATTACH, tracee)); 
     assert(tracee == waitpid(tracee, &status, 0)); 
     printf("child: parent should be stopped\n"); 
     printf("child: peeking at parent: %ld\n", ptrace(PTRACE_PEEKDATA, tracee, &readme)); 
    } 
    return 0; 
} 

請注意,我利用父母的虛擬地址空間的複製知道去哪裏找另外要注意的是,當孩子然後終止,我懷疑有一個明確分離其中。必須讓父母繼續,我沒有調查進一步。

+0

此代碼是否適用於您的計算機? – osgx 2010-02-07 13:10:37

+1

是的,它確實如此。也許你正在運行一些發行默認流程安全策略的發行版,我想fedora會這樣做。它爲你工作?你應該看到孩子偷看,並從父母打印值。 – 2010-02-07 14:45:51

+0

此代碼似乎工作...在Linux/x86和我的linux(嵌入式) – osgx 2010-02-08 14:59:08

1

是的,這是可能的... 甚至GETREGS的作品。 經過在x86 (根據馬特·喬伊納代碼,感謝他)

#include <assert.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/ptrace.h> 
#include <sys/types.h> 
#include <sys/user.h> 

int main() 
{ 
    pid_t pid = fork(); 
// assert(pid != -1); 
    int status; 
    long readme = 0; 
    struct user_regs_struct regs; 
    if (pid) 
    { 
     readme = 42; 
     printf("parent: child pid is %d\n", pid); 
     assert(pid == wait(&status)); 
     printf("parent: child terminated?\n"); 
     assert(0 == status); 
    } 
    else 
    { 
     pid_t tracee = getppid(); 
     printf("child: parent pid is %d\n", tracee); 
     sleep(1); // give parent time to set readme 
     assert(0 == ptrace(PTRACE_ATTACH, tracee)); 
     assert(tracee == waitpid(tracee, &status, 0)); 
     printf("child: parent should be stopped\n"); 
     printf("child: peeking at parent: %ld\n", ptrace(PTRACE_PEEKDATA, tracee, &readme, NULL)); 
     printf("Regs was %p, %p, %p, %p; &status is %p \n", regs.eax, regs.ebx, regs.ecx, regs.edx, &status); 
     printf("child: getregs parent: %ld\n", ptrace(PTRACE_GETREGS, tracee, NULL, &regs)); 
     printf("Regs is %p, %p, %p, %p; &status is %p \n", regs.eax, regs.ebx, regs.ecx, regs.edx, &status); 
    } 
    return 0; 
} 

結果:

child: parent pid is 1188 
parent: child pid is 1189 
child: parent should be stopped 
child: peeking at parent: 42 
Regs was (nil), (nil), (nil), (nil); &status is 0xbfffea50 
child: getregs parent: 0 
Regs is 0xfffffe00, 0xffffffff, 0xbfffea50, (nil); &status is 0xbfffea50 
parent: child terminated? 
+1

無恥副本我的代碼?:P – 2010-02-08 15:05:09

+0

是的,但是添加了GETREGS。 – osgx 2010-02-08 15:15:15

+0

osgx,嘗試爲getregs問題 – 2010-02-08 15:39:51