Jump to content

Recommended Posts

Posted
3 hours ago, Jos said:

This is a change to the func to close all $hToken handles properly:

#RequireAdmin
#include <WinAPIProc.au3>
ConsoleWrite("ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
Local $aProcessList = ProcessList()
For $i = 1 To $aProcessList[0][0]
    _WinAPI_IsElevated_pid($aProcessList[$i][1])
;~     ConsoleWrite($aProcessList[$i][0] & ' = ' & _WinAPI_IsElevated_pid($aProcessList[$i][1]) & '   >Error code: ' & @error & @CRLF) ;### Debug Console
Next
ConsoleWrite("ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
For $i = 1 To $aProcessList[0][0]
    _WinAPI_IsElevated_pid($aProcessList[$i][1])
;~     ConsoleWrite($aProcessList[$i][0] & ' = ' & _WinAPI_IsElevated_pid($aProcessList[$i][1]) & '   >Error code: ' & @error & @CRLF) ;### Debug Console
Next
ConsoleWrite("ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)

.....

...that is my "golden test". Been looking around and this one goes about the token differently, I think.

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted

Ok that all made me curious.  I tested my own version of it :

#RequireAdmin ; needed to access services

; elevated - another process

#include <WinAPIProc.au3>
#include <ProcessConstants.au3>
#include <Constants.au3>
#include <Array.au3>

Example()

Func Example()
  ConsoleWrite("Start : " & _WinAPI_GetProcessHandleCount() & @CRLF)

  Local $aList = ProcessList(), $t1, $t2, $iCount = _WinAPI_GetProcessHandleCount()
  For $i = 3 To $aList[0][0]
    $t1 = IsProcessElevated($aList[$i][1])
    If @error Then ConsoleWrite("error c " & $aList[$i][0] & "/" & @error & @CRLF)
    If $iCount <> _WinAPI_GetProcessHandleCount() Then
      $iCount = _WinAPI_GetProcessHandleCount()
      ConsoleWrite($iCount & "/" & $aList[$i][0] & "/" & $aList[$i][1] & @CRLF)
    EndIf
  Next
  ConsoleWrite("End : " & _WinAPI_GetProcessHandleCount() & @CRLF)
EndFunc   ;==>Example

Func IsProcessElevated($iPID)
  Local $aRet, $iError = 0
  Local $hProcess = _WinAPI_OpenProcess($PROCESS_QUERY_LIMITED_INFORMATION, False, $iPID, True)
  If Not $hProcess Then Return SetError(1, 0, False)
  Local $hToken = _WinAPI_OpenProcessToken($TOKEN_QUERY, $hProcess)
  If Not $hToken Then
    $iError = 2
  Else
    $aRet = DllCall('advapi32.dll', 'bool', 'GetTokenInformation', 'handle', $hToken, 'uint', 20, 'uint*', 0, 'dword', 4, 'dword*', 0)         ; TOKEN_ELEVATION
    If @error Or Not $aRet[0] Then $iError = 3
  EndIf
  _WinAPI_CloseHandle($hToken)
  _WinAPI_CloseHandle($hProcess)
  If $iError Then Return SetError($iError, 0, False)
  Return $aRet[3] = 1
EndFunc   ;==>IsProcessElevated

And in my case, only a single process creates a one shot 7 handles.  After digging, it has to do with one API LookupPrivilegeValueW that does it.  Nothing I can do about it, that seems to be a Windows "issue".

 

Posted (edited)

I think I've got it

#RequireAdmin
#include <WinAPIProc.au3>
ConsoleWrite("ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
Local $aProcessList = ProcessList()

For $n = 1 To 5
    For $i = 1 To $aProcessList[0][0]
        _WinAPI_IsElevated_pid($aProcessList[$i][1])
;~      ConsoleWrite($aProcessList[$i][1] & ' / ' & $aProcessList[$i][0] & ' = ' & _WinAPI_IsElevated_pid($aProcessList[$i][1]) & '   >Error code: ' & @error & @CRLF) ;### Debug Console
    Next
    ConsoleWrite("> ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
Next

Func _WinAPI_IsElevated_pid($iPID = 0)
    Local $hProcess, $hToken2, $aAdjust, $hToken, $iElev, $aRet, $iError = 0
    ; Enable "SeDebugPrivilege" privilege for obtain full access rights to another processes
;~  ConsoleWrite("@@ (" & @ScriptLineNumber & ") : ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
    Local $hToken1 = _WinAPI_OpenProcessToken(BitOR($TOKEN_ADJUST_PRIVILEGES, $TOKEN_QUERY))
    _WinAPI_AdjustTokenPrivileges($hToken1, $SE_DEBUG_NAME, $SE_PRIVILEGE_ENABLED, $aAdjust)
;~  ConsoleWrite("@@ (" & @ScriptLineNumber & ") : ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
    _WinAPI_CloseHandle($hToken1)
;~  ConsoleWrite("@@ (" & @ScriptLineNumber & ") : ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
    If $iPID <> 0 Then
        $hProcess = DllCall('kernel32.dll', 'handle', 'OpenProcess', 'dword', ((_WinAPI_GetVersion() < 6.0) ? 0x00000400 : 0x00001000), _
                'bool', 0, 'dword', $iPID)
        If @error Or Not $hProcess[0] Then Return SetError(@error + 20, @extended, 0)
;~      ConsoleWrite("@@ (" & @ScriptLineNumber & ") : ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
        $hToken2 = _WinAPI_OpenProcessToken(0x0008, $hProcess[0])
;~      ConsoleWrite("@@ (" & @ScriptLineNumber & ") : ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
    Else
        $hToken2 = _WinAPI_OpenProcessToken(0x0008)
    EndIf
    If Not $hToken2 Then
        _WinAPI_CloseHandle($hToken1)
        Return SetError(@error + 10, @extended, False)
    EndIf

;~  ConsoleWrite("@@ (" & @ScriptLineNumber & ") : ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
    Do
        $aRet = DllCall('advapi32.dll', 'bool', 'GetTokenInformation', 'handle', $hToken2, 'uint', 20, 'uint*', 0, 'dword', 4, _
                'dword*', 0) ; TOKEN_ELEVATION
        If @error Or Not $aRet[0] Then
            $iError = @error + 10
            ExitLoop
        EndIf
;~      ConsoleWrite("@@ (" & @ScriptLineNumber & ") : ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
        $iElev = $aRet[3]
        $aRet = DllCall('advapi32.dll', 'bool', 'GetTokenInformation', 'handle', $hToken2, 'uint', 18, 'uint*', 0, 'dword', 4, _
                'dword*', 0) ; TOKEN_ELEVATION_TYPE
        If @error Or Not $aRet[0] Then
            $iError = @error + 20
            ExitLoop
        EndIf
    Until 1
;~  ConsoleWrite("@@ (" & @ScriptLineNumber & ") : ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
    _WinAPI_CloseHandle($hToken1)
    _WinAPI_CloseHandle($hToken2)
;~  If $hProcess Then _WinAPI_CloseHandle($hProcess)
;~  ConsoleWrite("@@ (" & @ScriptLineNumber & ") : ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
    If $iError Then Return SetError($iError, 0, False)
    Return SetExtended($aRet[0] - 1, $iElev)
EndFunc   ;==>_WinAPI_IsElevated_pid

..and don't ask me why _WinAPI_CloseHandle($hToken1) twice 🤔

..am still wasting 1 on each loop. Anyone knows why ?

Fixed :) 

.. I kept editing :lol:

Edited by argumentum
better

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted

You got the same phenomenon as I have with my version.  One process generate 7 handles from nowhere.  And those 2 _WinAPI_CloseHandle($hToken) are very intriguing....

Posted (edited)

ok, I've cleaned it up, ready for copy'n'paste ( unless a better version is presented )

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#RequireAdmin
#include <WinAPIProc.au3>

ConsoleWrite("+++ ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
Test()
ConsoleWrite("+++ ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
Func Test()
    Local $aProcessList = ProcessList()
    For $n = 1 To 5
        For $i = 1 To $aProcessList[0][0]
            _WinAPI_IsElevated_pid($aProcessList[$i][1])
;~          ConsoleWrite($aProcessList[$i][1] & ' / ' & $aProcessList[$i][0] & ' = ' & _WinAPI_IsElevated_pid($aProcessList[$i][1]) & '   >Error code: ' & @error & @CRLF) ;### Debug Console
        Next
        ConsoleWrite("> ProcessHandleCount: " & _WinAPI_GetProcessHandleCount() & @CRLF)
    Next
EndFunc   ;==>Test

Func _WinAPI_IsElevated_pid($iPID = 0) ; https://www.autoitscript.com/forum/topic/203065-check-if-any-process-run-as-administrator/?do=findComment&comment=1539373
    Local Static $dwDesiredAccess = ((_WinAPI_GetVersion() < 6.0) ? 0x00000400 : 0x00001000) ; https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess
    Local $hProcess, $hToken2, $aAdjust, $hToken1, $iElev, $aRet, $iError = 0
    ; Enable "SeDebugPrivilege" privilege for obtain full access rights to another processes
    $hToken1 = _WinAPI_OpenProcessToken(BitOR($TOKEN_ADJUST_PRIVILEGES, $TOKEN_QUERY))
    _WinAPI_AdjustTokenPrivileges($hToken1, $SE_DEBUG_NAME, $SE_PRIVILEGE_ENABLED, $aAdjust)
    _WinAPI_CloseHandle($hToken1)
    If $iPID <> 0 Then
        $hProcess = DllCall('kernel32.dll', 'handle', 'OpenProcess', 'dword', $dwDesiredAccess, _
                'bool', 0, 'dword', $iPID)
        If @error Or Not $hProcess[0] Then Return SetError(@error + 10, @extended, 0)
        $hToken2 = _WinAPI_OpenProcessToken(0x0008, $hProcess[0])
    Else
        $hToken2 = _WinAPI_OpenProcessToken(0x0008)
    EndIf
    If Not $hToken2 Then
        _WinAPI_CloseHandle($hToken1)
        Return SetError(@error + 20, @extended, False)
    EndIf

    Do
        $aRet = DllCall('advapi32.dll', 'bool', 'GetTokenInformation', 'handle', $hToken2, 'uint', 20, 'uint*', 0, 'dword', 4, _
                'dword*', 0) ; TOKEN_ELEVATION
        If @error Or Not $aRet[0] Then
            $iError = @error + 30
            ExitLoop
        EndIf
        $iElev = $aRet[3]
        $aRet = DllCall('advapi32.dll', 'bool', 'GetTokenInformation', 'handle', $hToken2, 'uint', 18, 'uint*', 0, 'dword', 4, _
                'dword*', 0) ; TOKEN_ELEVATION_TYPE
        If @error Or Not $aRet[0] Then
            $iError = @error + 40
            ExitLoop
        EndIf
    Until 1
    _WinAPI_CloseHandle($hToken1)
    _WinAPI_CloseHandle($hToken2)
    If $iError Then Return SetError($iError, 0, False)
    Return SetExtended($aRet[0] - 1, $iElev)
EndFunc   ;==>_WinAPI_IsElevated_pid

... and the @error codes are basically 10, 20, 30, 40. I don't feel it deserves greater finesse.

Edit: made dwDesiredAccess static, as I do run this constantly ( reason that I found the handle leak )

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted

@Nine After remove the $bDebugPriv from
Local $hProcess = _WinAPI_OpenProcess($PROCESS_QUERY_LIMITED_INFORMATION, False, $iPID, True)

I have no leak.
I've come out with a Handle Count equal to the ones I entered

Thank you very much  :)

I know that I know nothing

Posted (edited)

@argumentum with your function I have a small leak (in windows10)  with 7 handles,

as the @Nine mentioned above  'One process generate 7 handles from nowhere'

However, after commented the line
; _WinAPI_AdjustTokenPrivileges($hToken1, $SE_DEBUG_NAME, $SE_PRIVILEGE_ENABLED, $aAdjust)
which does not seem to affect the result, :(

the leak is disappeared

Thank you very much  :)

Edit:
This is also invalid :(
after further testing it seems to affect some applications and it shows them incorrectly and some not at all

 

Edited by ioa747

I know that I know nothing

Posted

@ioa747 I know, but then there are @error in the detection of elevation.  It must be set at True to catch correctly all processes (see below).

Spoiler

>Running:(3.3.16.1):C:\Program Files (x86)\AutoIt3\autoit3.exe "C:\Apps\AutoIt\WinAPI\Check if another Process is Elevated.au3"     
Start : 171
error c csrss.exe/1
error c fontdrvhost.exe/1
error c WmiPrvSE.exe/1
error c dasHost.exe/1
error c AggregatorHost.exe/1
error c Aac3572DramHal_x86.exe/1
error c dllhost.exe/1
error c unsecapp.exe/1
error c extensionCardHal_x86.exe/1
error c AacKingstonDramHal_x86.exe/1
error c Aac3572MbHal_x86.exe/1
error c AacKingstonDramHal_x64.exe/1
error c vmmem/1
error c csrss.exe/1
error c fontdrvhost.exe/1
error c dwm.exe/1
error c MoUsoCoreWorker.exe/1
error c WmiPrvSE.exe/1
End : 171
+>06:56:22 AutoIt3 ended. rc:0

 

Posted (edited)

I noticed this too, (less often)

Spoiler

Start : 172
error c csrss.exe/1
error c csrss.exe/1
error c fontdrvhost.exe/1
error c fontdrvhost.exe/1
error c dwm.exe/1
error c WUDFHost.exe/1
error c dasHost.exe/1
error c wlanext.exe/1
error c conhost.exe/1
error c dllhost.exe/1
error c WmiPrvSE.exe/1
error c vmmem/1
error c cavwp.exe/1
End : 172

and I checked what it was about

Spoiler

   
1    csrss.exe (Client/Server Runtime Subsystem): This is a critical system process in Windows that is responsible for handling the user mode side of the Win32 subsystem.
        It manages console windows and creates or deletes threads. It is essential for the proper functioning of the Windows operating system.

    2    fontdrvhost.exe (Font Driver Host): This process is responsible for managing font rendering in Windows.
        It helps in loading and managing fonts, especially for applications that require specific font types.
        It runs in the background and is part of the Windows font management system.

    3    dwm.exe (Desktop Window Manager): This process is responsible for managing visual effects on the Windows desktop, such as transparency, live taskbar thumbnails, and window animations.
        It allows for a more visually appealing user interface and is essential for the Aero interface in Windows.

    4    WUDFHost.exe (Windows User-Mode Driver Framework Host): This process is part of the Windows Driver Framework and is used to host user-mode drivers.
        It allows for better management of device drivers and helps in improving the stability and performance of devices connected to the system.

    5    dasHost.exe (Device Association Framework Host): This process is responsible for managing device associations in Windows.
        It helps in connecting and managing devices such as Bluetooth and other peripherals, ensuring they work correctly with the operating system.

    6    wlanext.exe (WLAN Extensibility Framework): This process is related to the wireless networking capabilities of Windows.
        It provides support for wireless network connections and is involved in managing Wi-Fi connections and settings.

    7    conhost.exe (Console Host): This process is responsible for providing the command line interface in Windows.
        It allows for the execution of command-line applications and provides a way for these applications to interact with the Windows graphical user interface.

    8    dllhost.exe (COM Surrogate): This process is used to host COM (Component Object Model) objects.
        It allows for the execution of applications that use COM components in a separate process, which helps in improving stability and security by isolating these components.

    9    cavwp.exe (Windows Defender Antivirus Service): This process is part of Windows Defender, the built-in antivirus solution in Windows.
        It is responsible for real-time protection and scanning for malware and other security threats.

    10    WmiPrvSE.exe (WMI Provider Host): This process is part of the Windows Management Instrumentation (WMI) framework.
        It allows for the management and monitoring of system resources and provides information about the system's hardware and software.

    11    vmmem: This process is associated with Windows Subsystem for Linux (WSL) and virtual machines.
        It manages memory for virtualized environments and is responsible for allocating resources to WSL instances or other virtual machines running on the system.

These processes are generally safe and are part of the normal operation of the Windows operating system.
 

and I thought that since they are elements of the Windows 10 system, they can be bypassed,
by searching for the rights that some application has (obviously wrong) :(

Edited by ioa747

I know that I know nothing

Posted
Posted (edited)

I saw in my PC that the border coloring script had the handle count increased to over 30,000 and I realized that I was f:censored: !.
The resource behavior now is decent.
 

Spoiler
2024.11.17_10:58:11  -  RunTime: 00:00:00  -  UpTime: 008:08:07:33  -  PID: 16376
           | number of page faults | peak working set size, in bytes | current working set size, in bytes | peak paged pool usage, in bytes | current paged pool usage, in bytes | peak nonpaged pool usage, in bytes | current nonpaged pool usage, in bytes | current space allocated for the pagefile, in bytes | peak space allocated for the pagefile, in bytes | current amount of memory that cannot be shared with other processes, in bytes | ProcessHandleCount | ProcessThreadsCount | GDI objects | USER objects |
 Starting: | 18792                 | 34242560                        | 34160640                           | 215712                          | 215192                             | 18064                              | 12896                                 | 23166976                                           | 23392256                                        | 23166976                                                                      | 863                | 4                   | 31          | 17           |
  Exiting: | 18792                 | 34242560                        | 34160640                           | 215712                          | 215192                             | 18064                              | 12896                                 | 23166976                                           | 23392256                                        | 23166976                                                                      | 863                | 4                   | 31          | 17           |
    Diff.: | 0  ( x1 )             | 0 bytes  ( x1 )                 | 0 bytes  ( x1 )                    | 0 bytes  ( x1 )                 | 0 bytes  ( x1 )                    | 0 bytes  ( x1 )                    | 0 bytes  ( x1 )                       | 0 bytes  ( x1 )                                    | 0 bytes  ( x1 )                                 | 0 bytes  ( x1 )                                                               | 0  ( x1 )          | 0  ( x1 )           | 0  ( x1 )   | 0  ( x1 )    |

now vs before 

2024.12.11_04:29:43  -  RunTime: 012:02:20:10  -  UpTime: 032:01:39:03  -  PID: 10472  -  ExitCode: 11  -  ExitMethod: 1 (EXITCLOSE_BYEXIT)
           | number of page faults | peak working set size, in bytes | current working set size, in bytes | peak paged pool usage, in bytes | current paged pool usage, in bytes | peak nonpaged pool usage, in bytes | current nonpaged pool usage, in bytes | current space allocated for the pagefile, in bytes | peak space allocated for the pagefile, in bytes | current amount of memory that cannot be shared with other processes, in bytes | ProcessHandleCount | ProcessThreadsCount | GDI objects  | USER objects |
 Starting: | 129825                | 47820800                        | 47226880                           | 219888                          | 219368                             | 18200                              | 13032                                 | 36179968                                           | 36610048                                        | 36179968                                                                      | 1023               | 4                   | 31           | 17           |
  Exiting: | 3053801               | 51466240                        | 32026624                           | 831896                          | 807056                             | 25264                              | 19968                                 | 38694912                                           | 38694912                                        | 38694912                                                                      | 31186              | 6                   | 44           | 25           |
    Diff.: | 2923976  ( x23.5 )    | 3 MB  ( x1.1 )                  | -15200256 bytes  ( x0.7 )          | 598 KB  ( x3.8 )                | 574 KB  ( x3.7 )                   | 7 KB  ( x1.4 )                     | 7 KB  ( x1.5 )                        | 2 MB  ( x1.1 )                                     | 2 MB  ( x1.1 )                                  | 2 MB  ( x1.1 )                                                                | 30163  ( x30.5 )   | 2  ( x1.5 )         | 13  ( x1.4 ) | 8  ( x1.5 )  |

Myself, am not a programmer. I mix and match until it works, or looks like working. Am close to a living, breathing: LLM/ChatGPT with less memory :lol:

If this gets perfected by those that actually know what they are doing, I'll copy'n'paste that. But for now this is what we've got 🤷‍♂️

PS: Added _ArrayTranspose() to "Memory leak script". Next time I share the resource usage it will look better than this. Next time around :)

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...