2010-02-07 14 views
9

क्या बच्चे प्रक्रिया अपने माता-पिता का पता लगाने के लिए ptrace सिस्टम कॉल का उपयोग कर सकती है?पेरेंट प्रक्रिया का ptrace'ing

ओएस लिनक्स 2.6

धन्यवाद।

अपडेट 1: मैं प्रक्रिया 1 को "स्वयं" से ढूंढना चाहता हूं। यह असंभव है, इसलिए मैं कांटा करता हूं और बाल प्रक्रिया से ptrace(process1_pid, PTRACE_ATTACH) करने का प्रयास करता हूं। लेकिन मैं नहीं कर सकता, एक अजीब त्रुटि है, जैसे कर्नेल बच्चे को अपनी मूल प्रक्रियाओं का पता लगाने से रोकता है

यूपीडी 2: ऐसी नीतियों को सुरक्षा नीतियों द्वारा प्रतिबंधित किया जा सकता है। कौन सी नीतियां यह करती हैं? कर्नेल में चेकिंग कोड कहां है?

UPD3: मेरे एम्बेडेड लिनक्स पर मैं PEEKDATA त्रुटियां नहीं है, लेकिन GETREGS साथ नहीं:

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

errno = EPERM

+0

अजीब त्रुटि आप देख रहे हैं के बाद त्रुटि ('errno') क्या है? – jschmier

+0

osgx, क्या आप मेरी कोशिश कर रहे हैं जैसे माता-पिता प्रक्रिया के ट्रेसिंग का सही ढंग से परीक्षण कर रहे हैं? –

+1

चूंकि आप किसी भी तरह से फोर्किंग कर रहे हैं, आप विपरीत क्यों नहीं करते हैं, यानी माता-पिता से बच्चे का पता लगाते हैं? – shodanex

उत्तर

6

यह सवाल वास्तव में मुझे कोई दिलचस्पी। तो मैंने इसे आजमाने के लिए कुछ कोड लिखा।

सबसे पहले ध्यान रखें, कि किसी प्रक्रिया का पता लगाने पर, नाम (यानी getppid()) को छोड़कर ट्रेसिंग प्रक्रिया अधिकांश उद्देश्यों के लिए माता-पिता बन जाती है। कोड मैं परीक्षण करने और सत्यापित करने के लिए एक में यह डंपिंग से है कि आप इस तथ्य ptrace() में अपने माता पिता (आप इस का निर्माण कर सकते कर सकते हैं करने के लिए लिखा था है

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_ATTACH अनुभाग का एक टुकड़ा उपयोगी है फ़ाइल 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

+1

हाँ यह निश्चित रूप से करता है। हो सकता है कि आप एक डिस्ट्रो चला रहे हों कि कुछ डिफ़ॉल्ट प्रक्रिया सुरक्षा नीतियों वाले जहाज, मुझे लगता है कि फेडोरा उदाहरण के लिए ऐसा करता है। क्या यह आपके काम आया? आपको बच्चे की चोटी देखना चाहिए, और माता-पिता से मूल्य प्रिंट करना चाहिए। –

+0

यह कोड काम करने लगता है ... लिनक्स/x86 पर और मेरे लिनक्स पर (एम्बेडेड) – osgx

1

हाँ यह संभव है ... यहां तक ​​कि GETREGS काम करता है। (मैट योजक कोड के आधार पर, उसे धन्यवाद) 86 पर जांच की गई

#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

मेरे कोड की लापरवाह प्रतिलिपि?: पी –

+0

हां, लेकिन GETREGS जोड़ा गया है। मुझे समस्याएं हैं इसके साथ – osgx

+0

osgx, getregs समस्या –

संबंधित मुद्दे