golang 无法枚举注册表项的子项

Posted

技术标签:

【中文标题】golang 无法枚举注册表项的子项【英文标题】:golang can't enumerate subkeys of registry key 【发布时间】:2018-05-28 14:02:45 【问题描述】:

我正在尝试查看整个 Windows 注册表以找到一些键和值。有些键无法使用 registry.READ 权限打开,所以要读取值和键,我必须使用 registry.QUERY_VALUE 和 registry.ENUMERATE_SUB_KEYS 权限; 但是在使用具有此类权限的 k.OpenKey()(例如 HKEY_LOCAL_MACHINE\SOFTWARE)成功打开密钥后,k.ReadSubKeyNames() 函数在两种情况下都会出错:

ReadSubKeyNames: HKEY_LOCAL_MACHINE\SOFTWARE 访问被拒绝。

当然,为管理员启用了实际的注册表项权限 QUERY_VALUE 和 ENUMERATE_SUB_KEYS(我使用的是管理员配置文件)

我应该如何在不使用 registry.READ 权限的情况下获取子键名称,这是什么问题?

代码示例:

var (
queryVal uint32 = registry.QUERY_VALUE
enumSubs uint32 = registry.ENUMERATE_SUB_KEYS
)       
k, err = registry.OpenKey(globalK, p, queryVal)
    if err != nil 
        logErr(wrapErr(fmt.Sprintf("registry.OpenKey: %s", keyPath), err))
        return
    
    defer k.Close()


newKey := someLocalType


keyStat, err := k.Stat()
if err != nil 
    logWarn(fmt.Sprintf("Stat: %s %v", keyPath, err))
    return

newKey.mod = keyStat.ModTime()

n, err := k.ReadValueNames(-1)
if err != nil 
    logWarn(fmt.Sprintf("ReadValueNames: %s %v", keyPath, err))
    return

for _, each := range n 
    v, err := getKeyValue(k, each, keyStat.MaxValueLen)
    if err != nil 
        logWarn(fmt.Sprintf("getKeyValue: %s %v", keyPath, err))
        continue
    
    newKey.val = append(newKey.val, v)


var k1 registry.Key
if len(p) != 0 
    k1, err = registry.OpenKey(globalK, p, enumSubs)
    if err != nil 
        logErr(wrapErr(fmt.Sprintf("registry.OpenKey: %s", keyPath), err))
        return
    
    defer k1.Close()
 else 
    k1 = globalK


subNames, err := k1.ReadSubKeyNames(-1)
if err != nil 
    logWarn(fmt.Sprintf("ReadSubKeyNames: %s %v", keyPath, err))
    return


for _, each := range subNames 
    newPath := joinPath(p, each)
    scanKey(globalK, newPath, c)

return

【问题讨论】:

【参考方案1】:

答案是使用组合值:

combinedRights := registry.QUERY_VALUE | registry.ENUMERATE_SUB_KEYS

因为k.ReadSubKeyNames()里面使用了k.Stat(),而k.Stat()需要registry.QUERY_VALUE权限才能成功返回,之后k.ReadSubKeyNames()使用syscall枚举子键,有registry .ENUMERATE_SUB_KEYS 权限被使用。 Windows 注册表权限可以使用 OR 来概括,这就是答案。

【讨论】:

以上是关于golang 无法枚举注册表项的子项的主要内容,如果未能解决你的问题,请参考以下文章

枚举 Windows 注册表项中的所有子项和值

我无法删除注册表子项

电脑重装系统更新

注册表没有network子项

注册表项

Windows 注册表——子项列表