AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[SOLVED] Get a list of _user_ processes only

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
Conquer



Joined: 27 Jun 2006
Posts: 384
Location: Canada

PostPosted: Sun Feb 10, 2008 1:00 am    Post subject: [SOLVED] Get a list of _user_ processes only Reply with quote

EDIT>> Updated script below:
Gets the list of processes running under the current user. Special thanks to the below posters for making/updating the code Smile
Code:
d = `n  ; string separator
s := 4096  ; size of buffers and arrays (4 KB)

Process, Exist  ; sets ErrorLevel to the PID of this running script
; Get the handle of this script with PROCESS_QUERY_INFORMATION (0x0400)
h := DllCall("OpenProcess", "UInt", 0x0400, "Int", false, "UInt", ErrorLevel)
; Open an adjustable access token with this process (TOKEN_ADJUST_PRIVILEGES = 32)
DllCall("Advapi32.dll\OpenProcessToken", "UInt", h, "UInt", 32, "UIntP", t)
VarSetCapacity(ti, 16, 0)  ; structure of privileges
NumPut(1, ti, 0, 4)  ; one entry in the privileges array...
; Retrieves the locally unique identifier of the debug privilege:
DllCall("Advapi32.dll\LookupPrivilegeValueA", "UInt", 0, "Str", "SeDebugPrivilege", "UIntP", luid)
NumPut(luid, ti, 4, 8)
NumPut(2, ti, 12, 4)  ; enable this privilege: SE_PRIVILEGE_ENABLED = 2
; Update the privileges of this process with the new access token:
DllCall("Advapi32.dll\AdjustTokenPrivileges", "UInt", t, "Int", false, "UInt", &ti, "UInt", 0, "UInt", 0, "UInt", 0)
DllCall("CloseHandle", "UInt", h)  ; close this process handle to save memory

MySIDsize:=255, VarSetCapacity(MySID,MySIDsize,0)
sDomainSize:=255, VarSetCapacity(sDomain,sDomainSize,0)
if( !dllCall("advapi32\LookupAccountNameA"   ,"uint",0,"str",A_UserName
   ,"uint",&MySID,"uint*",MySIDsize,"str",sDomain,"uint*",sDomainSize,"uint*",SIDtype))
   msgbox Cannot obtain SID for "%A_UserName%"

hModule := DllCall("LoadLibrary", "Str", "Psapi.dll")  ; increase performance by preloading the libaray
s := VarSetCapacity(a, s)  ; an array that receives the list of process identifiers:
DllCall("Psapi.dll\EnumProcesses", "UInt", &a, "UInt", s, "UIntP", r)
Loop, % r // 4  ; parse array for identifiers as DWORDs (32 bits):
{
   id := NumGet(a, A_Index * 4)
   ; open process with: PROCESS_QUERY_INFORMATION (0x0400) | PROCESS_VM_READ (0x0010) | READ_CONTROL
   h := DllCall("OpenProcess", "UInt", 0x0010 | 0x0400 | 0x20000, "Int", false, "UInt", id)

   bMyProcess=0
   if(0=dllcall("advapi32\GetSecurityInfo","uint",h, "uint",6,"uint",1
      ,"uintP",ppSIDowner,"uint",0,"uint",0,"uint",0,"uintP",ppSecuDsc))
      if ppSecuDsc
      {  bMyProcess:=DllCall("advapi32\EqualSid","uint",&MySID,"uint",ppSIDowner)
         dllCall("LocalFree","uint",ppSecuDsc)
      }

   if bMyProcess
   {
      s := VarSetCapacity(m, 2 << 9) ; for array of modules:
      DllCall("Psapi.dll\EnumProcessModules", "UInt", h, "UInt", &m, "UInt", s, "UIntP", r)
      s := VarSetCapacity(n, 32) ; for module base name:
      e := DllCall("Psapi.dll\GetModuleBaseNameA", "UInt", h, "UInt", m, "Str", n, "Chr", s)
      If n ; if image is not null add to list:
         l = %l%%n%%d%
   }
   DllCall("CloseHandle", "UInt", h) ; close process handle to save memory
}
DllCall("FreeLibrary", "UInt", hModule)  ; unload the library to free memory
; Remove the first and last items in the list (possibly ASCII signitures)
StringMid, l, l, InStr(l, d) + 1, InStr(l, d, false, 0) - 2 - InStr(l, d)
StringReplace, l, l, %d%, %d%, UseErrorLevel  ; gets the number of processes
;Sort, l, C  ; uncomment this line to sort the list alphabetically
MsgBox, 0, %ErrorLevel% Processes, %l%


Thanks again Smile
_________________


Last edited by Conquer on Thu Feb 14, 2008 1:09 am; edited 1 time in total
Back to top
View user's profile Send private message
wOxxOm



Joined: 09 Feb 2006
Posts: 322

PostPosted: Sun Feb 10, 2008 3:48 pm    Post subject: Reply with quote

use a dllcall to "GetSecurityInfo" api function
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Conquer



Joined: 27 Jun 2006
Posts: 384
Location: Canada

PostPosted: Mon Feb 11, 2008 11:55 pm    Post subject: Reply with quote

MSDN: "GetSecurityInfo" wrote:
The GetSecurityInfo function retrieves a copy of the security descriptor for an object specified by a handle.

MSDN: "Security Descriptor" wrote:
A structure and associated data that contains the security information for a securable object. A security descriptor identifies the object's owner and primary group. It can also contain a DACL that controls access to the object, and a SACL that controls the logging of attempts to access the object.

MSDN: "Discretionary Access Control List" wrote:
(DACL) An access control list that is controlled by the owner of an object and that specifies the access particular users or groups can have to the object.

MSDN: "System Access Control List" wrote:
(SACL) An ACL that controls the generation of audit messages for attempts to access a securable object. The ability to get or set an object's SACL is controlled by a privilege typically held only by system administrators.


Okay, so besides expanding my vocabulary, whats the point of the GetSecurityInfo call? Why do I need a copy of the 'Security Descriptor'?

Thanks.
_________________


Last edited by Conquer on Tue Feb 12, 2008 12:00 am; edited 1 time in total
Back to top
View user's profile Send private message
ahklerner



Joined: 26 Jun 2006
Posts: 1317
Location: USA

PostPosted: Mon Feb 11, 2008 11:57 pm    Post subject: Reply with quote

Quote:
A security descriptor identifies the object's owner and primary group

_________________

ʞɔпɟ əɥʇ ʇɐɥʍ
Back to top
View user's profile Send private message
Conquer



Joined: 27 Jun 2006
Posts: 384
Location: Canada

PostPosted: Tue Feb 12, 2008 4:47 am    Post subject: Reply with quote

Alright, I'm still really new to DLL Calls.

What section of the 2nd parameter do I use?

These are the following "object" types:
Code:
SE_UNKNOWN_OBJECT_TYPE

    Unknown object type.
SE_FILE_OBJECT

    Indicates a file or directory. The name string that identifies a file or directory object can be in one of the following formats:

        * A relative path, such as FileName.dat or ..\FileName
        * An absolute path, such as FileName.dat, C:\DirectoryName\FileName.dat, or G:\RemoteDirectoryName\FileName.dat.
        * A UNC name, such as \\ComputerName\ShareName\FileName.dat.
        * A local file system root, such as \\\\.\\C:. Security set on a file system root does not persist when the system is restarted.

SE_SERVICE

    Indicates a Windows service. A service object can be a local service, such as ServiceName, or a remote service, such as \\ComputerName\ServiceName.
SE_PRINTER

    Indicates a printer. A printer object can be a local printer, such as PrinterName, or a remote printer, such as \\ComputerName\PrinterName.
SE_REGISTRY_KEY

    Indicates a registry key. A registry key object can be in the local registry, such as CLASSES_ROOT\SomePath or in a remote registry, such as \\ComputerName\CLASSES_ROOT\SomePath.

    The names of registry keys must use the following literal strings to identify the predefined registry keys: "CLASSES_ROOT", "CURRENT_USER", "MACHINE", and "USERS".
SE_LMSHARE

    Indicates a network share. A share object can be local, such as ShareName, or remote, such as \\ComputerName\ShareName.
SE_KERNEL_OBJECT

    Indicates a local kernel object.

    The GetSecurityInfo and SetSecurityInfo functions support all types of kernel objects. The GetNamedSecurityInfo and SetNamedSecurityInfo functions work only with the following kernel objects: semaphore, event, mutex, waitable timer, and file mapping.
SE_WINDOW_OBJECT

    Indicates a window station or desktop object on the local computer. You cannot use GetNamedSecurityInfo and SetNamedSecurityInfo with these objects because the names of window stations or desktops are not unique.
SE_DS_OBJECT

    Indicates a directory service object or a property set or property of a directory service object. The name string for a directory service object must be in X.500 form, for example:

    CN=SomeObject,OU=ou2,OU=ou1,DC=DomainName,DC=CompanyName,DC=com,O=internet
SE_DS_OBJECT_ALL

    Indicates a directory service object and all of its property sets and properties.
SE_PROVIDER_DEFINED_OBJECT

    Indicates a provider-defined object.
SE_WMIGUID_OBJECT

    Indicates a WMI object.
SE_REGISTRY_WOW64_32KEY

    Indicates an object for a registry entry under WOW64.


And I might be wrong, but do I use "OWNER_SECURITY_INFORMATION" for the 3rd parameter?
MSDN: "OWNER_SECURITY_INFORMATION wrote:
The owner identifier of the object is being referenced.

http://msdn2.microsoft.com/en-us/library/aa379573

Thanks.
_________________
Back to top
View user's profile Send private message
wOxxOm



Joined: 09 Feb 2006
Posts: 322

PostPosted: Tue Feb 12, 2008 2:20 pm    Post subject: Reply with quote

as always with api dllcalls just google for an example in any programming language you easily understand, for example visual basic Very Happy then transcode the call and analysis into ahk
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Conquer



Joined: 27 Jun 2006
Posts: 384
Location: Canada

PostPosted: Wed Feb 13, 2008 3:31 am    Post subject: Reply with quote

Good suggestion, but I don't know any programming languages. Embarassed Crying or Very sad
_________________
Back to top
View user's profile Send private message
wOxxOm



Joined: 09 Feb 2006
Posts: 322

PostPosted: Wed Feb 13, 2008 4:23 am    Post subject: Reply with quote

that was some fun, here it is:
Code:
d = `n ; string separator
s := VarSetCapacity(a, 2 << 9) ; 1KiB for array

MySIDsize:=255, VarSetCapacity(MySID,MySIDsize,0)
sDomainSize:=255, VarSetCapacity(sDomain,sDomainSize,0)
if( !dllCall("advapi32\LookupAccountNameA"   ,"uint",0,"str",A_UserName
   ,"uint",&MySID,"uint*",MySIDsize,"str",sDomain,"uint*",sDomainSize,"uint*",SIDtype))
   msgbox Cannot obtain SID for "%A_UserName%"

hModule := DllCall("LoadLibrary", "Str", "Psapi.dll") ; for speed
; get array of processes and parse identifiers as DWORDs:
DllCall("Psapi.dll\EnumProcesses", "UInt", &a, "UInt", s, "UIntP", r)
Loop, % r // 4 {
   id := NumGet(a, A_Index * 4)
   ; open process with: PROCESS_QUERY_INFORMATION (0x0400) | PROCESS_VM_READ (0x0010) | READ_CONTROL
   h := DllCall("OpenProcess", "UInt", 0x0010 | 0x0400 | 0x20000, "Int", false, "UInt", id)

   bMyProcess=0
   if(0=dllcall("advapi32\GetSecurityInfo","uint",h, "uint",6,"uint",1
      ,"uintP",ppSIDowner,"uint",0,"uint",0,"uint",0,"uintP",ppSecuDsc))
      if ppSecuDsc
      {  bMyProcess:=DllCall("advapi32\EqualSid","uint",&MySID,"uint",ppSIDowner)
         dllCall("LocalFree","uint",ppSecuDsc)
      }

   if bMyProcess
   {
      s := VarSetCapacity(m, 2 << 9) ; for array of modules:
      DllCall("Psapi.dll\EnumProcessModules", "UInt", h, "UInt", &m, "UInt", s, "UIntP", r)
      s := VarSetCapacity(n, 32) ; for module base name:
      e := DllCall("Psapi.dll\GetModuleBaseNameA", "UInt", h, "UInt", m, "Str", n, "Chr", s)
      If n ; if image is not null add to list:
         l = %l%%n%%d%
   }
   DllCall("CloseHandle", "UInt", h) ; close process handle to save memory
}
DllCall("FreeLibrary", "UInt", hModule) ; free memory
StringTrimLeft, l, l, InStr(l, d) ; remove first item (ASCII sig?)
Msgbox, %l%
Back to top
View user's profile Send private message Send e-mail Visit poster's website
SKAN



Joined: 26 Dec 2005
Posts: 7185

PostPosted: Wed Feb 13, 2008 8:25 am    Post subject: Re: Get a list of _user_ processes only Reply with quote

Conquer wrote:
I'm using this script by Titan:


That is outdated code
The correct version of Titan's code is this and has been included in AHK Doc under Process command.

@wOxxOm

That is fantastic code. Thanks.

However, with initial testing I find some process missing like taskmgr.exe, wscntfy.exe.
Has it got something to do with Debug Privilege ?

Smile
Back to top
View user's profile Send private message
wOxxOm



Joined: 09 Feb 2006
Posts: 322

PostPosted: Wed Feb 13, 2008 3:38 pm    Post subject: Reply with quote

yeah, dig MSDN, probably SE_DEBUG_PRIVILEGE or something else is needed somewhere Very Happy
Back to top
View user's profile Send private message Send e-mail Visit poster's website
SKAN



Joined: 26 Dec 2005
Posts: 7185

PostPosted: Wed Feb 13, 2008 5:16 pm    Post subject: Reply with quote

wOxxOm wrote:
yeah, dig MSDN


No,.. er .. I had pointed out that you should have adapted from Titan's corrected code posted at:
http://www.autohotkey.com/forum/viewtopic.php?p=81564#81564
instead of the code posted by Conquer.

I just inserted/replaced some code with yours ( in Red ) and you have to tell me if it is right:

Code:
d = `n  ; string separator
s := 4096  ; size of buffers and arrays (4 KB)

Process, Exist  ; sets ErrorLevel to the PID of this running script
; Get the handle of this script with PROCESS_QUERY_INFORMATION (0x0400)
h := DllCall("OpenProcess", "UInt", 0x0400, "Int", false, "UInt", ErrorLevel)
; Open an adjustable access token with this process (TOKEN_ADJUST_PRIVILEGES = 32)
DllCall("Advapi32.dll\OpenProcessToken", "UInt", h, "UInt", 32, "UIntP", t)
VarSetCapacity(ti, 16, 0)  ; structure of privileges
NumPut(1, ti, 0, 4)  ; one entry in the privileges array...
; Retrieves the locally unique identifier of the debug privilege:
DllCall("Advapi32.dll\LookupPrivilegeValueA", "UInt", 0, "Str", "SeDebugPrivilege", "UIntP", luid)
NumPut(luid, ti, 4, 8)
NumPut(2, ti, 12, 4)  ; enable this privilege: SE_PRIVILEGE_ENABLED = 2
; Update the privileges of this process with the new access token:
DllCall("Advapi32.dll\AdjustTokenPrivileges", "UInt", t, "Int", false, "UInt", &ti, "UInt", 0, "UInt", 0, "UInt", 0)
DllCall("CloseHandle", "UInt", h)  ; close this process handle to save memory

MySIDsize:=255, VarSetCapacity(MySID,MySIDsize,0)
sDomainSize:=255, VarSetCapacity(sDomain,sDomainSize,0)
if( !dllCall("advapi32\LookupAccountNameA"   ,"uint",0,"str",A_UserName
   ,"uint",&MySID,"uint*",MySIDsize,"str",sDomain,"uint*",sDomainSize,"uint*",SIDtype))
   msgbox Cannot obtain SID for "%A_UserName%"


hModule := DllCall("LoadLibrary", "Str", "Psapi.dll")  ; increase performance by preloading the libaray
s := VarSetCapacity(a, s)  ; an array that receives the list of process identifiers:
DllCall("Psapi.dll\EnumProcesses", "UInt", &a, "UInt", s, "UIntP", r)
Loop, % r // 4  ; parse array for identifiers as DWORDs (32 bits):
{
   id := NumGet(a, A_Index * 4)
   ; open process with: PROCESS_QUERY_INFORMATION (0x0400) | PROCESS_VM_READ (0x0010) | READ_CONTROL
   h := DllCall("OpenProcess", "UInt", 0x0010 | 0x0400 | 0x20000, "Int", false, "UInt", id)

   bMyProcess=0
   if(0=dllcall("advapi32\GetSecurityInfo","uint",h, "uint",6,"uint",1
      ,"uintP",ppSIDowner,"uint",0,"uint",0,"uint",0,"uintP",ppSecuDsc))
      if ppSecuDsc
      {  bMyProcess:=DllCall("advapi32\EqualSid","uint",&MySID,"uint",ppSIDowner)
         dllCall("LocalFree","uint",ppSecuDsc)
      }

   if bMyProcess
   {
      s := VarSetCapacity(m, 2 << 9) ; for array of modules:
      DllCall("Psapi.dll\EnumProcessModules", "UInt", h, "UInt", &m, "UInt", s, "UIntP", r)
      s := VarSetCapacity(n, 32) ; for module base name:
      e := DllCall("Psapi.dll\GetModuleBaseNameA", "UInt", h, "UInt", m, "Str", n, "Chr", s)
      If n ; if image is not null add to list:
         l = %l%%n%%d%
   }

   DllCall("CloseHandle", "UInt", h) ; close process handle to save memory
}
DllCall("FreeLibrary", "UInt", hModule)  ; unload the library to free memory
; Remove the first and last items in the list (possibly ASCII signitures)
StringMid, l, l, InStr(l, d) + 1, InStr(l, d, false, 0) - 2 - InStr(l, d)
StringReplace, l, l, %d%, %d%, UseErrorLevel  ; gets the number of processes
;Sort, l, C  ; uncomment this line to sort the list alphabetically
MsgBox, 0, %ErrorLevel% Processes, %l%


Rolling Eyes
Back to top
View user's profile Send private message
wOxxOm



Joined: 09 Feb 2006
Posts: 322

PostPosted: Wed Feb 13, 2008 5:22 pm    Post subject: Reply with quote

great!
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Conquer



Joined: 27 Jun 2006
Posts: 384
Location: Canada

PostPosted: Thu Feb 14, 2008 12:53 am    Post subject: Reply with quote

Wow, thanks so much w0xx0m! And thanks SKAN! You're both heroes Smile
_________________
Back to top
View user's profile Send private message
maraskan_user



Joined: 20 Jun 2008
Posts: 17

PostPosted: Fri Jun 20, 2008 12:56 pm    Post subject: Reply with quote

I was staring at this code for a while but got no wiser. Totally opaque to me. @_@ Could somebody explain how I'd have to change it to simply find out whether a single specified process has admin rights or not? Like, get the ahd_id of a process, check if it's admin or not and save the return value in a bool variable.

Greetings,
Gernot
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group