2011-02-28 16 views
8

मेरे सी ++ प्रोग्राम में, मैं रनटाइम पर प्रोग्रामेटिक रूप से कैसे पता लगा सकता हूं कि लिनक्स पर 'स्ट्रिप' gnu विकास उपकरण के माध्यम से प्रतीकों को छीन लिया गया है या नहीं?रनटाइम पर कैसे पता लगाया जाए कि प्रतीकों को छीन लिया गया है या नहीं?

मुझे एक फ़ंक्शन परिभाषा चाहिए जो छीनने पर सच हो जाती है, अन्यथा झूठी।

इस विश्वसनीयता का पता लगाने के लिए "मुख्य()" काम पर dlsym() का उपयोग करना होगा?

+0

उत्सुक क्यों आप रनटाइम पर इसका पता लगाना चाहते हैं? –

+0

मुझे स्पष्ट नहीं है कि आपको यह जानने की आवश्यकता क्यों है कि निष्पादन योग्य छीन लिया गया है या नहीं। लेकिन जो भी आप रनटाइम पर निष्पादन योग्य प्रक्रिया को संसाधित करने के लिए उपयोग कर रहे हैं, उसमें आपको यह बताने की क्षमता भी होनी चाहिए कि चीजें छीन ली गई हैं या नहीं। –

+0

@ मार्टिन यॉर्क एप्लिकेशन को निष्पादित करते समय एक चेतावनी संदेश ट्रिगर करने के लिए एक गैर-छीन लिया गया संस्करण अनजाने में किसी ग्राहक को दिया जाता है। – WilliamKF

उत्तर

7

मुझे पता है कि file कमांड अंतर बता सकता है, ताकि आप संभवतः अपने स्रोत को देख सकें कि यह किस तंत्र का उपयोग करता है।

+5

एक छीन लिया [ईएलएफ] (http://en.wikipedia.org/wiki/Executable_and_Linkable_Format) में '.symtab 'प्रविष्टि की कमी होगी। 'फ़ाइल' कमांड सभी ईएलएफ अनुभाग शीर्षकों के माध्यम से एक प्रतीक तालिका खंड मिलने तक ट्रैवर करता है। यदि कोई नहीं पाया जा सकता है, तो बाइनरी * स्ट्रिप * माना जाता है। – jschmier

2

dlsymगतिशील प्रतीकों, जो पट्टी से छुआ नहीं कर रहे हैं पर लग रहा है। स्थैतिक प्रतीक तालिका उन खंडों में निहित है जो रनटाइम पर लोड नहीं होते हैं और इस प्रकार सेगमेंट तालिका में प्रकट नहीं होते हैं।

ईएलएफ हेडर में एक सेक्शन टेबल के अस्तित्व के लिए एक बहुत अच्छा हेरिस्टिक देखना होगा, जो आमतौर पर आपकी प्रक्रिया मेमोरी में मैप किया जाता है, हालांकि गतिशील लिंकर इंटरफेस इसे जानबूझकर मुश्किल से पता लगाने के लिए कठिन बनाता है। एक विशिष्ट प्रणाली पर जिसमें dl_iterate_phdrs फ़ंक्शन (जो मानक के लिए विस्तार है) है, तो आप पीएचडीआरएस चलने में सक्षम हो सकते हैं और प्रत्येक के लिए vaddr पर जांच कर सकते हैं कि वहां कोई ईएलएफ जादू संख्या है या नहीं, लेकिन यह किसी भी तरह से नहीं है, आकार या पोर्टेबल फॉर्म।

1

आप popen() इस्तेमाल कर सकते हैं लक्ष्य आवेदन पर nm निष्पादित करने के लिए और फिर parse the output अगर यह या छीन नहीं लगाने की।

nm: /bin/ls: no symbols 
7

एक टिप्पणी से another answer के लिए छोड़ दिया:

एक छीन ELF एक .symtab प्रविष्टि की कमी होगी। file आदेश सभी ईएलएफ अनुभाग शीर्षकों के माध्यम से एक प्रतीक तालिका खंड मिलने तक ट्रैवर करता है। यदि कोई नहीं पाया जा सकता है, तो बाइनरी को छीन लिया जाता है।


libelf पुस्तकालय ELF वस्तु फ़ाइलें, संग्रह फ़ाइलों, और संग्रह के सदस्यों में हेरफेर करने के लिए एक कार्यक्रम की अनुमति देता है। elf(3E) मैन पेज लाइब्रेरी का उपयोग करने से संबंधित दस्तावेज प्रदान करते हैं। निम्नलिखित कोड यह निर्धारित करने के लिए एक उदाहरण प्रदान करता है कि निष्पादन योग्य प्रतीक तालिका खंड (.symtab) के अस्तित्व की तलाश करके छीन लिया गया है या नहीं।

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <fcntl.h> 

/* Include for ELF processing */ 
#include <libelf.h> 
#include <gelf.h> 

int main(int argc, char ** argv) 
{ 
    int fd; 
    const char *file = argv[0]; 

    Elf *elf;  /* ELF pointer for libelf */ 
    Elf_Scn *scn; /* section descriptor pointer */ 
    GElf_Shdr shdr; /* section header */ 

    /* Open ELF file to obtain file descriptor */ 
    if((fd = open(file, O_RDONLY)) < 0) 
    { 
     fprintf(stderr, "Error opening file %s\n", file); 
     exit(EXIT_FAILURE); 
    } 

    /* Protect program from using an older library */ 
    if(elf_version(EV_CURRENT) == EV_NONE) 
    { 
     fprintf(stderr, "WARNING - ELF Library is out of date!\n"); 
     exit(EXIT_FAILURE); 
    } 

    /* Initialize elf pointer for examining contents of file */ 
    elf = elf_begin(fd, ELF_C_READ, NULL); 

    /* Initialize section descriptor pointer so that elf_nextscn() 
    * returns a pointer to the section descriptor at index 1. */ 
    scn = NULL; 

    /* Iterate through ELF sections */ 
    while((scn = elf_nextscn(elf, scn)) != NULL) 
    { 
     /* Retrieve section header */ 
     gelf_getshdr(scn, &shdr); 

     /* If a section header holding a symbol table (.symtab) 
     * is found, this ELF file has not been stripped. */ 
     if(shdr.sh_type == SHT_SYMTAB) 
     { 
      printf("NOT STRIPPED\n"); 
      break; 
     } 
    } 

    elf_end(elf); 
    close(fd); 
    exit(EXIT_SUCCESS); 
} 
1

पढ़ा गया - अनुभाग binary_path | grep debug_info

सामान्य रूप से यह कहना मुश्किल नहीं है कि एक बाइनरी छीन ली गई थी या नहीं, क्योंकि फ़ाइल को अलग करने के विभिन्न तरीके हैं। अनिवार्य रूप से अलग करना प्रतीक और डिबगिंग से संबंधित कुछ खंडों को हटा देता है। हालांकि, अगर आप "डीबग" के साथ "डीबग_इनोफ़ो" को प्रतिस्थापित करते हैं, तो आप देख सकते हैं कि उबंटू वितरण की मानक बाइनरी में अभी भी कुछ डीबग-संबंधित अनुभाग शेष हैं।

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

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