使用RegSetKeySecurity避免注册表重定向

本文关键字:注册表 重定向 RegSetKeySecurity 使用 | 更新日期: 2023-09-27 18:03:50

为了避免注册表重定向到Wow64键,如何翻译以下使用Microsoft.Win32 api的代码

public void SetKeyAccessControl(
            RegistryKey rootKey, string subKeyName, string identity, 
            RegistryRights rights, InheritanceFlags inheritanceFlags,
            PropagationFlags propagationFlags, AccessControlType accessType)
{
   using (RegistryKey regKey = rootKey.OpenSubKey(subKeyName, true))
   {
       RegistrySecurity acl = new RegistrySecurity();
       RegistryAccessRule rule = new RegistryAccessRule(identity, rights, inheritanceFlags, propagationFlags, accessType);
       acl.AddAccessRule(rule);
       regKey.SetAccessControl(acl);
   }            
}

使用advapi32 RegSetKeySecurity API

[DllImport(@"advapi32.dll", EntryPoint = "RegSetKeySecurity", SetLastError = true)]
internal static extern int RegSetKeySecurity(IntPtr handle, uint securityInformation, IntPtr pSecurityDescriptor);

使用RegSetKeySecurity避免注册表重定向

要避免注册表重定向,您可以这样做…

SafeRegistryHandle handle = rootKey.Handle;
RegistryKey rootKey32 = RegistryKey.FromHandle(handle, RegistryView.Registry32);
RegistryKey rootKey64 = RegistryKey.FromHandle(handle, RegistryView.Registry64);

你可以使用rootKey32或rootKey64打开一个子密钥,你会得到所请求的视图的子密钥。

至少它在我尝试过的几个测试用例中有效。并且,根据FromHandle的文档…

此方法的view参数用于后续操作,例如打开子密钥

需要涉及另一个本机方法并给定一个SDDL,下面的代码将acl设置在正确的注册表项上:


[DllImport("Advapi32.dll", CallingConvention = CallingConvention.Winapi, SetLastError = true, CharSet = CharSet.Auto)]
internal static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string stringSecurityDescriptor, int stringSDRevision, out IntPtr ppSecurityDescriptor, ref int securityDescriptorSize);
string sddl = "...";
IntPtr secDescriptor = IntPtr.Zero;
int size = 0;
ConvertStringSecurityDescriptorToSecurityDescriptor
   (
      sddl,
      1,                              // revision 1
      out secDescriptor,
      ref size
   );
// get handle with RegOpenKeyEx
RegSetKeySecurity
(
     handle,
     0x00000004,                      // DACL_SECURITY_INFORMATION
     secDescriptor
);