2010-02-07 30 views
9

Quy trình con có thể sử dụng cuộc gọi hệ thống ptrace để theo dõi cha mẹ của nó không?ptrace'ing của quy trình gốc

Os là linux 2.6

Cảm ơn.

upd1: Tôi muốn theo dõi process1 từ "chính nó". Nó là không thể, vì vậy tôi làm ngã ba và cố gắng làm ptrace(process1_pid, PTRACE_ATTACH) từ quá trình con. Nhưng tôi không thể, có một lỗi lạ, giống như hạt nhân cấm trẻ em truy tìm các quy trình gốc của chúng

UPD2: theo dõi như vậy có thể bị cấm bởi chính sách bảo mật. Chính sách nào làm điều này? Mã kiểm tra trong hạt nhân ở đâu?

UPD3: trên linux nhúng của tôi, tôi không có lỗi với PEEKDATA, nhưng không phải với GETREGS:

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

errno = EPERM

+0

lỗi ('errno') sau lỗi lạ bạn đang nhìn thấy là gì? – jschmier

+0

osgx, là câu trả lời của tôi dưới đây một cách chính xác thử nghiệm truy tìm của một quá trình cha mẹ như bạn đang cố gắng? –

+1

Vì bạn đang bị nghẹt thở, tại sao bạn không làm ngược lại, tức là theo dõi đứa trẻ từ cha mẹ? – shodanex

Trả lời

6

Câu hỏi này thực sự quan tâm đến tôi. Vì vậy, tôi đã viết một số mã để dùng thử.

Trước hết hãy nhớ rằng khi truy tìm một quy trình, quy trình truy tìm sẽ trở thành phụ huynh cho hầu hết các mục đích, ngoại trừ trong tên (ví dụ: getppid()). Thứ nhất, một đoạn của phần PTRACE_ATTACH của cuốn cẩm nang hữu ích:

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.) 

Bây giờ đây là đoạn code tôi đã viết để kiểm tra và xác minh rằng bạn có thể trên thực tế ptrace() cha mẹ của bạn (bạn có thể xây dựng này bằng cách bán phá giá nó trong một file có tên blah.c và chạy 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; 
} 

lưu ý rằng tôi đang khai thác sự nhân lên của không gian địa chỉ ảo của cha mẹ để biết nơi để tìm Cũng lưu ý rằng khi trẻ sau đó chấm dứt, tôi nghi ngờ có một cửa sổ mới tiềm ẩn đó. phải cho phép phụ huynh tiếp tục, tôi đã không điều tra e hơn nữa.

+0

Mã này có hoạt động trên máy của bạn không? – osgx

+1

có nó chắc chắn không. có lẽ bạn đang chạy một distro mà tàu với một số chính sách bảo mật quá trình mặc định, tôi nghĩ rằng fedora làm điều này ví dụ. Nó đã làm việc cho bạn? bạn sẽ nhìn thấy hình thu nhỏ của trẻ và in giá trị từ cha mẹ. –

+0

Mã này dường như hoạt động ... Trên linux/x86 và trên linux của tôi (nhúng) – osgx

1

Có thể ... Ngay cả GETREGS cũng hoạt động. Kiểm tra trên x86 (dựa trên mã Matt Joiner, nhờ anh ấy)

#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; 
} 

kết quả:

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

bản sao không biết xấu mã của tôi ?: P –

+0

Có, nhưng GETREGS được thêm vào. với nó – osgx

+0

osgx, hãy thử tạo một câu hỏi khác cho vấn đề getregs –

Các vấn đề liên quan