2011-12-06 22 views
5

यह पहली बार है कि मैं SafeHandle का उपयोग करूँगा।सुरक्षित हैंडल क्यों है। खतरनाक गेटहैंडल() "खतरनाक"?

मुझे इस पी/Invoke विधि को कॉल करने की आवश्यकता है जिसे UIntPtr की आवश्यकता है।

[DllImport("advapi32.dll", CharSet = CharSet.Auto)] 
    public static extern int RegOpenKeyEx(
     UIntPtr hKey, 
     string subKey, 
     int ulOptions, 
     int samDesired, 
     out UIntPtr hkResult); 

यह UIntPtr नेट के RegistryKey वर्ग से प्राप्त की जाएगी। मैं विधि का उपयोग किया जाएगा ऊपर एक IntPtr करने RegistryKey वर्ग कन्वर्ट करने के लिए तो मैं ऊपर पी उपयोग कर सकते हैं/आह्वान:

 private static IntPtr GetRegistryKeyHandle(RegistryKey rKey) 
     { 
      //Get the type of the RegistryKey 
      Type registryKeyType = typeof(RegistryKey); 

      //Get the FieldInfo of the 'hkey' member of RegistryKey 
      System.Reflection.FieldInfo fieldInfo = 
       registryKeyType.GetField("hkey", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 

      //Get the handle held by hkey 
      if (fieldInfo != null) 
      { 
       SafeHandle handle = (SafeHandle)fieldInfo.GetValue(rKey); 

       //Get the unsafe handle 
       IntPtr dangerousHandle = handle.DangerousGetHandle();     
       return dangerousHandle; 
      } 
} 

सवाल:

  1. वहाँ का उपयोग किए बिना इस लिखने के लिए एक बेहतर तरीका है "असुरक्षित" हैंडल?
  2. असुरक्षित हैंडल खतरनाक क्यों हैं?

उत्तर

3

आप जो कर रहे हैं वह वास्तव में खतरनाक है। जब आप IntPtr का उपयोग कर रहे हों तो रजिस्ट्रीकी ऑब्जेक्ट का उपयोग कचरा इकट्ठा और अंतिम रूप दिया जा सकता है। जो हैंडल मान अमान्य बनाता है जो आपके कोड को यादृच्छिक रूप से विफल करता है। खैर, ठीक है, यादृच्छिक विफलता बिल्कुल खतरनाक नहीं है लेकिन अगर आप वास्तव में विस्तारित अवधि के लिए हैंडल को पकड़ते हैं तो यह एक हैंडल रीसायकल हमले के लिए दरवाजा खोलता है। यादृच्छिक विफलता मोड आपको इसके बारे में कुछ करने के लिए प्रेरित करने के लिए पर्याप्त होना चाहिए।

अपने PInvoke घोषणा इस तरह बनाएं:

[DllImport("advapi32.dll", CharSet=CharSet.Auto)] 
internal static extern int RegOpenKeyEx(SafeRegistryHandle key, string subkey, 
    int options, int sam, out SafeRegistryHandle result); 

तो आप लगातार सुरक्षित संभाल आवरण वर्ग का उपयोग कर सकते हैं। तदनुसार प्रतिबिंब कोड समायोजित करें।

+0

मैं यह उल्लेख करना भूल गया कि मेरे कोड का उद्देश्य नेटफैक्स 4 के 64-बिट रजिस्ट्री समर्थन की नकल करना है। हम केवल नेटफैक्स 3.5 का उपयोग कर रहे हैं, इसलिए कोई सुरक्षित रजिस्ट्री हैडल उपलब्ध नहीं है। – Ian

+0

बस इसे सुरक्षित करेंडलजेरोरोमिनसऑनइन्स इनवालिड, सुरक्षित रजिस्ट्री हैडल का आधार वर्ग। या यदि आप नाम टाइप करना नफरत करते हैं (जो नहीं) तो केवल सादा सेफहैंडल। –

4

रजिस्ट्रीकी की एक हैंडल संपत्ति है। तो तुम

private static IntPtr GetRegistryKeyHandle(RegistryKey rKey) 
{ 
    return rKey.Handle.DangerousGetHandle; 
} 

यह संभावित रूप से खतरनाक है, अब और उपयोग कर सकते हैं क्योंकि सूचक आप हो रही है मान्य नहीं हो सकता है जब आप इसे उपयोग कर रहे हैं। से MSDN

DangerousGetHandle पद्धति का उपयोग करना क्योंकि, अगर संभाल SetHandleAsInvalid साथ के रूप में अवैध चिह्नित किया गया है, DangerousGetHandle अभी भी मूल, संभवतः बासी संभाल मान देता है सुरक्षा जोखिम पैदा कर सकते हैं उद्धरण। लौटा संभाल भी किसी भी बिंदु पर पुनर्नवीनीकरण किया जा सकता है। सबसे अच्छा, इसका मतलब है कि हैंडल अचानक काम करना बंद कर सकता है। सबसे बुरी स्थिति में, अगर हैंडल या संसाधन जो हैंडल का प्रतिनिधित्व करता है, अविश्वसनीय कोड से अवगत कराया जाता है, तो यह पुन: उपयोग या लौटे हुए हैंडल पर रीसाइक्लिंग सुरक्षा हमले का कारण बन सकता है। उदाहरण के लिए, एक अविश्वसनीय कॉलर संभाल पर डेटा से पूछताछ कर सकता है और पूरी तरह से असंबंधित संसाधन के लिए जानकारी प्राप्त कर सकता है। खतरनाक गेटहैंडल विधियों का उपयोग करने के बारे में अधिक जानकारी के लिए खतरनाक एड्रॉफ और खतरनाक रिलीज विधियों को देखें।

+0

मैं यह उल्लेख करना भूल गया कि मेरे कोड का उद्देश्य नेटफैक्स 4 के 64-बिट रजिस्ट्री समर्थन की नकल करना है। हम केवल नेटफैक्स 3.5 का उपयोग कर रहे हैं इसलिए रजिस्ट्रीकी क्लास में कोई हैंडल सदस्य नहीं है। – Ian

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