AutoHotkey Community

It is currently May 26th, 2012, 12:01 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 14 posts ] 
Author Message
PostPosted: February 10th, 2008, 1:00 am 
Offline

Joined: June 27th, 2006, 2:38 pm
Posts: 385
Location: Canada
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 :)
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 :)


Last edited by Conquer on February 14th, 2008, 1:09 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 10th, 2008, 3:48 pm 
Offline

Joined: February 9th, 2006, 8:36 pm
Posts: 338
use a dllcall to "GetSecurityInfo" api function


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 11th, 2008, 11:55 pm 
Offline

Joined: June 27th, 2006, 2:38 pm
Posts: 385
Location: Canada
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 February 12th, 2008, 12:00 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 11th, 2008, 11:57 pm 
Offline

Joined: June 26th, 2006, 6:14 pm
Posts: 1379
Location: USA
Quote:
A security descriptor identifies the object's owner and primary group

_________________
Image
ʞɔпɟ əɥʇ ʇɐɥʍ


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2008, 4:47 am 
Offline

Joined: June 27th, 2006, 2:38 pm
Posts: 385
Location: Canada
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2008, 2:20 pm 
Offline

Joined: February 9th, 2006, 8:36 pm
Posts: 338
as always with api dllcalls just google for an example in any programming language you easily understand, for example visual basic :-D then transcode the call and analysis into ahk


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 13th, 2008, 3:31 am 
Offline

Joined: June 27th, 2006, 2:38 pm
Posts: 385
Location: Canada
Good suggestion, but I don't know any programming languages. :oops: :cry:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 13th, 2008, 4:23 am 
Offline

Joined: February 9th, 2006, 8:36 pm
Posts: 338
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%


Report this post
Top
 Profile  
Reply with quote  
PostPosted: February 13th, 2008, 8:25 am 
Offline
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8775
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 ?

:)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 13th, 2008, 3:38 pm 
Offline

Joined: February 9th, 2006, 8:36 pm
Posts: 338
yeah, dig MSDN, probably SE_DEBUG_PRIVILEGE or something else is needed somewhere :-D


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 13th, 2008, 5:16 pm 
Offline
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8775
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/viewtop ... 1564#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%


:roll:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 13th, 2008, 5:22 pm 
Offline

Joined: February 9th, 2006, 8:36 pm
Posts: 338
great!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 14th, 2008, 12:53 am 
Offline

Joined: June 27th, 2006, 2:38 pm
Posts: 385
Location: Canada
Wow, thanks so much w0xx0m! And thanks SKAN! You're both heroes :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 20th, 2008, 12:56 pm 
Offline

Joined: June 20th, 2008, 12:40 pm
Posts: 47
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


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: dra, Google Feedfetcher, LazyMan, Leef_me, tank, Tegno and 14 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group