当前位置:   article > 正文

Accessing 64 bit registry from a 32 bit process_error: ‘mbedtls_sha512_finish_ret’ accessing 64 by

error: ‘mbedtls_sha512_finish_ret’ accessing 64 bytes in a region of size

As you may know, Windows is virtualizing some parts of the registry under 64 bit.

So if you try to open, for example, this key : “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\90″, from a 32 bit C# application running on a 64 bit system, you will be redirected to : “HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SQL Server\90″

Why ? Because Windows uses the Wow6432Node registry entry to present a separate view of HKEY_LOCAL_MACHINE\SOFTWARE for 32 bit applications that runs on a 64 bit systems.

If you want to explicitly open the 64 bit view of the registry, here is what you have to perform :

You are using VS 2010 and version 4.x of the .NET framework

It’s really simple, all you need to do is, instead of doing :

//Will redirect you to the 32 bit view
RegistryKey sqlsrvKey = Registry.LocalMachine.OpenSubKey( @"SOFTWARE\Microsoft\Microsoft SQL Server\90" );

do the following :

RegistryKey localMachineX64View = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey sqlsrvKey = localMachineX64View.OpenSubKey( @"SOFTWARE\Microsoft\Microsoft SQL Server\90" );

Prior versions of the .NET framework

For the prior versions of the framework, we have to use P/Invoke and call the function RegOpenKeyExW with parameter KEY_WOW64_64KEY

enum RegWow64Options
{
     None = 0,
     KEY_WOW64_64KEY = 0x0100,
     KEY_WOW64_32KEY = 0x0200
}
 
enum RegistryRights
{
     ReadKey = 131097,
     WriteKey = 131078
}
 
/// <summary>
/// Open a registry key using the Wow64 node instead of the default 32-bit node.
/// </summary>
/// <param name="parentKey">Parent key to the key to be opened.</param>
/// <param name="subKeyName">Name of the key to be opened</param>
/// <param name="writable">Whether or not this key is writable</param>
/// <param name="options">32-bit node or 64-bit node</param>
/// <returns></returns>
static RegistryKey _openSubKey(RegistryKey parentKey, string subKeyName, bool writable, RegWow64Options options)
{
     //Sanity check
     if (parentKey == null || _getRegistryKeyHandle(parentKey) == IntPtr.Zero)
     {
         return null ;
     }
 
     //Set rights
     int rights = ( int )RegistryRights.ReadKey;
     if (writable)
         rights = ( int )RegistryRights.WriteKey;
 
     //Call the native function >.<
     int subKeyHandle, result = RegOpenKeyEx(_getRegistryKeyHandle(parentKey), subKeyName, 0, rights | ( int )options, out subKeyHandle);
 
     //If we errored, return null
     if (result != 0)
     {
         return null ;
     }
 
     //Get the key represented by the pointer returned by RegOpenKeyEx
     RegistryKey subKey = _pointerToRegistryKey((IntPtr)subKeyHandle, writable, false );
     return subKey;
}
 
/// <summary>
/// Get a pointer to a registry key.
/// </summary>
/// <param name="registryKey">Registry key to obtain the pointer of.</param>
/// <returns>Pointer to the given registry key.</returns>
static IntPtr _getRegistryKeyHandle(RegistryKey registryKey)
{
     //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
     SafeHandle handle = (SafeHandle)fieldInfo.GetValue(registryKey);
     //Get the unsafe handle
     IntPtr dangerousHandle = handle.DangerousGetHandle();
     return dangerousHandle;
}
 
/// <summary>
/// Get a registry key from a pointer.
/// </summary>
/// <param name="hKey">Pointer to the registry key</param>
/// <param name="writable">Whether or not the key is writable.</param>
/// <param name="ownsHandle">Whether or not we own the handle.</param>
/// <returns>Registry key pointed to by the given pointer.</returns>
static RegistryKey _pointerToRegistryKey(IntPtr hKey, bool writable, bool ownsHandle)
{
     //Get the BindingFlags for private contructors
     System.Reflection.BindingFlags privateConstructors = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic;
     //Get the Type for the SafeRegistryHandle
     Type safeRegistryHandleType = typeof (Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid).Assembly.GetType( "Microsoft.Win32.SafeHandles.SafeRegistryHandle" );
     //Get the array of types matching the args of the ctor we want
     Type[] safeRegistryHandleCtorTypes = new Type[] { typeof (IntPtr), typeof ( bool ) };
     //Get the constructorinfo for our object
     System.Reflection.ConstructorInfo safeRegistryHandleCtorInfo = safeRegistryHandleType.GetConstructor(
     privateConstructors, null , safeRegistryHandleCtorTypes, null );
     //Invoke the constructor, getting us a SafeRegistryHandle
     Object safeHandle = safeRegistryHandleCtorInfo.Invoke( new Object[] { hKey, ownsHandle });
 
     //Get the type of a RegistryKey
     Type registryKeyType = typeof (RegistryKey);
     //Get the array of types matching the args of the ctor we want
     Type[] registryKeyConstructorTypes = new Type[] { safeRegistryHandleType, typeof ( bool ) };
     //Get the constructorinfo for our object
     System.Reflection.ConstructorInfo registryKeyCtorInfo = registryKeyType.GetConstructor(
     privateConstructors, null , registryKeyConstructorTypes, null );
     //Invoke the constructor, getting us a RegistryKey
     RegistryKey resultKey = (RegistryKey)registryKeyCtorInfo.Invoke( new Object[] { safeHandle, writable });
     //return the resulting key
     return resultKey;
}
 
[DllImport( "advapi32.dll" , CharSet = CharSet.Auto)]
public static extern int RegOpenKeyEx(IntPtr hKey, string subKey, int ulOptions, int samDesired, out int phkResult);

Then we can open our registry key like this :

RegistryKey sqlsrvKey = _openSubKey(Registry.LocalMachine, @"SOFTWARE\Microsoft\Microsoft SQL Server\90" , false , RegWow64Options.KEY_WOW64_64KEY);

As you can see, the framework 4 make our life easier.


Referenced from: http://dotnetgalactics.wordpress.com/2010/05/10/accessing-64-bit-registry-from-a-32-bit-process/

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/325018?site
推荐阅读
相关标签
  

闽ICP备14008679号