2010-04-22 18 views
33

मैं सी # प्रतिबिंब एपीआई के साथ खेल रहा हूं। मैं असेंबली में कक्षाओं, विधियों इत्यादि की आसानी से Type जानकारी लोड कर सकता हूं, हालांकि, अब मुझे आश्चर्य है कि मैं विधि के अंदर कोड कैसे लोड और पढ़ सकता हूं?क्या मैं विधि में कोड का निरीक्षण करने के लिए प्रतिबिंब का उपयोग कर सकता हूं?

+0

क्या यह परिदृश्य है जो इसे उपयोगी बनाता है? यह ओओ के मौलिक किरायेदारों में से एक तोड़ता है जो encapsulation है। लेकिन इसके अलावा आईएल के रूप में कोड वास्तव में वही नहीं है। – DevelopingChris

+8

@ डेवलपिंग क्रिस: यदि आप एक डीबगर या कोड विश्लेषण उपकरण लिख रहे हैं, तो यह एक असेंबली लोड करने और विधि के शरीर का विश्लेषण करने में सक्षम होने के लिए उपयोगी हो सकता है। यह वास्तव में, FxCop जैसे उपकरण हैं। – LBushkin

+0

.NET का लक्षित दर्शक अमेरिकी निगम है (और दूसरा शायद कुछ छोटे व्यवसाय)। यदि आप .NET obfuscation को बाईपास कर सकते हैं, तो (उत्पादन करने में महंगा) सॉफ़्टवेयर आसानी से प्रतिस्पर्धी की उंगलियों में उड़ सकता है। – micahhoover

उत्तर

31

बेसिक उत्तर:

आप कर सकते हैं प्रतिबिंब एपीआई (System.Reflection) के साथ नहीं।

कारण यह है कि प्रतिबिंब एपीआई मेटाडेटा (वर्गों का प्रकार, नाम और विधि के हस्ताक्षर, ...) पर काम करने के लिए डिज़ाइन किया गया है, लेकिन डेटा स्तर पर नहीं (जो आईएल-स्ट्रीम स्वयं होगा)।

विस्तारित उत्तर:

आप फेंकना कर सकते हैं (न कि उन्हें पढ़ने) System.Reflection.Emit साथ आईएल (जैसे ILGenerator श्रेणी)।

MethodInfo.GetMethodBody() के माध्यम से आप एक विधि के कार्यान्वयन के लिए बाइनरी आईएल-स्ट्रीम प्राप्त कर सकते हैं। लेकिन आमतौर पर यह पूरी तरह से बेकार है।

बाह्य पुस्तकालय (जैसे Cecil) हैं जिनका उपयोग आप किसी विधि के अंदर कोड को पढ़ने/संशोधित/जोड़ने/हटाने के लिए कर सकते हैं।

+1

क्या आप प्रतिनिधि के माध्यम से विधि का उल्लेख नहीं कर सकते हैं, फिर प्रतिनिधि से अभिव्यक्ति ट्री बनाएं और पेड़ का निरीक्षण करें? –

+1

@ मैट ग्रीर: नहीं। आप एक प्रतिनिधि के विधि शरीर को एक अभिव्यक्ति वृक्ष में "रिवर्स इंजीनियर" नहीं कर सकते हैं। – LBushkin

+0

@ मैट: यह आपको कोड * अंदर * कोड नहीं दे रहा है, आपको बस 'MethodCallExpression' मिलेगा जो आपको उसी' MethodInfo' तक पहुंच प्रदान करता है जिसे आप प्रतिबिंब API के साथ अधिक सीधे प्राप्त कर सकते थे। – Aaronaught

1

नहीं
यह एक विशेषता है जो सी # के अगले संस्करण के लिए बनाई गई है। प्रतिबिंब की तुलना में अधिक जानकारी प्राप्त करने के लिए आप CodeDom का उपयोग कर सकते हैं, लेकिन आप अभी तक पार्स पेड़ से पूछताछ नहीं कर सकते हैं।

वैसे हमेशा मोनो होता है, मोनो में कंपाइलर एक सेवा है, और आप रनटाइम पर पार्स पेड़ प्राप्त कर सकते हैं।

बेहतर सवाल यह है कि आप क्यों चाहते हैं?

1

हां, इसे प्राप्त करने का एक तरीका होना चाहिए: .NET Reflector Tool यह भी करता है। हालांकि, आपको यह नहीं बता सकता कि यह कैसे किया गया है।

+1

आप परावर्तक को प्रतिबिंबित क्यों नहीं करते हैं;) – ntziolis

+9

परावर्तक का उपयोग नहीं करता है प्रतिबिंब के .NET ढांचे की भावना में कम से कम प्रतिबिंब नहीं। यह वास्तव में पीई फ़ाइल को पार करता है और आईएल कोड को .TEXT अनुभाग से अलग करता है। फिर आईएल को एक लक्षित भाषा में मानचित्र/डिकंपाइल करने के लिए मिलान करने वाला कुछ बहुत ही स्मार्ट और शांत पैटर्न होता है। –

2

यदि आपको यह वास्तविक समय करने की आवश्यकता नहीं है, तो Reflector पर एक नज़र डालें। आप किसी भी .NET असेंबली (एमएस कोर डीएलएल सहित) को अलग कर सकते हैं और अपनी पसंद की भाषा में कोड देख सकते हैं। यह बहुत शैक्षणिक हो सकता है।

अद्यतन क्या किसी ने इस बात को समझने के लिए परावर्तक पर परावर्तक का उपयोग करने का प्रयास किया है?

+1

नोट, यह कोड को डी-अनुकूलित नहीं करता है। इसलिए यदि आईएल को एक कंपाइलर अनुकूलन किया गया था, तो यह अपने मूल निर्माण स्रोत पर वापस नहीं लौटाया जाता है, लेकिन थोड़ा कम मानव लिखित अनुकूलित संस्करण में।यह देखने का एक साफ तरीका है कि आप सबसे कुशलता से क्या कर सकते हैं। – DevelopingChris

+0

आप परावर्तक पर परावर्तक का उपयोग नहीं कर सकते हैं। इसे आज़माएं और देखें, आपको एक अच्छा आश्चर्य मिलेगा। – Aaronaught

+1

परावर्तक एन्क्रिप्ट किया गया है कि यह स्वयं पर प्रतिबिंबित नहीं हो सकता है, मुझे लगता है कि उन्होंने ऐसा करने के लिए डॉटफुस्केटर का उपयोग किया था। – DevelopingChris

16

यह कोड पढ़ने के द्वारा आपके मतलब पर निर्भर करता है। कोड के 4 रूप हैं।

1- स्रोत कोड उदा। मूल C# या VB.NET - नहीं, तुम नहीं इस प्रतिबिंब
2- प्रतीकात्मक आईएल कोड के साथ प्राप्त कर सकते हैं - नहीं, आप प्रतिबिंब के साथ इस प्राप्त नहीं कर सकते
3 JITed विधानसभा कोड - नहीं, आप प्रतिबिंब के साथ इस प्राप्त नहीं कर सकते

4- आईएल बाइट्स, आईएल संकलित वास्तविक बाइट्स, यह प्राप्त कर सकता है।

उदाहरण के लिए MethodBase.GetMethodBody() पर एक नज़र डालें, आप आईएल बाइट्स, स्थानीय चर, अपवाद फ्रेम इत्यादि प्राप्त कर सकते हैं। http://msdn.microsoft.com/en-us/library/system.reflection.methodbase.getmethodbody.aspx

+0

'GetMethodBody() 'मुझे लगता है कि निकटतम है, मुझे लगता है। – LBushkin

9

का प्रकार कर सकते हैं। प्रासंगिक कार्य MethodBase.GetMethodBody है।

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

Mono.Cecil पुस्तकालय है, जो जो वास्तविक Instructions शामिल अपने स्वयं के MethodBody कार्यान्वयन के साथ एक MethodDefinition वर्ग को उजागर करता है, तो आप कच्चे बाइट कोड की व्याख्या करने की जरूरत नहीं है में एक थोड़ा बेहतर एपीआई नहीं है। फिर भी, अगर आप इसके बारे में सी # कोड प्राप्त करना चाहते हैं, तो ला रिफ्लेक्टर, आप बहुत निराश होने जा रहे हैं। इसके अलावा, सेसिल बहुत अच्छी तरह से प्रलेखित नहीं है।

यदि आप अभी भी कोशिश करना चाहते हैं, तो शुभकामनाएं।

10

अब कर रहे हैं पुस्तकालयों/संकुल है कि आप Expression करने के लिए इसे डिकंपाइल विधि कोड का निरीक्षण किया और यहां तक ​​कि करने की अनुमति:

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

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