Page 1 of 1

Get Process Owner, & Permissions [Win_Func]

Posted: Wed Aug 24, 2016 4:39 am
by Thunder93

Code: Select all

#OWNER_SECURITY_INFORMATION = $1
#DACL_SECURITY_INFORMATION  = $4

Enumeration ;ACL_INFORMATION_CLASS
  #AclRevisionInformation = 1
  #AclSizeInformation
EndEnumeration

Enumeration ; SID_NAME_USE
  #SidTypeUser = 1
  #SidTypeGroup
  #SidTypeDomain
  #SidTypeAlias
  #SidTypeWellKnownGroup
  #SidTypeDeletedAccount
  #SidTypeInvalid
  #SidTypeUnknown
  #SidTypeComputer
  #SidTypeLabel
EndEnumeration

Enumeration ; SE_OBJECT_TYPE
  #SE_UNKNOWN_OBJECT_TYPE
  #SE_FILE_OBJECT
  #SE_SERVICE
  #SE_PRINTER
  #SE_REGISTRY_KEY
  #SE_LMSHARE
  #SE_KERNEL_OBJECT
  #SE_WINDOW_OBJECT
  #SE_DS_OBJECT
  #SE_DS_OBJECT_ALL
  #SE_PROVIDER_DEFINED_OBJECT
EndEnumeration

Structure SID
  Revision.b
  SubAuthorityCount.b
  *IdentifierAuthority.SID_IDENTIFIER_AUTHORITY
  SubAuthority.l[#ANYSIZE_ARRAY]
EndStructure


#TH32CS_SNAPPROCESS = $2

Procedure SearchPID(Name.s)
  Protected Process.PROCESSENTRY32, Snapshot.i, ProcCount.l, ProcName$
  Process\dwSize = SizeOf(PROCESSENTRY32)
  Snapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS, 0)
  If Snapshot
    ProcCount = Process32First_(Snapshot, Process)
    While ProcCount
      ProcName$ = UCase(PeekS(@Process\szExeFile, #MAX_PATH))
      If UCase(Name) = GetFilePart(ProcName$)
        ProcedureReturn Process\th32ProcessID
      EndIf
      ProcCount = Process32Next_(Snapshot, Process)
    Wend
    CloseHandle_(Snapshot)
  EndIf
  ProcedureReturn 0
EndProcedure

Procedure.b EnumProcPermissions(pDacl)
  Protected *pAce.ACCESS_ALLOWED_ACE, aclSize.ACL_SIZE_INFORMATION
  Protected.i retfunc, acl_ACECount, dwAccountNameSize, dwDomainNameSize, SID_NAME_USE
  Protected.s szAccountName, szDomainName


  If GetAclInformation_(pDacl, @aclSize, SizeOf(aclSize), #AclSizeInformation)

    acl_ACECount = aclSize\AceCount - 1
    If Not acl_ACECount : ProcedureReturn 0 : EndIf

    Repeat
      GetAce_(pDacl, acl_ACECount, @*pAce)

      bRtnBool = LookupAccountSid_(#Null, @*pAce\SidStart, 0, @dwAccountNameSize, 0, @dwDomainNameSize, @SID_NAME_USE)
      szAccountName = Space(dwAccountNameSize)
      szDomainName = Space(dwDomainNameSize)
      If LookupAccountSid_(#Null, @*pAce\SidStart, @szAccountName, @dwAccountNameSize, @szDomainName, @dwDomainNameSize, @SID_NAME_USE)

        If  *pAce\Mask = #FILE_ALL_ACCESS
          AccessMask$ = "( Full Access ) - "
        ElseIf *pAce\Mask = 268435456
          AccessMask$ = "( Full Access (Sub Only) ) - "
        EndIf


        ;Standard Access Rights
        If *pAce\Mask & #STANDARD_RIGHTS_ALL = #STANDARD_RIGHTS_ALL
          StandardAccess$ + "( STANDARD_RIGHTS_ALL ) | "
        EndIf
        If *pAce\Mask & #DELETE
          StandardAccess$ + "DELETE - "
        EndIf
        If *pAce\Mask & #READ_CONTROL
          StandardAccess$ + "READ_CONTROL - "
        EndIf
        If *pAce\Mask & #SYNCHRONIZE
          StandardAccess$ + "SYNCHRONIZE - "
        EndIf
        If *pAce\Mask & #WRITE_OWNER
          StandardAccess$ + "WRITE_OWNER - "
        EndIf

        StandardAccess$ = RemoveString(StandardAccess$, " - ", #PB_String_NoCase, Len(StandardAccess$) - 3, 1)


        If *pAce\Mask & #FILE_ALL_ACCESS = #FILE_ALL_ACCESS
          GenericAccess$ + " (Full Access) | "
        EndIf
        If *pAce\Mask & #FILE_GENERIC_READ = #FILE_GENERIC_READ
          GenericAccess$ + "FILE_GENERIC_READ - "
        EndIf
        If *pAce\Mask & #FILE_GENERIC_WRITE = #FILE_GENERIC_WRITE
          GenericAccess$ + "FILE_GENERIC_WRITE - "
        EndIf
        If *pAce\Mask & #FILE_GENERIC_EXECUTE = #FILE_GENERIC_EXECUTE
          GenericAccess$ + "FILE_GENERIC_EXECUTE - "
        EndIf

        GenericAccess$ = RemoveString(GenericAccess$, " - ", #PB_String_NoCase, Len(GenericAccess$) - 3, 1)


        ;Specific Access Rights
        If *pAce\Mask & #FILE_READ_DATA
          SpecificAccess$ + "READ / FILE_LIST_DIRECTORY - "
        EndIf
        If *pAce\Mask & #FILE_WRITE_DATA
          SpecificAccess$ + "WRITE / FILE_ADD_FILE - "
        EndIf
        If *pAce\Mask & #FILE_APPEND_DATA
          SpecificAccess$ + "FILE_APPEND_DATA / FILE_ADD_SUBDIRECTORY / FILE_CREATE_PIPE_INSTANCE - "
        EndIf
        If *pAce\Mask & #FILE_READ_EA
          SpecificAccess$ + "FILE_READ_EA - "
        EndIf
        If *pAce\Mask & #FILE_WRITE_EA
          SpecificAccess$ + "FILE_WRITE_EA - "
        EndIf
        If *pAce\Mask & #FILE_READ_ATTRIBUTES
          SpecificAccess$ + "FILE_READ_ATTRIBUTES - "
        EndIf
        If *pAce\Mask & #FILE_WRITE_ATTRIBUTES
          SpecificAccess$ + "FILE_WRITE_ATTRIBUTES - "
        EndIf
        If *pAce\Mask & #FILE_EXECUTE
          SpecificAccess$ + "FILE_EXECUTE / FILE_TRAVERSE - "
        EndIf
        If *pAce\Mask & #FILE_DELETE_CHILD
          SpecificAccess$ + "FILE_DELETE_CHILD - "
        EndIf

        If *pAce\Mask & #SPECIFIC_RIGHTS_ALL = #SPECIFIC_RIGHTS_ALL
          SpecificAccess$ + "SPECIFIC_RIGHTS_ALL"
        EndIf

        SpecificAccess$ = RemoveString(SpecificAccess$, " - ", #PB_String_NoCase, Len(SpecificAccess$) - 3, 1)

        Select *pAce\Header\AceType
          Case #ACCESS_ALLOWED_ACE_TYPE
            AceType$ = "ACCESS_ALLOWED_ACE_TYPE"
          Case #ACCESS_DENIED_ACE_TYPE
            AceType$ = "ACCESS_DENIED_ACE_TYPE"
          Case #SYSTEM_AUDIT_ACE_TYPE
            AceType$ = "SYSTEM_AUDIT_ACE_TYPE"
          Default
            AceType$ = "Unknown ACE type"
        EndSelect


        Debug "Account = " + szAccountName + ", Domain = " + szDomainName + ", Generic Access Rights = " + GenericAccess$
        Debug "Account = " + szAccountName + ", Domain = " + szDomainName + ", Standard Access Rights = " + StandardAccess$
        Debug "Account = " + szAccountName + ", Domain = " + szDomainName + ", Specific Access Rights = " + AccessMask$ + SpecificAccess$
        Debug "Account = " + szAccountName + ", Domain = " + szDomainName + ", ACE Type = " + AceType$
        Debug ""

        GenericAccess$=""
        StandardAccess$=""
        SpecificAccess$=""
        AccessMask$=""
      EndIf
      dwDomainNameSize = 0

      acl_ACECount - 1
    Until acl_ACECount < 0
  EndIf
EndProcedure

Procedure.b GetObjectOwner(PID.l, ProcName.s, EnumProcPermissions.l = 0)
  Protected *pSidOwner.SID, *pSD.SECURITY_DESCRIPTOR
  Protected.i dwRtnCode, bRtnBool, eUse
  Protected.s szAccountName, szDomainName
  Protected.i dwAcctName, dwDomainName

  If PID = #INVALID_HANDLE_VALUE
    Debug "Invalid PID"
    ProcedureReturn 0
  EndIf

  Object = OpenProcess_(#READ_CONTROL, #False, PID)

  If Not Object
    Debug GetLastError_()
    Debug "Invalid Object handle!"
    ProcedureReturn 0
  EndIf

  If OpenProcessToken_(GetCurrentProcess_(), #TOKEN_QUERY | #TOKEN_ADJUST_PRIVILEGES, @htok) <= 0
    Debug "OpenProcessToken failed"
    ProcedureReturn 0
  EndIf

  ; Allocate memory for the security descriptor structure
  *pSD = AllocateMemory(SizeOf(SECURITY_DESCRIPTOR))
  If *pSD = 0
    Debug "Can't allocate memory for the SECURITY_DESCRIPTOR structure"
    ProcedureReturn 0
  EndIf

  ; Get the owner SID of the object
  dwRtnCode = GetSecurityInfo_(Object, #SE_KERNEL_OBJECT, #DACL_SECURITY_INFORMATION|#OWNER_SECURITY_INFORMATION, @*pSidOWner, #Null, @pDacl.i, #Null, @*pSD)

  ; Check GetLastError for GetSecurityInfo error condition
  If dwRtnCode <> #ERROR_SUCCESS
    Debug "GetSecurityInfo error = " + Str(dwRtnCode)
    ProcedureReturn 0
  EndIf

  ; First call to LookupAccoundSid to get the buffer sizes
  bRtnBool = LookupAccountSid_(#Null, *pSidOwner, szAccountName, @dwAcctName, szDomainName, @dwDomainName, @eUse)

  ; Reallocate memory for the buffers
  szAccountName = Space(dwAcctName)
  szDomainName = Space(dwDomainName)

  ; Second call to LookupAccountSid to get the account name
  bRtnBool = LookupAccountSid_(#Null, *pSidOwner, szAccountName, @dwAcctName, szDomainName, @dwDomainName, @eUse)

  Debug "Object Owner for Process [ "+ProcName+" ]:"+#LF$+"  "+szAccountName
  Debug ""

  If EnumProcPermissions
    Debug "Enumerate Process Permissions:"
    EnumProcPermissions(pDacl)
  EndIf

  ; Close the process handle
  CloseHandle_(Object)
  ProcedureReturn 1
EndProcedure

Procedure EnableDebugPrivNT()
  Protected DebugValue.LUID, *tkp.TOKEN_PRIVILEGES

  ; Retrieve a handle of the access token
  If Not OpenProcessToken_(GetCurrentProcess_(), #TOKEN_ADJUST_PRIVILEGES|#TOKEN_QUERY, @hToken)
    ProcedureReturn 0
  EndIf

  ; Enable the SE_DEBUG_NAME privilege
  If Not LookupPrivilegeValue_("", #SE_DEBUG_NAME, @DebugValue)
    ProcedureReturn 0
  EndIf

  *tkp = AllocateMemory( SizeOf(TOKEN_PRIVILEGES) + (1 * SizeOf(LUID_AND_ATTRIBUTES)) )
  If Not *tkp : ProcedureReturn 0 : EndIf

  *tkp\PrivilegeCount = 1
  *tkp\Privileges\Luid\HighPart = DebugValue\HighPart
  *tkp\Privileges\Luid\LowPart = DebugValue\LowPart
  *tkp\Privileges\Attributes = #SE_PRIVILEGE_ENABLED

  If Not AdjustTokenPrivileges_(hToken, #False, @*tkp, SizeOf(TOKEN_PRIVILEGES), @PreviousState.TOKEN_PRIVILEGES, @ReturnLength)
    If GetLastError_() = #ERROR_SUCCESS
      ProcedureReturn 0
    EndIf
  EndIf

  FreeMemory(*tkp)

  ProcedureReturn 1
EndProcedure


#EnumProcPermissions = 1

If EnableDebugPrivNT()
  Debug "Privilege loaded..."+#CRLF$

  Debug "Search processes list for explorer.exe PID number..."
  PID1 = SearchPID("explorer.exe")
  If PID1
    Debug "  PID #: "+Str(PID1)+#CRLF$
    GetObjectOwner(PID1, "explorer.exe", #EnumProcPermissions)
  EndIf

Else
  Debug "Privilege issue."
EndIf

When compiled, you'll see basically the following;

Code: Select all

Privilege loaded...

Search processes list for explorer.exe PID number...
  PID #: 4020

Object Owner for Process [ explorer.exe ]:
  JohnDoe

Enumerate Process Permissions:
Account = LogonSessionId_0_270100, Domain = NT AUTHORITY, Generic Access Rights = 
Account = LogonSessionId_0_270100, Domain = NT AUTHORITY, Standard Access Rights = READ_CONTROL - SYNCHRONIZE
Account = LogonSessionId_0_270100, Domain = NT AUTHORITY, Specific Access Rights = READ / FILE_LIST_DIRECTORY - FILE_WRITE_EA
Account = LogonSessionId_0_270100, Domain = NT AUTHORITY, ACE Type = ACCESS_ALLOWED_ACE_TYPE

Account = SYSTEM, Domain = NT AUTHORITY, Generic Access Rights =  (Full Access) | FILE_GENERIC_READ - FILE_GENERIC_WRITE - FILE_GENERIC_EXECUTE
Account = SYSTEM, Domain = NT AUTHORITY, Standard Access Rights = ( STANDARD_RIGHTS_ALL ) | DELETE - READ_CONTROL - SYNCHRONIZE - WRITE_OWNER
Account = SYSTEM, Domain = NT AUTHORITY, Specific Access Rights = READ / FILE_LIST_DIRECTORY - WRITE / FILE_ADD_FILE - FILE_APPEND_DATA / FILE_ADD_SUBDIRECTORY / FILE_CREATE_PIPE_INSTANCE - FILE_READ_EA - FILE_WRITE_EA - FILE_READ_ATTRIBUTES - FILE_WRITE_ATTRIBUTES - FILE_EXECUTE / FILE_TRAVERSE - FILE_DELETE_CHILD - SPECIFIC_RIGHTS_ALL
Account = SYSTEM, Domain = NT AUTHORITY, ACE Type = ACCESS_ALLOWED_ACE_TYPE

Account = JohnDoe, Domain = DESKTOP-5BE1L1R, Generic Access Rights =  (Full Access) | FILE_GENERIC_READ - FILE_GENERIC_WRITE - FILE_GENERIC_EXECUTE
Account = JohnDoe, Domain = DESKTOP-5BE1L1R, Standard Access Rights = ( STANDARD_RIGHTS_ALL ) | DELETE - READ_CONTROL - SYNCHRONIZE - WRITE_OWNER
Account = JohnDoe, Domain = DESKTOP-5BE1L1R, Specific Access Rights = READ / FILE_LIST_DIRECTORY - WRITE / FILE_ADD_FILE - FILE_APPEND_DATA / FILE_ADD_SUBDIRECTORY / FILE_CREATE_PIPE_INSTANCE - FILE_READ_EA - FILE_WRITE_EA - FILE_READ_ATTRIBUTES - FILE_WRITE_ATTRIBUTES - FILE_EXECUTE / FILE_TRAVERSE - FILE_DELETE_CHILD - SPECIFIC_RIGHTS_ALL
Account = JohnDoe, Domain = DESKTOP-5BE1L1R, ACE Type = ACCESS_ALLOWED_ACE_TYPE

... I'm not doing no more! :wink:

Re: Get Process Owner, & Permissions [Win_Func]

Posted: Wed Aug 24, 2016 7:11 pm
by fryquez
Works nice here :)

However in SearchPID() Snapshot should be an integer no a long.

Also what's with these Procedure.b?

Re: Get Process Owner, & Permissions [Win_Func]

Posted: Thu Aug 25, 2016 1:28 am
by Thunder93
Thanks!

Your absolutely right, overlooked. Good catch!

I don't need Integer procedurereturns when -1, 0, 1 typically is what I'm expecting. :lol:

Re: Get Process Owner, & Permissions [Win_Func]

Posted: Thu Aug 25, 2016 7:58 am
by fryquez
Return type is always an integer.
Using .b will add an extra code instruction to make sure the integer is smaller than 256.

Re: Get Process Owner, & Permissions [Win_Func]

Posted: Thu Aug 25, 2016 1:03 pm
by Thunder93
Procedurereturns always integer. I actually didn't know this. Thanks for pointing this out.

On the other end, when storing the results of procedurereturns into smaller variables. We are using less memory right? or no?

Re: Get Process Owner, & Permissions [Win_Func]

Posted: Thu Aug 25, 2016 1:31 pm
by ts-soft
Thunder93 wrote:On the other end, when storing the results of procedurereturns into smaller variables. We are using less memory right? or no?
No!

Re: Get Process Owner, & Permissions [Win_Func]

Posted: Thu Aug 25, 2016 1:31 pm
by Keya
Procedure.b

Code: Select all

Procedure.b ByteProc()
  Protected bval.b = 3
  ProcedureReturn bval
EndProcedure
Define bval.b = ByteProc()
=

Code: Select all

00401040  |.  E8 2C000000         call 00401071
	00401071   $  31C0                xor eax, eax
	00401073   .  50                  push eax
	00401074   .  C60424 03           mov byte ptr [esp], 3
	00401078   .  0FBE0424            movsx eax, byte ptr [esp]
	0040107C   .  0FBEC0              movsx eax, al
	0040107F   .  EB 02               jmp short 00401083
	00401081   .  31C0                xor eax, eax
	00401083   >  83C4 04             add esp, 4
	00401086   .  C3                  retn
00401045  |.  A2 E8304000         mov byte ptr [4030E8], al
Procedure.i (32bit long - x86)

Code: Select all

Procedure.i IntProc()
  Protected ival.i = 3
  ProcedureReturn ival
EndProcedure
Define ival.i = IntProc()
=

Code: Select all

0040104B  |.  E8 37000000         call 00401087
	00401087   $  31C0                xor eax, eax
	00401089   .  50                  push eax
	0040108A   .  C70424 03000000     mov dword ptr [esp], 3
	00401091   .  8B0424              mov eax, dword ptr [esp]
	00401094   .  EB 02               jmp short 00401098
	00401096   .  31C0                xor eax, eax
	00401098   >  83C4 04             add esp, 4
	0040109B   .  C3                  retn
00401050  |.  A3 E0304000         mov dword ptr [4030E0], eax

Re: Get Process Owner, & Permissions [Win_Func]

Posted: Thu Aug 25, 2016 11:37 pm
by Thunder93
Defining variables of different sizes don't reserve memory portions based on variables types used?

Instance.a = 0

... no different then;

Instance.i = 0

this what you saying?

ts-soft wrote:
Thunder93 wrote:On the other end, when storing the results of procedurereturns into smaller variables. We are using less memory right? or no?
No!