अच्छा ... आप "शुद्ध .NET" को कैसे परिभाषित करेंगे? मैं CLR2/प्रतिनिधि/GCHandle/सरणी के साथ खेला जाता है जब मैं "JVM दुर्घटना करने के लिए कैसे" पोस्ट पढ़ा है, और कुछ इस तरह के साथ आया था:
using System;
using System.Reflection;
using System.Runtime.InteropServices;
namespace TestCLR2Crash {
static void Main(string[ ] args) {
// declare a delegate that refers to a static method,
// in this case it's a static method generated from the
// anonymous delegate.
Action action = delegate() { };
// "generate" code into an array of uint
var fakeDelegate = new uint[ ] {
// dummy values
0x00000000, 0x00000000,
// fake _methodPtrAux
0x00000000,
// native code/string
0x6AEC8B55, 0x2FD9B8F5, 0xD0FF7C81, 0x006A006A,
0x00E81F6A, 0x83000000, 0x50102404, 0x81CC5DBA,
0x8BD2FF7C, 0x47C35DE5, 0x74656572, 0x73676E69,
0x6F726620, 0x6567206D, 0x6172656E, 0x20646574,
0x65646F63, 0x00000A21
};
// fill in the fake _methodPtrAux,
// make it point to the code region in fakeDelegate
var handle = GCHandle.Alloc(fakeDelegate, GCHandleType.Pinned);
var addr = handle.AddrOfPinnedObject();
const int sizeOfUInt32 = sizeof(uint); // 4
const int indexOfCode = 3;
fakeDelegate[ 2 ] = Convert.ToUInt32(addr.ToInt32() + sizeOfUInt32 * indexOfCode);
var targetInfo = typeof(Action)
.GetField("_target", BindingFlags.NonPublic | BindingFlags.Instance);
targetInfo.SetValue(action, fakeDelegate);
action(); // Greetings from generated code!
Console.WriteLine("Greetings from managed code!");
handle.Free();
}
}
}
यह केवल CLR2 साथ पर 32-बिट Windows XP काम करने के लिए जाना जाता है x86 पर; और विस्टा और विंडोज 7 और इसी तरह के साथ काम नहीं करने के लिए भी जाना जाता है, जहां डीईपी + एएसएलआर डिफ़ॉल्ट रूप से चालू होता है।
उपरोक्त कोड के बारे में मजाक का मुद्दा यह है कि यह स्पष्ट रूप से असुरक्षित कोड का उपयोग नहीं करता है (हालांकि GCHandle.Alloc (..., GCHandleType.Pinned) सुरक्षा विशेषाधिकार की मांग करता है), फिर भी यह नकली सरणी को प्रबंधित करता है प्रतिनिधि उदाहरण, और सरणी के भीतर x86 मशीन कोड में कॉल करता है। कोड स्वयं शुद्ध सी # है, यदि आप एम्बेडेड x86 कोड को कुछ "विदेशी भाषा" के रूप में नहीं मानते हैं ;-) असल में यह स्थिर तरीकों पर सीएलआर 2 के प्रतिनिधियों के आंतरिक कार्यान्वयन का उपयोग करता है, कि वास्तव में प्रतिनिधि के कुछ निजी सदस्य वास्तव में हैं आंतरिक संकेतक मैंने x86 कोड को एक सरणी में भर दिया, जिसे प्रबंधित ढेर पर आवंटित किया गया है। इसलिए इसे काम करने के लिए, डीईपी सक्षम नहीं होना चाहिए, या हमें उस मेमोरी पेज पर निष्पादन विशेषाधिकार प्राप्त करने के लिए कुछ और तरीका ढूंढना होगा।
86 कोड इस तरह है: (छद्म MASM वाक्य रचना में)
55 push ebp
8BEC mov ebp,esp
6A F5 push -0B ; /DevType = STD_OUTPUT_HANDLE
B8 D92F817C mov eax,KERNEL32.GetStdHandle ; |
FFD0 call eax ; \GetStdHandle
6A 00 push 0 ; /pReserved = NULL
6A 00 push 0 ; |pWritten = NULL
6A 1F push 1F ; |CharsToWrite = 1F (31.)
E8 00000000 call <&next_instruction> ; |
830424 10 add dword ptr ss:[esp],10 ; |Buffer
50 push eax ; |hConsole
BA 5DCC817C mov edx,KERNEL32.WriteConsoleA ; |
FFD2 call edx ; \WriteConsoleA
8BE5 mov esp,ebp
5D pop ebp
C3 ret
यह एक व्यवहार CLI द्वारा निर्दिष्ट नहीं है, और इस तरह मोनो के रूप में अन्य CLI कार्यान्वयन पर काम नहीं करेगा। हालांकि मोनो पर समान तर्क चलाने के अन्य तरीके हैं, पहले से ही उबंटू 9.04 डब्ल्यू/मोनो 2.4 पर कोशिश की और काम किया।
मैं इसके बारे में यहाँ एक ब्लॉग पोस्ट ने लिखा है: http://rednaxelafx.javaeye.com/blog/461787
यह चीनी में है, लेकिन वहाँ कोड के बहुत सारे जो व्याख्या करनी चाहिए मैं क्या किया है। ब्लॉग पोस्ट के अंत में, एक ही चाल का उपयोग करके मैंने कुछ उदाहरण दिखाए कि आप चीजों को गलत बनाने के लिए ऊपर दिए गए कोड को कैसे बदल सकते हैं, जैसे कि SEHException प्राप्त करना।
.NET CLR के पूरे मुद्दे सार करने के लिए कंप्यूटर से दूर है, CLR के अंदर ढेर अतिप्रवाह और अन्य कीड़े रखने और (यहां तक कि एक गाड़ी ओएस के साथ) अपने भौतिक कंप्यूटर दुर्घटनाग्रस्त नहीं – Earlz
ऐसी बात है, तो संभव है, क्या यह परिभाषा के अनुसार "वीएम स्वयं में बग" श्रेणी में नहीं आता है? –
हां .. जब तक आप महत्वपूर्ण फाइलों को हटाने और सीएलआर रनटाइम – Earlz