में एक जेआईटी कंपाइलर (मूल कोड में) लिखना संभव है। मैं एक जेआईटी कंपाइलर लिखने के विचार से टकरा रहा हूं और सोच रहा हूं कि क्या यह पूरी बात लिखने के लिए सैद्धांतिक रूप से संभव है प्रबंधित कोड में। विशेष रूप से, एक बार जब आप एक बाइट सरणी में असेंबलर उत्पन्न कर लेते हैं तो आप इसे निष्पादन शुरू करने के लिए कैसे कूदते हैं?क्या एक पूरी तरह से प्रबंधित .NET भाषा
उत्तर
और अवधारणा यहां का पूरा सबूत के लिए एक पूरी तरह सक्षम एफ #
open System
open System.Runtime.InteropServices
type AllocationType =
| COMMIT=0x1000u
type MemoryProtection =
| EXECUTE_READWRITE=0x40u
type FreeType =
| DECOMMIT = 0x4000u
[<DllImport("kernel32.dll", SetLastError=true)>]
extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize, AllocationType flAllocationType, MemoryProtection flProtect);
[<DllImport("kernel32.dll", SetLastError=true)>]
extern bool VirtualFree(IntPtr lpAddress, UIntPtr dwSize, FreeType freeType);
let JITcode: byte[] = [|0x55uy;0x8Buy;0xECuy;0x8Buy;0x45uy;0x08uy;0xD1uy;0xC8uy;0x5Duy;0xC3uy|]
[<UnmanagedFunctionPointer(CallingConvention.Cdecl)>]
type Ret1ArgDelegate = delegate of (uint32) -> uint32
[<EntryPointAttribute>]
let main (args: string[]) =
let executableMemory = VirtualAlloc(IntPtr.Zero, UIntPtr(uint32(JITcode.Length)), AllocationType.COMMIT, MemoryProtection.EXECUTE_READWRITE)
Marshal.Copy(JITcode, 0, executableMemory, JITcode.Length)
let jitedFun = Marshal.GetDelegateForFunctionPointer(executableMemory, typeof<Ret1ArgDelegate>) :?> Ret1ArgDelegate
let mutable test = 0xFFFFFFFCu
printfn "Value before: %X" test
test <- jitedFun.Invoke test
printfn "Value after: %X" test
VirtualFree(executableMemory, UIntPtr.Zero, FreeType.DECOMMIT) |> ignore
0
कि खुशी से एक में एक JIT कम्पाइलर लेखन
Value before: FFFFFFFC
Value after: 7FFFFFFE
वाह! उत्कृष्ट जवाब, धन्यवाद! –
मेरे उत्थान के बावजूद, मैं अलग होना चाहता हूं: यह ** मनमाने ढंग से कोड निष्पादन ** है, जेआईटी नहीं - जेआईटी का अर्थ है "बस समय ** संकलन **", लेकिन मुझे इस कोड से "संकलन" पहलू नहीं दिखाई दे रहा है उदाहरण। – rwong
@rwong: "संकलन" पहलू मूल प्रश्न चिंताओं के दायरे में कभी नहीं था। कार्यान्वित करने की प्रबंधित कोड क्षमता * आईएल -> देशी कोड * परिवर्तन थोड़े स्पष्ट है। –
असुरक्षित कोड का उपयोग करके, आप एक प्रतिनिधि को "हैक" कर सकते हैं और इसे एक मनमानी असेंबली कोड को इंगित कर सकते हैं जिसे आपने जेनरेट किया है और एक सरणी में संग्रहीत किया है। विचार यह है कि प्रतिनिधि के पास _methodPtr
फ़ील्ड है, जिसे प्रतिबिंब का उपयोग करके सेट किया जा सकता है। यहां कुछ नमूना कोड है:
यह वह जगह है, ज़ाहिर है, एक गंदा हैक है कि किसी भी समय था जब .NET रनटाइम परिवर्तन पर काम करना बंद कर सकता है की।
मुझे लगता है कि, सिद्धांत रूप में, पूरी तरह से प्रबंधित सुरक्षित कोड को जेआईटी को लागू करने की अनुमति नहीं दी जा सकती है, क्योंकि यह रनटाइम पर निर्भर करता है कि किसी भी सुरक्षा धारणा को तोड़ देगा। (जब तक, जेनरेटेड असेंबली कोड मशीन-चेक करने योग्य सबूत के साथ नहीं आया है कि यह धारणाओं का उल्लंघन नहीं करता है ...)
अच्छा हैक। शायद आप टूटी हुई लिंक के साथ बाद के मुद्दों से बचने के लिए कोड के कुछ हिस्सों को इस पोस्ट में कॉपी कर सकते हैं। (या बस इस पोस्ट में एक छोटा सा विवरण लिखें)। –
यदि मैं आपका उदाहरण चलाने की कोशिश करता हूं तो मुझे 'AccessViolationException' मिलता है। मुझे लगता है कि यह केवल तभी काम करता है जब डीईपी अक्षम हो। –
लेकिन अगर मैं EXECUTE_READWRITE ध्वज के साथ स्मृति आवंटित करता हूं और _methodPtr फ़ील्ड में इसका उपयोग करता हूं तो यह ठीक काम करता है। रोटर-कोड के माध्यम से देखकर, यह मूल रूप से मार्शल। गेटडिलेगेटफोरफंक्शन पॉइंटर() करता है, सिवाय इसके कि यह स्टैक और हैंडलिंग सुरक्षा स्थापित करने के लिए कोड के चारों ओर कुछ अतिरिक्त थंक्स जोड़ता है। –
हाँ, आप कर सकते हैं। असल में, यह मेरा काम है :)
मैंने पूरी तरह से एफ # (मॉड्यूलो हमारे यूनिट परीक्षण) में GPU.NET लिखा है - यह वास्तव में .NET CLR की तरह रन-टाइम पर डिस्सेबल और जेआईटीएस आईएल लिखा है। हम जो भी अंतर्निहित त्वरण उपकरण का उपयोग करना चाहते हैं उसके लिए हम देशी कोड उत्सर्जित करते हैं; वर्तमान में हम केवल एनवीडिया जीपीयू का समर्थन करते हैं, लेकिन मैंने अपने सिस्टम को कम से कम काम के साथ पुनः लक्षित करने के लिए डिज़ाइन किया है, इसलिए संभवतः हम भविष्य में अन्य प्लेटफॉर्म का समर्थन करेंगे।
प्रदर्शन के लिए, मेरे पास एफ # धन्यवाद है - ऑप्टिमाइज्ड मोड (टेलकॉल के साथ) में संकलित होने पर, हमारे जेआईटी कंपाइलर शायद सीएलआर (जो सी ++, आईआईआरसी में लिखा गया है) के भीतर कंपाइलर जितना तेज हो।
निष्पादन के लिए, हमारे पास जेट कोड चलाने के लिए हार्डवेयर ड्राइवरों को नियंत्रण पास करने में सक्षम होने का लाभ है; हालांकि, सीपीयू पर ऐसा करना मुश्किल नहीं होगा क्योंकि .NET फ़ंक्शन पॉइंटर्स को अप्रबंधित/मूल कोड के लिए समर्थन करता है (हालांकि आप सामान्य रूप से .NET द्वारा प्रदान की गई कोई सुरक्षा/सुरक्षा खो देंगे)।
NoExecute का पूरा बिंदु नहीं है कि आप उस कोड पर कूद नहीं सकते जिसे आपने स्वयं बनाया है? एक फ़ंक्शन पॉइंटर के माध्यम से मूल कोड पर कूदने के बजाय: क्या यह ** सूचक नहीं है ** फ़ंक्शन पॉइंटर के माध्यम से देशी कोड पर कूदना संभव है? –
एक बहुत ही अच्छी परियोजना की तरह लगता है। –
बहुत बढ़िया प्रोजेक्ट, हालांकि मुझे लगता है कि अगर आप इसे गैर-लाभकारी अनुप्रयोगों के लिए मुफ्त बनाते हैं तो आपको बहुत अधिक जोखिम मिलेगा। आप "उत्साही" स्तर से चंप-परिवर्तन खो देंगे, लेकिन इसका उपयोग करने वाले लोगों से बढ़े हुए एक्सपोजर के लिए यह उचित होगा * (मुझे पता है कि मैं निश्चित रूप से करूंगा;)) *! –
चाल VirtualAllocEXECUTE_READWRITE
-flag (पी/Invoke की आवश्यकता है) और Marshal.GetDelegateForFunctionPointer के साथ होना चाहिए।
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint Ret1ArgDelegate(uint arg1);
public static void Main(string[] args){
// Bitwise rotate input and return it.
// The rest is just to handle CDECL calling convention.
byte[] asmBytes = new byte[]
{
0x55, // push ebp
0x8B, 0xEC, // mov ebp, esp
0x8B, 0x45, 0x08, // mov eax, [ebp+8]
0xD1, 0xC8, // ror eax, 1
0x5D, // pop ebp
0xC3 // ret
};
// Allocate memory with EXECUTE_READWRITE permissions
IntPtr executableMemory =
VirtualAlloc(
IntPtr.Zero,
(UIntPtr) asmBytes.Length,
AllocationType.COMMIT,
MemoryProtection.EXECUTE_READWRITE
);
// Copy the machine code into the allocated memory
Marshal.Copy(asmBytes, 0, executableMemory, asmBytes.Length);
// Create a delegate to the machine code.
Ret1ArgDelegate del =
(Ret1ArgDelegate) Marshal.GetDelegateForFunctionPointer(
executableMemory,
typeof(Ret1ArgDelegate)
);
// Call it
uint n = (uint)0xFFFFFFFC;
n = del(n);
Console.WriteLine("{0:x}", n);
// Free the memory
VirtualFree(executableMemory, UIntPtr.Zero, FreeType.DECOMMIT);
}
Full example (अब दोनों x86 और x64 के साथ काम करता है):
यहाँ घुमाने पूर्णांक उदाहरण का एक संशोधित संस्करण (ध्यान दें कि असुरक्षित कोड यहाँ की जरूरत है) है।
शानदार, धन्यवाद! –
- 1. एक पूरी तरह से प्रबंधित डेटाबेस समाधान?
- 2. पूरी तरह से प्रबंधित साझा स्मृति .NET कार्यान्वयन?
- 3. क्या पूरी तरह से प्रबंधित एएसपीनेट सी # वेब एप्लिकेशन
- 4. एक एप्लेट पूरी तरह से
- 5. नेटबीन्स में आईडीई भाषा को पूरी तरह से बदलें 6.8
- 6. पूरी तरह से nullptr
- 7. पूरी तरह से अजगर
- 8. क्या सी ++ पूरी तरह उन्मुख भाषा का ऑब्जेक्ट है?
- 9. एक पूरी तरह से अनुकूलित एनएसएर्टर्ट
- 10. मैं पूरी तरह से एक रेल आवेदन
- 11. एक पूरी तरह से स्थित div
- 12. .NET में पूरी तरह से नया x509Certificate2 कैसे बनाएं?
- 13. पूरी तरह से .NET संस्करणों और पिछड़े संगतता को समझना
- 14. एक पूरी तरह से विशिष्ट वर्ग टेम्पलेट
- 15. एक लिंक पूरी तरह से अदृश्य बनाओ?
- 16. क्या कोई भाषा यूनिकोड और क्रॉस-प्लेटफ़ॉर्म को ठीक से और पूरी तरह से करती है?
- 17. पूरी तरह से कॉच डीबी
- 18. पूरी तरह से क्षैतिज पथ
- 19. एक्सेल पूरी तरह से vba
- 20. पूरी तरह से एक्सकोड लक्ष्य
- 21. पूरी तरह से गिट डेटाबेस
- 22. mysql_real_escape_string() पूरी तरह से स्ट्रिंग
- 23. TinyMCE - पूरी तरह से मान्यता
- 24. PHPExcel पूरी तरह से उत्पादन
- 25. .NET प्रबंधित मॉड्यूल क्या है?
- 26. रूबी वास्तव में पूरी तरह ऑब्जेक्ट उन्मुख भाषा है?
- 27. JAXB पूरी तरह से इंटरफेस से marshalling
- 28. गिट भंडार से एक विशिष्ट परिवर्तन हटाएं पूरी तरह से?
- 29. क्या हास्केल वास्तव में असुरक्षित कार्यक्षमता पर विचार कर एक पूरी तरह कार्यात्मक भाषा है?
- 30. स्थानीय रूप से एक पूरी तरह कार्यात्मक पेड़ संपादन
उपज कार्यान्वित में JIT को Rasmus 'दृष्टिकोण का अनुवाद है जेआईटी कंपाइलर। मुझें यह पसंद है। यह JITCEPTION है :) –
मुझे विश्वास नहीं है कि - जबकि आप प्रबंधित भाषाओं में कभी-कभी असुरक्षित संदर्भ में काम कर सकते हैं, मुझे विश्वास नहीं है * आप एक सूचक से एक प्रतिनिधि को संश्लेषित कर सकते हैं - और आप कैसे कूदेंगे जेनरेट कोड के लिए? –
@ डेमियन: असुरक्षित कोड आपको फ़ंक्शन पॉइंटर पर लिखने नहीं देगा? –