2017-02-17 128 views
1

我最近一直在研究一个非常好的注册表编辑器。C#WPF - 即使使用管理员权限,也不允许注册表访问?

然而,某些注册表项,下面的注册表编辑器中指出,在我的程序不会出现,因为他们提出的权限不足的错误时打开,因此被错误处理捕获并跳过:

注册表编辑器:

Registry 1

我的程序:

Registry 2

正如您所看到的,即使我使用管理员权限运行程序,SECURITY键也会丢失,并且SAM键不可扩展。

这显然可以通过制作假钥匙并将它们放在那里,并为它们显示一个空的默认值来解决,但这不是一个具体的解决方案,只是让用户看起来像是问题解决了。

我想知道是否有办法以具体的方式解决问题,换句话说,接收注册表访问这些密钥?

它们显示的所有内容都是空的默认值,包括可扩展的SAM键 - 它只是一个名为'SAM'的子键,其默认值为空。

但是,对于用户来说,如果程序完全按照Regedit显示,则会更好,因为这意味着它是一个功能完整的软件。

感谢您的帮助。

编辑(包括代码):

public static void TreeViewItemExpanded(TreeViewItem sender) 
     { 
      if (sender.Items[0] is string) 
      { 
       sender.Items.Clear(); 

       RegistryKey expandedKey = (RegistryKey)sender.Tag; 

       foreach (string key in expandedKey.GetSubKeyNames().OrderBy(x => x)) try { sender.Items.Add(CreateTreeViewItem(expandedKey.OpenSubKey(key))); } catch { } 
      } 
     } 

     private static TreeViewItem CreateTreeViewItem(RegistryKey key) 
     { 
      TreeViewItem treeViewItem = new TreeViewItem() { Header = new RegistryEditor_RegistryStructure_TreeView() { Name = Path.GetFileName(key.ToString()) }, Tag = key }; 

      try { if (key.SubKeyCount > 0) treeViewItem.Items.Add("Loading..."); } catch { } 

      return treeViewItem; 
     } 

回答

1

你没有提供的示例代码到你的日常,但我有,你使用的是默认的注册表的安全描述符suspision。

当您调用RegCreateKeyEx或RegSetKeySecurity函数时,您可以为注册表项指定安全描述符。

当您调用RegOpenKeyEx函数时,系统会根据密钥的安全描述符检查请求的访问权限。如果用户没有对注册表项的正确访问权限,则打开操作失败。如果管理员需要访问密钥,解决方案是启用SE_TAKE_OWNERSHIP_NAME权限并使用WRITE_OWNER权限打开注册表项。MSDN:

此信息是取自 https://msdn.microsoft.com/en-us/library/windows/desktop/ms724878(v=vs.85).aspx

在C#中,您应该使用系统登录权限类 https://msdn.microsoft.com/en-us/library/system.security.permissions.registrypermission(v=vs.110).aspx

如何处理注册表权限一个很好的例子可以在这里找到: https://msdn.microsoft.com/en-us/library/microsoft.win32.registrykey.setaccesscontrol(v=vs.110).aspx

+0

我已经编辑过,以包含每次键展开和创建时使用的代码。 我正在使用RegistryKey.OpenSubKey(子键) 如何使用RegCreateKeyEx? – Aleksbgbg

+0

@Aleksbgbg我添加了更多的链接,这些链接解释了如何在.NET中处理Registry Security。第三个链接在C#中显示了一个例子,它可以帮助你。祝你好运! –

0

您需要启用SE_RESTORE_PRIVILEGESE_BACKUP_PRIVILEGE并使用RegOpenKeyExZwOpenKeyExREG_OPTION_BACKUP_RESTORE fla克(视窗的但这将是工作只能从Windows 7开始和更高版本)

如果设置了这个标志,函数忽略samDesired参数和 尝试打开与需要访问的关键备份或还原 的关键。如果调用线程启用了SE_BACKUP_NAME权限 ,则会使用ACCESS_SYSTEM_SECURITY和 KEY_READ访问权限打开密钥。如果调用线程启用了SE_RESTORE_NAME 权限,则从Windows Vista开始,密钥将以ACCESS_SYSTEM_SECURITY,DELETE和KEY_WRITE访问权限打开 。 如果同时启用了这两个权限,则该密钥对于这两种权限都具有组合的访问权限 。


例如

#define LAA(se) {{se},SE_PRIVILEGE_ENABLED|SE_PRIVILEGE_ENABLED_BY_DEFAULT} 
#define BEGIN_PRIVILEGES(tp, n) static const struct {ULONG PrivilegeCount;LUID_AND_ATTRIBUTES Privileges[n];} tp = {n,{ 
#define END_PRIVILEGES }}; 

ULONG AdjustBackupRestore() 
{ 
    HANDLE hToken; 
    if (OpenProcessToken(NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) 
    { 
     BEGIN_PRIVILEGES(tp, 2) 
      LAA(SE_RESTORE_PRIVILEGE), 
      LAA(SE_BACKUP_PRIVILEGE), 
     END_PRIVILEGES 

     AdjustTokenPrivileges(hToken, FALSE, (::PTOKEN_PRIVILEGES)&tp, 0, 0, 0); 
     ULONG err = GetLastError(); 
     CloseHandle(hToken); 

     return err; 
    } 

    return GetLastError(); 
} 

if (!AdjustBackupRestore())//called once on startup 
{ 
    HKEY hKey; 
    if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SECURITY\\SAM", REG_OPTION_BACKUP_RESTORE|REG_OPTION_OPEN_LINK, 0, &hKey)) 
    { 
     RegCloseKey(hKey); 
    } 
} 

但是,对于获得全功率注册表编辑器/浏览器我是使用原生API

enter image description here

相关问题