Here's another approach, with human comprehensible format. I've had something several days ago, that I've posted here. However, I've made several changes.
Get Registry Key Permissions; v0.001 [2016-08-23 Rev: #0]
Code: Select all
Enumeration ;ACL_INFORMATION_CLASS
#AclRevisionInformation = 1
#AclSizeInformation
EndEnumeration
#OWNER_SECURITY_INFORMATION = $1
#DACL_SECURITY_INFORMATION = $4
Procedure TopHiveKey(TopHiveKey$)
Protected HiveKey, HiveKeyTop$
HiveKeyTop$ = UCase(TopHiveKey$)
Select HiveKeyTop$
Case "HKEY_CLASSES_ROOT"
HiveKey = #HKEY_CLASSES_ROOT
Case "HKEY_CURRENT_USER"
HiveKey = #HKEY_CURRENT_USER
Case "HKEY_LOCAL_MACHINE"
HiveKey = #HKEY_LOCAL_MACHINE
Case "HKEY_USERS"
HiveKey = #HKEY_USERS
Case "HKEY_CURRENT_CONFIG"
HiveKey = #HKEY_CURRENT_CONFIG
Default
HiveKey = #Null
EndSelect
ProcedureReturn HiveKey
EndProcedure
Procedure.b Reg_EnumAccountKeyAccessPermission(Key.s)
Protected *pSecDesc.SECURITY_DESCRIPTOR, *pDacl.ACL, *pAce.ACCESS_ALLOWED_ACE, aclSize.ACL_SIZE_INFORMATION
Protected.i hTKey, hKey, retfunc, bRtnBool, acl_ACECount, dwAccountNameSize, dwDomainNameSize, SID_NAME_USE
Protected.s TopHiveKey, KeyName, szAccountName, szDomainName, szAccountName1
TopHiveKey = StringField(Key, 1, "\")
KeyName = Mid(Key, Len(TopHiveKey)+2)
hTKey = TopHiveKey(TopHiveKey)
retfunc = RegOpenKeyEx_(hTKey, @KeyName, 0, #KEY_ALL_ACCESS, @hKey)
If retfunc = #ERROR_SUCCESS
retfunc = RegGetKeySecurity_(hKey, #DACL_SECURITY_INFORMATION|#OWNER_SECURITY_INFORMATION, #Null, @nLengthNeeded.l)
If retfunc = #ERROR_INSUFFICIENT_BUFFER
*pSecDesc = AllocateMemory(nLengthNeeded)
If Not *pSecDesc : Debug "*pSecDesc memory allocation failed." : ProcedureReturn 0 : EndIf
retfunc = RegGetKeySecurity_(hKey, #DACL_SECURITY_INFORMATION|#OWNER_SECURITY_INFORMATION, *pSecDesc, @nLengthNeeded)
EndIf
If retfunc = #ERROR_SUCCESS
Debug "Key: "+Key
If RegQueryInfoKey_(hKey, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @lpftLastWriteTime.FILETIME) = #ERROR_SUCCESS
If FileTimeToSystemTime_(@lpftLastWriteTime, @SystemTime.SYSTEMTIME)
Debug " Last Modified Date: "+FormatDate("%dd/%mm/%yyyy %hh:%ii:%ss", Date(SystemTime\wYear, SystemTime\wMonth, SystemTime\wDay, SystemTime\wHour, SystemTime\wMinute, SystemTime\wSecond))
EndIf
EndIf
Protected pOwner.i, lpbOwnerDef.l
bRetFunc = GetSecurityDescriptorOwner_(*pSecDesc, @pOwner, @lpbOwnerDef)
If bRetFunc
bRtnBool = LookupAccountSid_(#Null, pOwner, 0, @dwAccountNameSize, 0, @dwDomainNameSize, @SID_NAME_USE)
szAccountName = Space(dwAccountNameSize)
szDomainName = Space(dwDomainNameSize)
If LookupAccountSid_(#Null, pOwner, @szAccountName, @dwAccountNameSize, @szDomainName, @dwDomainNameSize, @SID_NAME_USE)
Debug ""
Debug "Object Ownership:"
Debug " Account = " + szAccountName + ", Domain = " + szDomainName
Debug ""
EndIf
dwDomainNameSize = 0
EndIf
If *pSecDesc
GetSecurityDescriptorDacl_(*pSecDesc, @bDaclPresent.l, @*pDacl, @bDaclDefault.l)
If bDaclPresent = 0
RegCloseKey_(hKey)
Debug "No DACL"
ProcedureReturn 0
Else
GetAclInformation_(*pDacl, @aclSize, SizeOf(aclSize), #AclSizeInformation)
acl_ACECount = aclSize\AceCount - 1
Repeat
GetAce_(*pDacl, acl_ACECount, @*pAce)
bRtnBool = LookupAccountSid_(#Null, @*pAce\SidStart, 0, @dwAccountNameSize, 0, @dwDomainNameSize, @snu)
szAccountName = Space(dwAccountNameSize)
szDomainName = Space(dwDomainNameSize)
bRtnBool = LookupAccountSid_(#Null, @*pAce\SidStart, @szAccountName, @dwAccountNameSize, @szDomainName, @dwDomainNameSize, @snu)
;Standard Access Rights
If *pAce\Mask & #STANDARD_RIGHTS_REQUIRED = #STANDARD_RIGHTS_REQUIRED
StandardAccess$ + "( Full Access ) | "
EndIf
If *pAce\Mask & #READ_CONTROL
StandardAccess$ + "READ_CONTROL - "
EndIf
If *pAce\Mask & #WRITE_DAC
StandardAccess$ + "WRITE_DAC - "
EndIf
If *pAce\Mask & #WRITE_OWNER
StandardAccess$ + "WRITE_OWNER - "
EndIf
If *pAce\Mask & #DELETE
StandardAccess$ + "DELETE - "
EndIf
StandardAccess$ = RemoveString(StandardAccess$, " - ", #PB_String_NoCase, Len(StandardAccess$) - 3, 1)
If *pAce\Mask & #KEY_ALL_ACCESS = #KEY_ALL_ACCESS
SpecificAcess$ + "(Full Access) - "
EndIf
If *pAce\Mask & #KEY_READ = #KEY_READ
SpecificAcess$ + "KEY_READ / KEY_EXECUTE - " ; Equivalent to KEY_EXECUTE (0x20019)
EndIf
If *pAce\Mask & #KEY_WRITE
SpecificAcess$ + "KEY_WRITE - "
EndIf
If *pAce\Mask & #KEY_QUERY_VALUE
SpecificAcess$ + "KEY_QUERY_VALUE - "
EndIf
If *pAce\Mask & #KEY_SET_VALUE
SpecificAcess$ + "KEY_SET_VALUE - "
EndIf
If *pAce\Mask & #KEY_CREATE_SUB_KEY
SpecificAcess$ + "KEY_CREATE_SUB_KEY - "
EndIf
If *pAce\Mask & #KEY_ENUMERATE_SUB_KEYS
SpecificAcess$ + "KEY_ENUMERATE_SUB_KEYS - "
EndIf
If *pAce\Mask & #KEY_NOTIFY = #KEY_NOTIFY
SpecificAcess$ + "KEY_NOTIFY - "
EndIf
If *pAce\Mask & #KEY_CREATE_LINK = #KEY_CREATE_LINK
SpecificAcess$ + "KEY_CREATE_LINK - "
EndIf
SpecificAcess$ = RemoveString(SpecificAcess$, " - ", #PB_String_NoCase, Len(SpecificAcess$) - 3, 1) ; goes away later with string formatting
Select *pAce\Header\AceType
Case #ACCESS_ALLOWED_ACE_TYPE
AceType$ = "ACCESS_ALLOWED_ACE_TYPE"
;Break
Case #ACCESS_DENIED_ACE_TYPE
AceType$ = "ACCESS_DENIED_ACE_TYPE"
;Break
Case #SYSTEM_AUDIT_ACE_TYPE
AceType$ = "SYSTEM_AUDIT_ACE_TYPE"
;Break
Default
AceType$ = "Unknown ACE type"
;Break
EndSelect
Debug "Account = " + szAccountName + ", Domain = " + szDomainName + ", Specific Access Rights = " + SpecificAcess$
Debug "Account = " + szAccountName + ", Domain = " + szDomainName + ", Standard Access Rights = " + StandardAccess$
Debug "Account = " + szAccountName + ", Domain = " + szDomainName + ", ACE Type = " + AceType$
Debug ""
szAccountName1 = szAccountName
dwDomainNameSize = 0
StandardAccess$=""
SpecificAcess$=""
acl_ACECount - 1
Until acl_ACECount < 0
EndIf
FreeMemory(*pSecDesc)
EndIf
RegCloseKey_(hKey)
ProcedureReturn 1
EndIf
EndIf
EndProcedure
Debug Reg_EnumAccountKeyAccessPermission("HKEY_CURRENT_USER\Control Panel")
When compiled;
Code: Select all
Key: HKEY_CURRENT_USER\Control Panel
Last Modified Date: 04/08/2016 02:25:09
Object Ownership:
Account = SYSTEM, Domain = NT AUTHORITY
Account = ALL APPLICATION PACKAGES, Domain = APPLICATION PACKAGE AUTHORITY, Specific Access Rights = KEY_READ / KEY_EXECUTE - KEY_WRITE - KEY_QUERY_VALUE - KEY_ENUMERATE_SUB_KEYS - KEY_NOTIFY
Account = ALL APPLICATION PACKAGES, Domain = APPLICATION PACKAGE AUTHORITY, Standard Access Rights = READ_CONTROL
Account = ALL APPLICATION PACKAGES, Domain = APPLICATION PACKAGE AUTHORITY, ACE Type = ACCESS_ALLOWED_ACE_TYPE
Account = RESTRICTED, Domain = NT AUTHORITY, Specific Access Rights = KEY_READ / KEY_EXECUTE - KEY_WRITE - KEY_QUERY_VALUE - KEY_ENUMERATE_SUB_KEYS - KEY_NOTIFY
Account = RESTRICTED, Domain = NT AUTHORITY, Standard Access Rights = READ_CONTROL
Account = RESTRICTED, Domain = NT AUTHORITY, ACE Type = ACCESS_ALLOWED_ACE_TYPE
Account = Administrators, Domain = BUILTIN, Specific Access Rights = (Full Access) - KEY_READ / KEY_EXECUTE - KEY_WRITE - KEY_QUERY_VALUE - KEY_SET_VALUE - KEY_CREATE_SUB_KEY - KEY_ENUMERATE_SUB_KEYS - KEY_NOTIFY - KEY_CREATE_LINK
Account = Administrators, Domain = BUILTIN, Standard Access Rights = ( Full Access ) | READ_CONTROL - WRITE_DAC - WRITE_OWNER - DELETE
Account = Administrators, Domain = BUILTIN, ACE Type = ACCESS_ALLOWED_ACE_TYPE
Account = SYSTEM, Domain = NT AUTHORITY, Specific Access Rights = (Full Access) - KEY_READ / KEY_EXECUTE - KEY_WRITE - KEY_QUERY_VALUE - KEY_SET_VALUE - KEY_CREATE_SUB_KEY - KEY_ENUMERATE_SUB_KEYS - KEY_NOTIFY - KEY_CREATE_LINK
Account = SYSTEM, Domain = NT AUTHORITY, Standard Access Rights = ( Full Access ) | READ_CONTROL - WRITE_DAC - WRITE_OWNER - DELETE
Account = SYSTEM, Domain = NT AUTHORITY, ACE Type = ACCESS_ALLOWED_ACE_TYPE
Account = JohnDoe, Domain = DESKTOP-5BE1L1R, Specific Access Rights = (Full Access) - KEY_READ / KEY_EXECUTE - KEY_WRITE - KEY_QUERY_VALUE - KEY_SET_VALUE - KEY_CREATE_SUB_KEY - KEY_ENUMERATE_SUB_KEYS - KEY_NOTIFY - KEY_CREATE_LINK
Account = JohnDoe, Domain = DESKTOP-5BE1L1R, Standard Access Rights = ( Full Access ) | READ_CONTROL - WRITE_DAC - WRITE_OWNER - DELETE
Account = JohnDoe, Domain = DESKTOP-5BE1L1R, ACE Type = ACCESS_ALLOWED_ACE_TYPE
1