#1560 closed Bug (Fixed)
Errors in implementation of _Security_... functions
Reported by: | ProgAndy | Owned by: | Jpm |
---|---|---|---|
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)
comment:1 follow-up: ↓ 2 Changed 15 years ago by anonymous
comment:2 in reply to: ↑ 1 Changed 15 years ago by anonymous
strike that - I misread ProgAndy's code/response. Sorry
comment:3 Changed 15 years ago by Jpm
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 Changed 15 years ago by anonymous
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 Changed 15 years ago by Jpm
- Summary changed from Errors in implementation of _Security_... funtions to 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 Changed 15 years ago by ProgAndy
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 Changed 15 years ago by Valik
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 Changed 15 years ago by Jpm
- Milestone set to 3.3.7.0
- Owner changed from Gary to Jpm
- Resolution set to Fixed
- Status changed from new to closed
Fixed by revision [5781] in version: 3.3.7.0
comment:9 Changed 15 years ago by Jpm
This ticket is referenced in revision: [5782]
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.
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:
If this isn't done, the result is there's be a 'LastError' of "ERROR_INSUFFICIENT_BUFFER" (122)