首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么SafeHandle.DangerousGetHandle()是“危险的”?

为什么SafeHandle.DangerousGetHandle()是“危险的”?
EN

Stack Overflow用户
提问于 2011-12-06 08:12:47
回答 2查看 4.1K关注 0票数 7

这是我第一次使用SafeHandle

我需要调用这个需要UIntPtr的P/Invoke方法。

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

此UIntPtr将来自.NET的RegistryKey类。我将使用上面的方法将RegistryKey类转换为IntPtr,以便使用上面的P/Invoke:

代码语言:javascript
复制
        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. 为什么不安全的处理方法是危险的?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-12-06 12:14:17

你所做的实际上是危险的。您使用的RegistryKey对象可以在使用IntPtr时进行垃圾收集和最终确定。这使得句柄值无效,从而导致代码随机失败。好吧,随机故障并不是很危险,但是如果你能长时间保持手柄的话,它确实会打开手柄循环攻击的大门。随机的失败模式应该足以激励你去做一些事情。

使pinvoke声明如下所示:

代码语言:javascript
复制
[DllImport("advapi32.dll", CharSet=CharSet.Auto)]
internal static extern int RegOpenKeyEx(SafeRegistryHandle key, string subkey, 
    int options, int sam, out SafeRegistryHandle result);

因此,您可以始终使用安全句柄包装器类。相应地调整反射代码。

票数 4
EN

Stack Overflow用户

发布于 2011-12-06 08:20:17

RegistryKey具有句柄属性。所以你可以用

代码语言:javascript
复制
private static IntPtr GetRegistryKeyHandle(RegistryKey rKey)
{
    return rKey.Handle.DangerousGetHandle();
}

这是潜在的危险,因为当您使用指针时,得到的指针可能不再有效。来自MSDN的报价

使用DangerousGetHandle方法可能会带来安全风险,因为如果句柄被SetHandleAsInvalid标记为无效,DangerousGetHandle仍然返回原始的、可能陈旧的句柄值。返回的句柄也可以在任何时候回收。充其量,这意味着手柄可能突然停止工作。最坏的情况是,如果句柄或句柄所代表的资源暴露在不受信任的代码中,这可能导致对重用或返回的句柄进行回收安全攻击。例如,不受信任的调用方可以查询刚刚返回的句柄上的数据,并接收完全无关资源的信息。有关安全使用DangerousAddRef方法的更多信息,请参见DangerousRelease方法和DangerousGetHandle方法。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8396923

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档