#include-once
; #### Flags for _SeGetWellKnownAccountSid ####
; ============================================================================================================
Const $SE_WELLKNOWN_ADMIN = -1
Const $SE_WELLKNOWN_GUEST = -2
Const $SE_WELLKNOWN_POWER_USERS = -3
Const $SE_WELLKNOWN_USERS = -4
Const $SE_WELLKNOWN_ADMINS = -5
Const $SE_WELLKNOWN_GUESTS = -6
; ============================================================================================================
; #### Flags for SE_EXPLICIT_ACCESS.AccessMode ####
; ============================================================================================================
Const $SE_INVALID_ACCESS = 0
Const $SE_GRANT_ACCESS = 1
Const $SE_SET_ACCESS = 2
Const $SE_DENY_ACCESS = 3
Const $SE_REVOKE_ACCESS = 4
Const $SE_AUDIT_SUCCESS = 5
Const $SE_AUDIT_FAILURE = 6
; ============================================================================================================
; #### Maximum SID size ####
; ============================================================================================================
Const $SE_MAX_SID_SIZE = 68
; ============================================================================================================
; #### NT Well-Known Authorities ####
; ============================================================================================================
Const $SE_SECURITY_DIALUP_RID = 0x00000001
Const $SE_SECURITY_NETWORK_RID = 0x00000002
Const $SE_SECURITY_BATCH_RID = 0x00000003
Const $SE_SECURITY_INTERACTIVE_RID = 0x00000004
Const $SE_SECURITY_SERVICE_RID = 0x00000006
Const $SE_SECURITY_ANONYMOUS_LOGON_RID = 0x00000007
Const $SE_SECURITY_PROXY_RID = 0x00000008
Const $SE_SECURITY_SERVER_LOGON_RID = 0x00000009
Const $SE_SECURITY_LOGON_IDS_RID = 0x00000005
Const $SE_SECURITY_LOGON_IDS_RID_COUNT = 3
Const $SE_SECURITY_LOCAL_SYSTEM_RID = 0x00000012
Const $SE_SECURITY_NT_NON_UNIQUE = 0x00000015
Const $SE_SECURITY_BUILTIN_DOMAIN_RID = 0x00000020
; ============================================================================================================
; #### Relative Ids ####
; ============================================================================================================
Const $SE_DOMAIN_USER_RID_ADMIN = 0x000001F4
Const $SE_DOMAIN_USER_RID_GUEST = 0x000001F5
Const $SE_DOMAIN_GROUP_RID_ADMINS = 0x00000200
Const $SE_DOMAIN_GROUP_RID_USERS = 0x00000201
Const $SE_DOMAIN_GROUP_RID_GUESTS = 0x00000202
Const $SE_DOMAIN_ALIAS_RID_ADMINS = 0x00000220
Const $SE_DOMAIN_ALIAS_RID_USERS = 0x00000221
Const $SE_DOMAIN_ALIAS_RID_GUESTS = 0x00000222
Const $SE_DOMAIN_ALIAS_RID_POWER_USERS = 0x00000223
Const $SE_DOMAIN_ALIAS_RID_ACCOUNT_OPS = 0x00000224
Const $SE_DOMAIN_ALIAS_RID_SYSTEM_OPS = 0x00000225
Const $SE_DOMAIN_ALIAS_RID_PRINT_OPS = 0x00000226
Const $SE_DOMAIN_ALIAS_RID_BACKUP_OPS = 0x00000227
Const $SE_DOMAIN_ALIAS_RID_REPLICATOR = 0x00000228
; ============================================================================================================
; #### Lsasecur's structures definition ####
; ============================================================================================================
Const $tagSE_BUFFERW = "word Length;word MaxLength;ptr BufferW"
Const $tagSE_SID_ATTRIBUTES = "ptr Sid;dword Attributes"
Const $tagSE_LUID_ATTRIBUTES = "int64 Luid;dword Attributes"
Const $tagSE_PRIV_SET = "dword Count;dword Control;" & $tagSE_LUID_ATTRIBUTES
Const $tagSE_ACCESS_HEADER = "byte AceType;byte AceFlags;word AceSize"
Const $tagSE_ACCESS_ACE = $tagSE_ACCESS_HEADER & ";ptr AccessMask;dword SidStart"
Const $tagSE_TRUSTEE = "ptr MultiTrustee;dword MultiTrusteeOperation;dword TrusteeFrom;dword TrusteeType;ptr Name"
Const $tagSE_EXPLICIT_ACCESS = "ptr AccessMask;dword AccessMode;dword Inheritance;" & $tagSE_TRUSTEE
Const $tagSE_ACCESS_CONTROL_LIST = "word Revision;word AclSize;dword AceCount;" & $tagSE_ACCESS_ACE
Const $tagSE_ABSOLUTE_DESCRIPTOR = "word Revision;word ControlFlags;ptr Owner;ptr Group;ptr Sacl;ptr Dacl"
Const $tagSE_SELF_RELATIVE_DESCRIPTOR = "word Revision;word ControlFlags;dword Owner;dword Group;dword Sacl;dword Dacl"
Const $tagSE_GENERIC_MAPPING = "dword GenericRead;dword GenericWrite;dword GenericExecute;dword GenericAll"
Const $tagSE_TOKEN_STATISTICS = "int64 TokenId;int64 AuthenticationId;int64 ExpirationTime;long TokenType;long ImpersonationLevel;dword DynamicCharged;dword DynamicAvailable;dword GroupCount;dword PrivilegeCount;int64 ModifiedId"
Const $tagSE_PROCESS_INFO = "handle Process;handle Thread;dword ProcessId;dword ThreadId"
Const $tagSE_STARTUP_INFO = "dword Length;ptr Reserved;ptr Desktop;ptr Title;dword X;dword Y;dword XSize;dword YSize;dword XCountChars;dword YCountChars;dword FillAttributes;dword Flags;word ShowWindow;word Reserved2;ptr Reserved3;handle StdInput;handle StdOuput;handle StdError"
Const $tagSE_TREE_RESET_SECUR = "ptr Object;long ObjType;long SecurInfo;ptr Owner;ptr Group;ptr Dacl;ptr Sacl;bool KeepExplicit;ptr CallBack;ulong Invoke;ptr Context;wchar wzObject[260]"
Const $tagSE_MEMORY_NOTIFY = "ptr BaseAddress;dword Length;ptr CallBack;dword Equaled;hWnd Reserved"
Const $tagSE_SECURITY_QOS = "dword Length;dword ImpersonationLevel;bool ContextTrackingMode;boolean EffectiveOnly"
Const $tagSE_SECUR_ATTRIB = "dword Length;handle RootDir;ptr BufferW;ulong Attributes;ptr Securitydescriptor;ptr SecurityQos"
; ============================================================================================================
; #### Flags for SE_TRUSTEE.TrusteeFrom ####
; ============================================================================================================
Const $SE_TRUSTEE_IS_SID = 0
Const $SE_TRUSTEE_IS_NAME = 1
Const $SE_TRUSTEE_IS_BAD = 2
Const $SE_TRUSTEE_IS_OBJS_AND_SID = 3
Const $SE_TRUSTEE_IS_OBJS_AND_NAME = 4
; ============================================================================================================
; #### Handle to Heap ####
; ============================================================================================================
Const $SE_PROCESSHEAP = _SeProcessHeap()
; ============================================================================================================
Func _SeIsUserAdminEx($sUserName = @UserName)
Local $pDacl, $pSid, $iAccessRights
Local $aAceList[1][4] = [[_SeGetWellKnownAccountSid($SE_WELLKNOWN_ADMINS), 1, $SE_GRANT_ACCESS]]
$pSid = _SeLookupAccountName($sUserName)
$pDacl = _SeSetEntriesInAcl($aAceList)
$iAccessRights = _SeGetEffectiveRightsFromAcl($pDacl, $pSid)
Return SetError(@error, _SeLocalFree($pDacl), _SeHeapFree($pSid) * 0 + $iAccessRights)
EndFunc ;==>_SeIsUserAdminEx
Func _SeLookupAccountName($sUserName = @UserName, $sSystem = "")
Local $iResult, $pBuffer = _SeHeapAlloc($SE_MAX_SID_SIZE * 2)
$iResult = DllCall("Advapi32.dll", "bool", "LookupAccountName", "str", $sSystem, _
"str", $sUserName, "ptr", $pBuffer, "dword*", $SE_MAX_SID_SIZE, _
"ptr", $pBuffer + $SE_MAX_SID_SIZE, "dword*", $SE_MAX_SID_SIZE, "long*", 0)
If ($iResult[0]) Then
Return SetError(0, $iResult[7], $pBuffer)
Else
Return SetError(_SeLastError(), _SeHeapFree($pBuffer) * 0 + $iResult[7], 0)
EndIf
EndFunc ;==>_SeLookupAccountName
Func _SeSetEntriesInAcl(ByRef $aEntry, $pExistingAcl = 0)
Local $iUBound, $pBuffer, $iResult
$iUBound = UBound($aEntry)
$pBuffer = _SeInitExplicitEntries($aEntry, $iUBound)
If ($pBuffer = 0) Then Return SetError(@error, 0, 0)
$iResult = DllCall("AdvApi32.dll", "dword", "SetEntriesInAcl", "ulong", $iUBound, _
"ptr", $pBuffer, "ptr", $pExistingAcl, "ptr*", 0)
If ($iResult[0]) Then
Return SetError($iResult[0], _SeHeapFree($pBuffer), 0)
Else
Return SetExtended(_SeHeapFree($pBuffer), $iResult[4])
EndIf
EndFunc ;==>_SeSetEntriesInAcl
Func _SeGetWellKnownAccountSid($iWellKnown)
Local $pSid
Switch $iWellKnown
Case $SE_WELLKNOWN_ADMIN, $SE_WELLKNOWN_GUEST
#CS
Local $aUser, $aRid[2] = [500, 501]
$aUser = _SeEnumLocalUsers($SE_FILTER_NORMAL_ACCOUNT)
For $i = 1 To $aUser[0][0]
If $aUser[$i][3] = $aRid[Abs($iWellKnown) - 1] Then
$pSid = _SeLookupAccountName($aUser[$i][0])
Return SetError(@error, 0, $pSid)
EndIf
Next
Return 0
#CE
Local $pDomainSid = _SeLookupAccountName(@ComputerName, @ComputerName)
$pSid = _SeCreateWellKnownSid(37 + Abs($iWellKnown), $pDomainSid)
SetError(@error, _SeHeapFree($pDomainSid))
Case $SE_WELLKNOWN_POWER_USERS
$pSid = _SeAllocAndInitSid(5, $SE_SECURITY_BUILTIN_DOMAIN_RID, $SE_DOMAIN_ALIAS_RID_POWER_USERS)
Case $SE_WELLKNOWN_USERS
$pSid = _SeAllocAndInitSid(5, $SE_SECURITY_BUILTIN_DOMAIN_RID, $SE_DOMAIN_ALIAS_RID_USERS)
Case $SE_WELLKNOWN_ADMINS
$pSid = _SeAllocAndInitSid(5, $SE_SECURITY_BUILTIN_DOMAIN_RID, $SE_DOMAIN_ALIAS_RID_ADMINS)
Case $SE_WELLKNOWN_GUESTS
$pSid = _SeAllocAndInitSid(5, $SE_SECURITY_BUILTIN_DOMAIN_RID, $SE_DOMAIN_ALIAS_RID_GUESTS)
Case Else
$pSid = _SeCreateWellKnownSid($iWellKnown)
EndSwitch
Return SetError(@error, 0, $pSid)
EndFunc ;==>_SeGetWellKnownAccountSid
Func _SeGetEffectiveRightsFromAcl($pDacl, $pSid)
#CS
If Not _SeIsValidSid($pSid) Then
Return SetError(@error, 0, 0)
EndIf
#CE
Local $tBuffer, $pBuffer, $iResult
$tBuffer = DllStructCreate($tagSE_TRUSTEE)
$pBuffer = DllStructGetPtr($tBuffer)
DllStructSetData($tBuffer, "Name", $pSid)
DllStructSetData($tBuffer, "TruesteeFrom", $SE_TRUSTEE_IS_SID)
$iResult = DllCall("AdvApi32.dll", "dword", "GetEffectiveRightsFromAcl", _
"ptr", $pDacl, "ptr", $pBuffer, "dword*", 0)
Return SetError($iResult[0], 0, $iResult[3])
EndFunc ;==>_SeGetEffectiveRightsFromAcl
Func _SeLocalFree($pBuffer)
Local $iResult = DllCall("Kernel32.dll", "ptr", "LocalFree", "ptr", $pBuffer)
Return SetError(_SeLastError(), 0, $iResult[0])
EndFunc ;==>_SeLocalFree
Func _SeHeapFree($pBuffer, $iError = @error, $iExtended = @extended)
If $pBuffer < 1 Then Return SetError($iError, $iExtended, 0)
Local $iResult
$iResult = DllCall("Kernel32.dll", "bool", "HeapFree", "handle", $SE_PROCESSHEAP, _
"int", 0, "ptr", $pBuffer)
Return SetError($iError, $iExtended, $iResult[0])
EndFunc ;==>_SeHeapFree
Func _SeProcessHeap()
Local $iResult = DllCall("Kernel32.dll", "handle", "GetProcessHeap")
Return $iResult[0]
EndFunc ;==>_SeProcessHeap
Func _SeHeapAlloc($iBytesToAlloc = 8)
If ($iBytesToAlloc < 1) Then Return 0
Local $iResult
$iResult = DllCall("Kernel32.dll", "ptr", "HeapAlloc", "handle", $SE_PROCESSHEAP, _
"int", 8, "int", $iBytesToAlloc)
Return SetExtended($iBytesToAlloc, $iResult[0])
EndFunc ;==>_SeHeapAlloc
Func _SeLastError()
Local $iResult = DllCall("Kernel32.dll", "long", "GetLastError")
Return $iResult[0]
EndFunc ;==>_SeLastError
Func _SeInitExplicitEntries($aEntry, $iUBound)
If UBound($aEntry, 0) <> 2 Then Return SetError(87, 0, 0)
If UBound($aEntry, 2) <> 4 Then Return SetError(87, 0, 0)
Local $pBuffer, $tBuffer
$pBuffer = _SeHeapAlloc($iUBound * 32)
For $i = 0 To $iUBound - 1
If Not _SeIsValidSid($aEntry[$i][0]) Then
Return SetError(@error, _SeHeapFree($pBuffer), 0)
EndIf
$tBuffer = DllStructCreate($tagSE_EXPLICIT_ACCESS, $pBuffer + ($i * 32))
DllStructSetData($tBuffer, "AccessMask", $aEntry[$i][1])
DllStructSetData($tBuffer, "AccessMode", $aEntry[$i][2])
DllStructSetData($tBuffer, "Inheritance", $aEntry[$i][3])
DllStructSetData($tBuffer, "TrusteeFrom", $SE_TRUSTEE_IS_SID)
DllStructSetData($tBuffer, "Name", $aEntry[$i][0])
$tBuffer = 0
Next
Return $pBuffer
EndFunc ;==>_SeInitExplicitEntries
Func _SeCreateWellKnownSid($iWellKnown, $pDomainSid = 0)
Local $iResult, $pSid = _SeHeapAlloc($SE_MAX_SID_SIZE)
$iResult = DllCall("AdvApi32.dll", "bool", "CreateWellKnownSid", "long", $iWellKnown, _
"ptr", $pDomainSid, "ptr", $pSid, "dword*", $SE_MAX_SID_SIZE)
If ($iResult[0]) Then
Return SetError(0, $iResult[4], $pSid)
Else
Return SetError(_SeLastError(), _SeHeapFree($pSid) * 0, 0)
EndIf
EndFunc ;==>_SeCreateWellKnownSid
Func _SeAllocAndInitSid($iAuthorityId, $iAuth0, $iAuth1 = 0, $iAuth2 = 0, $iAuth3 = 0, _
$iAuth4 = 0, $iAuth5 = 0, $iAuth6 = 0, $iAuth7 = 0)
Local $pAuthority, $iResult
$pAuthority = _SeHeapAlloc(6)
_SeWriteBytes($pAuthority + 5, $iAuthorityId, "byte", 1)
$iResult = DllCall("AdvApi32.dll", "bool", "AllocateAndInitializeSid", "ptr", $pAuthority, _
"byte", @NumParams - 1, "dword", $iAuth0, "dword", $iAuth1, "dword", $iAuth2, _
"dword", $iAuth3, "dword", $iAuth4, "dword", $iAuth5, "dword", $iAuth6, _
"dword", $iAuth7, "ptr*", 0)
Return SetError(_SeLastError(), _SeHeapFree($pAuthority), $iResult[11])
EndFunc ;==>_SeAllocAndInitSid
Func _SeIsValidSid($pSid)
Local $iResult = DllCall("AdvApi32.dll", "bool", "IsValidSid", "ptr", $pSid)
If $iResult[0] Then
Return 1
Else
Return SetError(1337, 0, 0)
EndIf
EndFunc ;==>_SeIsValidSid
Func _SeWriteBytes($pBuffer, $vData, $sType = "dword", $iBytesToWrite = 4)
Local $fResult
If ($sType <> "str") And ($sType <> "wstr") Then $sType &= "*"
$fResult = _SeWriteProcessMemory(-1, $pBuffer, $vData, $iBytesToWrite, $sType)
Return SetError(@error, @extended, $fResult)
EndFunc ;==>_SeWriteBytes
Func _SeWriteProcessMemory($hProcess, $pBaseAddress, $pBuffer, $iSize, $sBufferType = "ptr")
Switch $sBufferType
Case "binary", "binary*"
$sBufferType = "ptr"
Local $tBuffer = DllStructCreate("ubyte Binary[" & $iSize & "]")
DllStructSetData($tBuffer, "Binary", $pBuffer)
$pBuffer = DllStructGetPtr($tBuffer)
Case "str", "char"
$iSize += 1
Case "wstr", "wchar"
$iSize += 2
EndSwitch
Local $iResult
$iResult = DllCall("Kernel32.dll", "bool", "WriteProcessMemory", "handle", $hProcess, _
"ptr", $pBaseAddress, $sBufferType, $pBuffer, "dword", $iSize, _
"dword*", 0)
If ($sBufferType = "binary") Or ($sBufferType = "binary*") Then $tBuffer = 0
If (@error) Then
Return SetError(87, 0, 0)
Else
Return SetError(_SeLastError(), $iResult[5], $iResult[0])
EndIf
EndFunc ;==>_SeWriteProcessMemory