#1560 closed Bug (Fixed)
Errors in implementation of _Security_... functions
| Reported by: | ProgAndy | Owned by: | J-Paul Mesnage |
|---|---|---|---|
| Milestone: | 3.3.7.0 | Component: | Standard UDFs |
| Version: | 3.3.6.0 | Severity: | None |
| Keywords: | Cc: |
Description
The functions _SecurityOpenProcessToken and _SecurityGetTokenInformation aren't correctly implemented.
In _SecurityOpenProcessToken the last parameter must be a reference (ptr*)
In _SecurityGetTokenInformation the error checking was too strict. The firstl DLLCall returns the required buffer size. Additionally the return value will be zero, but this is not accepted by the current function.
This are the corrected fnctions without headers
; Author ........: Paul Campbell (PaulIA)
Func _Security__OpenProcessToken($hProcess, $iAccess)
Local $aResult = DllCall("advapi32.dll", "int", "OpenProcessToken", "handle", $hProcess, "dword", $iAccess, "ptr*", 0)
If @error Then Return SetError(@error, @extended, 0)
Return SetError(0, $aResult[0], $aResult[3])
EndFunc ;==>_Security__OpenProcessToken
; Author ........: Paul Campbell (PaulIA)
Func _Security__GetTokenInformation($hToken, $iClass)
Local $aResult = DllCall("advapi32.dll", "bool", "GetTokenInformation", "handle", $hToken, "int", $iClass, "ptr", 0, "dword", 0, "dword*", 0)
If @error Then Return SetError(@error, @extended, 0)
If Not $aResult[5] Then Return 0
Local $tBuffer = DllStructCreate("byte[" & $aResult[5] & "]")
Local $pBuffer = DllStructGetPtr($tBuffer)
$aResult = DllCall("advapi32.dll", "bool", "GetTokenInformation", "handle", $hToken, "int", $iClass, "ptr", $pBuffer, _
"dword", $aResult[5], "dword*", 0)
If @error Then Return SetError(@error, @extended, 0)
If Not $aResult[0] Then Return 0
Return $tBuffer
EndFunc ;==>_Security__GetTokenInformation
Attachments (0)
Change History (9)
follow-up: 2 comment:1 by , 16 years ago
comment:3 by , 16 years ago
at least the _SecurityOpenProcessToken() is doing what the doc and the windows API does a ptr to an handle not the handle itself sor "ptr" is correct.
comment:4 by , 16 years ago
For _SecurityOpenProcessToken(), "handle*" or as ProgAndy has it "ptr*" is correct, as MSDN lists it as 'PHANDLE' which is a pointer to a handle (to be written to). This won't be written to unless you provide that "*" at the end.
comment:5 by , 16 years ago
| Summary: | Errors in implementation of _Security_... funtions → Errors in implementation of _Security_... functions |
|---|
At least the doc can be wrong as I understand an HANDLE is returned instead of a ptr to an HANDLE if we change ptr to ptr*.
Can somebody post a "working" example?
Thanks ;)
comment:6 by , 16 years ago
Yes, OpenProcessToken returns a handle in the last parameter. But tell me, how would the function be able to return something in a by-value parameter? There is always a reference required to return a value per parameter.
Here is a working example (needs the both changed funtions from this post) When debugging this script, I found the errors in the two functions.
#include <Security.au3>
#include <Constants.au3>
#Include <WinAPI.au3>
ConsoleWrite("Process explorer.exe is running under user: " & _ProcessGetOwner("explorer.exe") & @LF)
Func _ProcessGetOwner($ivPID)
$ivPID = ProcessExists($ivPID)
If Not $ivPID Then Return(SetError(1, 0, 0))
Local Const $TOKEN_READ = 0x00020000+0x0008; STANDARD_RIGHTS_READ+TOKEN_QUERY
Local $hvProcess = _WinAPI_OpenProcess($PROCESS_QUERY_INFORMATION, False, $ivPID, False)
Local $hvToken = _Security__OpenProcessToken($hvProcess, $TOKEN_READ)
Local $bvSID = _Security__GetTokenInformation($hvToken, $TOKENOWNER)
Local $avRet = DllStructCreate("ulong", DllStructGetPtr($bvSID))
$avRet = _Security__SidToStringSid(DllStructGetData($avRet, 1))
$avRet = _Security__LookupAccountSid($avRet)
_WinAPI_CloseHandle($hvProcess)
_WinAPI_CloseHandle($hvToken)
If Not IsArray($avRet) Then Return(SetError(1, 0, ""))
Return(SetError(0, $avRet[2], $avRet[0]))
EndFunc
Script taken from http://www.autoitscript.com/forum/index.php?showtopic=112924&view=findpost&p=790780
comment:7 by , 16 years ago
Why is this a discussion? It took me 20 seconds to go to MSDN and get this:
BOOL WINAPI OpenProcessToken( __in HANDLE ProcessHandle, __in DWORD DesiredAccess, __out PHANDLE TokenHandle );
That means, unless the function is using "handle", "dword", and "handle*" for it's parameters to DllCall() then it's wrong. Pretty clear cut and I'm not sure why there has to be this back and forth on it.
comment:8 by , 16 years ago
| Milestone: | → 3.3.7.0 |
|---|---|
| Owner: | changed from to |
| Resolution: | → Fixed |
| Status: | new → closed |
Fixed by revision [5781] in version: 3.3.7.0

Good catch ProgAndy. To add to the _Security problems though, the _SecurityGetTokenInformation() function will always return 0 (false) because the first call will always fail due to the buffer size equaling 0. To modify it to work correctly, check the return size as well:
Func _Security__GetTokenInformation($hToken, $iClass) Local $aResult = DllCall("advapi32.dll", "bool", "GetTokenInformation", "handle", $hToken, "int", $iClass, "ptr", 0, "dword", 0, "dword*", 0) If @error Then Return SetError(@error, @extended, 0) If Not $aResult[0] And $aResult[5]=0 Then Return 0If this isn't done, the result is there's be a 'LastError' of "ERROR_INSUFFICIENT_BUFFER" (122)