Modify

Opened 14 years ago

Closed 14 years ago

Last modified 14 years ago

#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 _Security
GetTokenInformation 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: Changed 14 years ago by anonymous

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 0

If this isn't done, the result is there's be a 'LastError' of "ERROR_INSUFFICIENT_BUFFER" (122)

comment:2 in reply to: ↑ 1 Changed 14 years ago by anonymous

strike that - I misread ProgAndy's code/response. Sorry

comment:3 Changed 14 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 14 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 14 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 14 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 14 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 14 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 14 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.

Add Comment

Modify Ticket

Action
as closed The owner will remain Jpm.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.