2011-06-03 20 views
13

मैं आवेदन (सी ++ में लिखा गया) पर काम कर रहा हूं, जो रनटाइम पर कुछ मशीन कोड उत्पन्न करता है (लिनक्स, x86-64 अब, लेकिन मैं एआरएम पर माइग्रेट करने की योजना बना रहा हूं)। इसके बाद यह स्मृति में जेनरेट कोड संग्रहीत करें और मेमोरी लोकेशन पर कूदकर इसे निष्पादित करें। एक लंबे समय के लिए मैं निष्पादन योग्य स्मृति आवंटन के साथ एक समस्या थी, लेकिन मैं अंत में का उपयोग कर इसे हल:रनटाइम पर निष्पादन योग्य कोड में कोड

uint8_t *memory = mmap (NULL, length, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 

अब तक यह काम करता है, लेकिन मुझे यकीन है कि अगर यह इस तरह के काम करने के लिए सुरुचिपूर्ण तरीका है नहीं कर रहा हूँ। मुझे आश्चर्य है कि निष्पादन योग्य लोडर यह कैसे करता है?

+1

यह वही तरीका है। –

+0

संभावित डुप्लिकेट [लिनक्स पर सी में निष्पादन योग्य राम आवंटित करें] (http://stackoverflow.com/questions/3125756/allocate-executable-ram-in-c-on-linux) – ninjalj

उत्तर

13

यह अनिवार्य रूप से निष्पादन योग्य लोडर चीजें कैसे करता है; उनके मामले में वे फ़ाइल के mmap निष्पादित करते हैं, न कि अज्ञात मैपिंग, लेकिन इसके अलावा यह अनिवार्य रूप से वही है।

ध्यान दें कि एक अच्छा विचार है कि दोनों एक ही समय में लिखने और निष्पादित न करें, क्योंकि इससे कुछ प्रकार के सुरक्षा शोषण आसान हो जाते हैं। प्रारंभिक मैपिंग के बाद सुरक्षा फ़्लैग को समायोजित करने के लिए आप mprotect का उपयोग कर सकते हैं।

13

आपका समाधान अधिकतर किया जाना चाहिए: ओएस को पृष्ठों को निष्पादन योग्य मानते हैं। हालांकि, कुछ ऑपरेटिंग सिस्टम तथाकथित W^X नीति को लागू करेंगे, जिसमें एक पृष्ठ या तो लिखने योग्य या निष्पादन योग्य हो सकता है, लेकिन दोनों एक साथ नहीं। ऐसे सिस्टम (जैसे ओपनबीएसडी, लेकिन संशोधित लिनक्स संस्करण भी हैं जो इसे भी करते हैं), आपके mmap() उपरोक्त विफल हो जाएंगे। तो पूरा समाधान पहले mmap() और PROT_READ | PROT_WRITE के साथ कुछ पृष्ठों को आवंटित करने के लिए लागू होगा, फिर कोड उत्पन्न होने पर पृष्ठों को PROT_READ | PROT_EXEC पर स्विच करने के लिए mprotect() का उपयोग करें।

भले ही ओएस डब्ल्यू^एक्स को लागू नहीं करता है, कैश प्रभावों के कारण mprotect() पर कॉल की अत्यधिक अनुशंसा की जाती है (सीपीयू में डेटा एक्सेस और निष्पादन एक-दूसरे से अलग होते हैं; आप यह सुनिश्चित करना चाहते हैं कि सीपीयू अपने नए लिखित ऑपोड्स का उपयोग करें और न कि पहले रैम में क्या था; mprotect() में इसके लिए आवश्यक जादू शामिल है)।

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