2011-03-29 3 views
5

संपादित करें (मेड प्रोजेक्ट):एक बहु थ्रेडेड अनुप्रयोग को कैसे पट्टा करें?

मैं एक vsftpd डिमन को छेड़छाड़ करने की कोशिश कर रहा हूं। मेरे पास निम्न कोड है जो डेमॉन से जुड़ा हुआ है। फिर यह पहली स्पॉन्डेड प्रक्रिया के पीआईडी ​​को सफलतापूर्वक प्रदर्शित करता है। हालांकि, इस पैदावार की प्रक्रिया के बच्चों के लिए यह पीआईडी ​​को 2,3 के रूप में वापस लाता है, .. कार्यक्रम हालांकि तैयार प्रक्रियाओं से बाहर निकलता है, जो मुझे लगता है कि मैं करीब हूं।

कोई विचार?

void * trace_process(void * pid){ 
    pid_t child = atoi((char *) pid); 
    long orig_eax, eax; 
    int status; 
    int callmade = FALSE; 
    long opt = PTRACE_O_TRACEFORK; 
    long newpid; 

    long trace = ptrace(PTRACE_ATTACH,child,NULL,NULL); 
    ptrace(PTRACE_SETOPTIONS,child,NULL,opt); 
    if(trace == FALSE) 
     printf("Attached to %d\n",child); 

    while(TRUE) { 
     child = waitpid(-1, &status, __WALL); 

     if (status >> 16 == PTRACE_EVENT_FORK) { 
      ptrace(PTRACE_GETEVENTMSG, child, NULL, (long) &newpid); 
      ptrace(PTRACE_SYSCALL, newpid, NULL, NULL);  

      printf("Attached to offspring %ld\n", newpid); 
     } 
     else{ 
      if(WIFEXITED(status)) 
       printf("Child %d exited\n", child); 
     } 

     ptrace(PTRACE_SYSCALL,child, NULL, NULL); 
    } 
} 

नमूना उत्पादन:

Attached to 2015 // daemon 
Attached to offspring 5302 // new connection handler 
Attached to offspring 2 // should be authenticator 
Child 5303 exited  // authenticator exiting on successful login 
Attached to offspring 3 // should be process serving files 
Child 5304 exited  // logout: process serving files 
Child 5302 exited  // connection closed 
Attached to offspring 5305 // new connection handler 
Attached to offspring 2 // ... repeat 
Child 5306 exited 
Attached to offspring 3 
Child 5307 exited 
Child 5305 exited 
+0

आप 'strace (1) में देखा है' बिल्कुल? –

+0

@ निकोलई एन Fetissov मैं अब स्ट्रेस स्रोत में देख रहा हूँ। के माध्यम से जाना बिल्कुल आसान नहीं है। और अधिक दिलचस्प बात यह है कि मैंने vsftpd के ढक्कन को चिपकाया और जब मैं ncftp का उपयोग करके लॉगिन करता हूं तो यह "कनेक्टिंग ..." वार्तालाप पर लटकता है। जब मैं ctrl-c strace से बाहर यह ठीक से जारी है। तो स्ट्रेस वास्तव में काम नहीं कर रहा है। – ofosho

+0

क्या आपने '-f' विकल्प का उपयोग किया था? –

उत्तर

1

मेरी कोड के साथ आगे जाने के बाद, मैं महसूस करें कि यह वास्तव में माता-पिता और उसके बच्चों से आने वाली सभी सिस्टम कॉलों को कैप्चर करने के लिए काम करता है। एकमात्र मुद्दा यह है कि पीआईडी ​​वास्तविक पीआईडी ​​के बजाए सापेक्ष संख्या के रूप में वापस आते हैं। इसका नतीजा यह नहीं है कि वास्तव में माता-पिता से प्रतीक्षा पीआईडी ​​उत्पन्न हुई थी। किसी भी तरह से, कोड आपको सभी सिस्टम कॉल प्राप्त करेगा। मैं अभी भी जानना चाहूंगा कि पीआईडी ​​मेरे अपने ज्ञान के लिए क्यों सापेक्ष है, लेकिन कोड ठीक काम करता है।

+0

वे सापेक्ष पीआईडी ​​नहीं हैं, वे एक नए पीआईडी ​​नेमस्पेस (1 से फिर से शुरू) में पिड्स हैं। दरअसल वास्तव में vsftpd को चिपकाने और स्ट्रेस स्रोत में गहरे कोहनी करने की कोशिश कर रहा है। –

0

Playing with ptrace लेख को पढ़ते समय, मैं एक उपयोगकर्ता के लिए जो भी इस के साथ संघर्ष से this comment पाया:

/* After struggled a long time, I got a true way to make my ptrace worked 
* correct with multi-thread application. Here're my sample codes, hope it 
* can help others whom have the same confusion. */  

char trapCode[] = {0, 0, 0, 0}; 
int status; 

ptrace(PTRACE_ATTACH, childProcess, NULL, NULL); //childProcess is the main thread 
wait(NULL); 

printf("\nchild %d created\n", childProcess); 
fflush(stdout); 

long ptraceOption = PTRACE_O_TRACECLONE; 
ptrace(PTRACE_SETOPTIONS, childProcess, NULL, ptraceOption); 

struct user_regs_struct regs; 

for(unsigned int i = 0; i < m_breakPoints.size(); i++) 
{ 
    BreakPoint_Info breakPointInfo = m_breakPoints[i]; 
    if(!breakPointInfo.m_enabled) 
     continue; 

    unsigned int index = breakPointInfo.m_checkPointIndex; 
    if(m_bytesBackup.find(m_checkPoints[index].m_offset) != m_bytesBackup.end()) 
     continue; 

    unsigned long readAddr = m_checkPoints[index].m_offset; 
    One_Byte_With_Result *oneByte = new One_Byte_With_Result; 
    getData(childProcess, readAddr, trapCode, 4); 
    oneByte->m_char = trapCode[0]; 
    trapCode[0] = 0xcc; 
    putData(childProcess, readAddr, trapCode, 4); 

    m_bytesBackup.insert(std::make_pair(m_checkPoints[index].m_offset, oneByte)); 
} 

std::set allThreads; 
std::set::iterator allThreadsIter; 
allThreads.insert(childProcess); 

int rec = ptrace(PTRACE_CONT, childProcess, NULL, NULL); 

while(true) 
{ 
    pid_t child_waited = waitpid(-1, &status, __WALL); 

    if(child_waited == -1) 
     break; 

    if(allThreads.find(child_waited) == allThreads.end()) 
    { 
     printf("\nreceived unknown child %d\t", child_waited); 
     break; 
    } 

    if(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) 
    { 
     pid_t new_child; 
     if(((status >> 16) & 0xffff) == PTRACE_EVENT_CLONE) 
     { 
      if(ptrace(PTRACE_GETEVENTMSG, child_waited, 0, &new_child) != -1) 
      {   
       allThreads.insert(new_child); 
       ptrace(PTRACE_CONT, new_child, 0, 0); 

       printf("\nchild %d created\t", new_child); 
      } 

      ptrace(PTRACE_CONT, child_waited, 0, 0); 
      continue; 
     } 
    } 

    if(WIFEXITED(status)) 
    { 
     allThreads.erase(child_waited); 
     printf("\nchild %d exited with status %d\t", child_waited, WEXITSTATUS(status)); 

     if(allThreads.size() == 0) 
      break; 
    } 
    else if(WIFSIGNALED(status)) 
    { 
     allThreads.erase(child_waited); 
     printf("\nchild %d killed by signal %d\t", child_waited, WTERMSIG(status)); 

     if(allThreads.size() == 0) 
      break; 
    } 
    else if(WIFSTOPPED(status)) 
    { 
     int stopCode = WSTOPSIG(status); 
     if(stopCode == SIGTRAP) 
     { 
      ptrace(PTRACE_GETREGS, child_waited, NULL, &regs); 
      unsigned long currentEip = regs.eip; 
      //printf("%d\t%08x\n", child_waited, currentEip); 

      Address_Bytes_Map::iterator iter = m_bytesBackup.find(currentEip - 1); 
      if(iter != m_bytesBackup.end()) 
      { 
       iter->second->m_result = true; 

       regs.eip = regs.eip - 1; 
       getData(child_waited, regs.eip, trapCode, 4); 
       trapCode[0] = iter->second->m_char; 
       putData(child_waited, regs.eip, trapCode, 4); 
       rec = ptrace(PTRACE_SETREGS, child_waited, NULL, &regs); 
      } 
     } 
    } 

    rec = ptrace(PTRACE_CONT, child_waited, 1, NULL); 

    continue; 
} 
+0

हाँ, यह वह कोड है जिस पर मैं आधारित हूं। मैं मूल रूप से एक ही बात है, लेकिन पोस्टिंग उद्देश्यों के लिए सरलीकृत। जब मैं सीधे अपने संस्करण का उपयोग करता हूं तो मुझे एक "अज्ञात बच्चा" मिलता है और यह निकलता है। यह समझ में आता है क्योंकि यह संग्रहीत (2,3, ..) और बाहर निकलने पर वास्तविक पिड प्राप्त हुआ। हालांकि मैं पद की सराहना करता हूं। – ofosho

+0

@ofosho ठीक है, मैं बाद में इसे देख लूंगा। – karlphillip

1

थ्रेड अगले wait() से पहले चलने दें।

प्रयास करें:

ptrace(PTRACE_SYSCALL,child, NULL, NULL); 

से पहले:

while(TURE) 

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

  • कोई संबंधित समस्या नहीं^_^