2010-02-07 7 views
9

Çocuk işlemi, üst öğesinin izini izlemek için ptrace sistem çağrısını kullanabilir mi?ptrace'ing

Os, linux 2.6

Teşekkürler.

upd1: İşlem1'i "kendinden" izlemek istiyorum. Bu imkansız, bu yüzden çatallıyorum ve çocuk süreçten ptrace(process1_pid, PTRACE_ATTACH) yapmayı denedim. Ama yapamıyorum, kernelin ana süreçlerini takip etmesini yasakladığı gibi garip bir hata var:

UPD2: bu tür izleme güvenlik politikaları tarafından yasaklanabilir. Hangi politikalar bunu yapıyor? Çekirdekdeki kontrol kodu nerede?

UPD3: my gömülü linux üzerinde ben değil GETREGS ile PEEKDATA ile hiçbir hata var:

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

errno = EPERM

+0

Gördüğünüz garip hata sonra hata ('errno') nedir? – jschmier

+0

osgx, aşağıda yanıtımı yaptığınız gibi bir ana işlemin izlemesini doğru bir şekilde test ediyor mu? –

+1

Her neyse, zaten neyse, neden tersini yapmıyorsun, yani çocuğu ebeveynden takip etmiyorsun? – shodanex

cevap

6

beni bu soru gerçekten ilgi. Bu yüzden denemek için bir kod yazdım. Öncelikle, bir işlemin izlenmesi sırasında, izleme işleminin ad (örneğin, getppid()) dışında çoğu amaç için bir üst öğe haline geldiğini unutmayın. Birincisi, kılavuzun PTRACE_ATTACH bölümünün bir pasajı faydalıdır: Şimdi burada

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

I test etmek ve bir de boşaltılarak sen aslında ptrace() da ebeveyn (bunu inşa edebilirsiniz doğrulamak için yazdığı kod dosya blah.c adlandırılır ve make blah çalışan. Ben ebeveynin sanal adres alanı çoğaltma istismar ediyorum

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

Not Ayrıca çocuğun daha sonra sona erer, ben örtük bir detach var şüpheli olduğuna dikkat bakmak nerede olduğunu bilmek hangi Ebeveynlerin devam etmesine izin vermeli, araştırmam. e daha fazla.

+0

Bu kod makinenizde çalışıyor mu? – osgx

+1

evet kesinlikle yapar. belki de bazı varsayılan süreç güvenlik politikalarıyla birlikte bir dağıtım yapıyorsunuz, örneğin fedora'nın bunu yaptığını düşünüyorum. Senin için mi çalışıyordu? Çocuk gözlerini görmeli ve değeri ebeveynden yazdırmalısınız. –

+0

Bu kod çalışıyor gibi görünüyor ... linux/x86 ve benim linux (gömülü) üzerinde – osgx

1

Evet, mümkün ... GETREGS bile çalışıyor. (Matt Joiner koduna göre sayesinde ona) x86 üzerine İşaretli

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

sonucu:

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

Kodumun utanmazca kopyası ?: P –

+0

Evet, ama GETREGS eklendi. – osgx

+0

osgx, getregs problemi için başka bir soru oluşturmayı deneyin –