2009-06-15 5 views
8

के बिना लिनक्स में फ़ंक्शन इंटरपोजिशन मैं वर्तमान में एक प्रोजेक्ट पर काम कर रहा हूं जहां मुझे कई सिस्टम कॉल और निम्न स्तर के कार्यों जैसे mmap, brk, sbrk के उपयोग को ट्रैक करने की आवश्यकता है। अब तक, मैं फ़ंक्शन इंटरपोजिशन का उपयोग करके ऐसा कर रहा हूं: मैं उसी नाम के साथ एक रैपर फ़ंक्शन लिखता हूं जिसे मैं बदल रहा हूं (mmap उदाहरण के लिए), और मैं इसे LD_PRELOAD पर्यावरण चर सेट करके प्रोग्राम में लोड करता हूं। मैं एक पॉइंटर के माध्यम से वास्तविक फ़ंक्शन को कॉल करता हूं जिसे मैं dlsym से लोड करता हूं।बिना किसी dlsym

दुर्भाग्यवश, मैं जो फ़ंक्शन लपेटना चाहता हूं, sbrk, आंतरिक रूप से dlsym द्वारा उपयोग किया जाता है, इसलिए जब मैं प्रतीक लोड करने का प्रयास करता हूं तो प्रोग्राम क्रैश हो जाता है। sbrk लिनक्स में सिस्टम कॉल नहीं है, इसलिए मैं इसे अप्रत्यक्ष रूप से कॉल करने के लिए syscall का उपयोग नहीं कर सकता।

तो मेरा सवाल यह है कि, मैं dlsym का उपयोग किए बिना उसी नाम के रैपर फ़ंक्शन से लाइब्रेरी फ़ंक्शन कैसे कॉल कर सकता हूं? क्या कोई कंपाइलर चाल है (जीसीसी का उपयोग करके) जो मुझे मूल कार्य को संदर्भित करने देता है?

उत्तर

14

एलडी विकल्प --wrap symbol देखें। मैन पेज से:

- स्क्रैप प्रतीक प्रतीक के लिए एक रैपर फ़ंक्शन का उपयोग करें। किसी भी अपरिभाषित प्रतीक के संदर्भ में को "__wrap_symbol" पर हल किया जाएगा। "__real_symbol" के संदर्भ में कोई भी अपरिभाषित प्रतीक के लिए हल किया जाएगा।

इसका उपयोग सिस्टम फ़ंक्शन के लिए रैपर प्रदान करने के लिए किया जा सकता है। रैपर फ़ंक्शन को "__wrap_symbol" कहा जाना चाहिए। यदि यह सिस्टम फ़ंक्शन को कॉल करना चाहता है, तो उसे "__real_symbol" पर कॉल करना चाहिए।

यहाँ एक तुच्छ उदाहरण है:

void * 
__wrap_malloc (size_t c) 
{ 
    printf ("malloc called with %zu\n", c); 
    return __real_malloc (c); 
} 

आप --wrap malloc का उपयोग कर इस फ़ाइल के साथ अन्य कोड लिंक करते हैं, तो सभी कॉल करने के लिए "malloc" समारोह कॉल करेंगे " __wrap_malloc "इसके बजाए।
"__wrap_malloc" में "__real_malloc" को कॉल करें "malloc" फ़ंक्शन को कॉल करेगा।

साथ ही आप एक "__real_malloc" समारोह प्रदान करने के लिए, इच्छा हो सकती है इसलिए --wrap विकल्प सफल होगा बिना लिंक है कि। यदि आप ऐसा करते हैं, तो को "__real_malloc" की परिभाषा को "__wrap_malloc" जैसी फ़ाइल में नहीं डालना चाहिए; यदि आप करते हैं, असेंबलर से पहले कॉल को हल कर सकता है तो लिंकर को इसे "malloc" पर लपेटने का मौका मिला है।

दूसरा विकल्प संभावित रूप से स्रोत के स्रोत को देखना है, यह एक ही चीज़ कम या कम है: -पी।

हालांकि यहां एक विचार है।आपके पास LD_PRELOAD 'एड लाइब्रेरी आपके कोड को इंगित करने के लिए पीएलटी प्रविष्टियों को बदल सकती है। यह तकनीकी रूप से sbrk() फ़ंक्शन अभी भी आपके कोड से कॉल करने योग्य है।

+0

यह बहुत अच्छा है। मैंने कभी भी स्क्रैप विकल्प के बारे में नहीं सुना था, लेकिन यह वही है जो मुझे चाहिए। धन्यवाद। –

+0

स्पष्टीकरण के लिए, निष्पादन योग्य लिंक करते समय या रैपर वाले एलडी_PRELOAD लाइब्रेरी को लिंक करते समय - स्क्रैप ध्वज को पारित करने की आवश्यकता होती है? साथ ही, क्या आप निष्पादन योग्य की पीएलटी प्रविष्टियों को संशोधित करने के बारे में अधिक जानकारी प्रदान करने पर विचार करेंगे? –

+0

आपके लिए * target * ऐप को --wrap से लिंक करने के लिए डिज़ाइन किया गया उपयोग केस है। यह एलडी_PRELOAD केस के लिए भी काम करना संभव हो सकता है, मुझे यकीन नहीं है, मुझे परीक्षण करना होगा। –

2

आप भैया जैसे उपकरण का उपयोग कर समारोह मंगलाचरण की जांच कर सकते हैं:

  • gdb
  • ltrace
  • systemtap

इन उपकरणों एक मॉनिटर कार्यक्रम आपको सूचित करने के लिए अनुमति देते हैं जब एक समारोह में कहा जाता है , और आप तर्कों से पूछताछ करने की अनुमति देते हैं।

मुख्य अंतर हैं:

  • gdb इंटरैक्टिव है, लेकिन शक्तिशाली
  • ltrace सरल उपयोग करने के लिए, लेकिन आप केवल समारोह नाम
  • systemtap सहभागी नहीं है मुद्रित कर सकते हैं, लेकिन यह हो सकता है बहुत तेज़, और शक्तिशाली है।
0

यदि आप ग्लिब के साथ होस्ट सिस्टम चला रहे हैं, तो libc के पास रनटाइम गतिशील लिंकर के कुछ आंतरिक बैक एंड हैं जो मैंने कुछ समय पहले उपयोग किया था। अगर मुझे सही याद आती है, तो मुझे लगता है कि इसे '__libc_dlsym' कहा जाता है। (जांचने के लिए, "$ readelf -s /usr/lib/libc.a | grep dlsym" मदद करनी चाहिए।) इसे एक ही तर्क के साथ बाहरी रूप से जुड़े फ़ंक्शन के रूप में घोषित करें और dlsym के पास वापस लौटें और dlsym को स्वयं लपेटने के लिए इसका उपयोग करें।

0

truss आपके सिस्टम पर काम नहीं करता है? यह सोलारिस पर इस तरह की चीजों के लिए पूरी तरह से काम करता है।

+0

यह लिनक्स में बिल्कुल 'स्ट्रेस' जैसा लगता है। यह ठीक काम करता है अगर आपको केवल कॉल की सूची प्राप्त करने की आवश्यकता होती है। इस प्रोजेक्ट में, मुझे रैपर में कुछ कार्यक्षमता जोड़ने की ज़रूरत थी, और मुझे लगता है कि इसके लिए जाने का एकमात्र तरीका इंटरपोजिशन है। –