matrixnz Posted November 14, 2009 Share Posted November 14, 2009 Brief Overview of what I'm trying to achieve I have a program that runs as Local System Account, in the middle of this process I'd like to have the option to run IE, Word, etc.. as the currently logged in user. (The reason being is that, the System Account doesn't have access to the Web, Printers etc..) What I've found while searching is that you can use the WinAPI ImpersonateLoggedOnUser, the problem is I have no idea how to impliment it. Open Process Function http://msdn.microsoft.com/en-us/library/ms684320(VS.85).aspx Open Process Token Function http://msdn.microsoft.com/en-us/library/aa379295(VS.85).aspx Impersonate Logged On User Function http://msdn.microsoft.com/en-us/library/aa378612(VS.85).aspx From what I understand the simplist method is to get a user ProcessID for example Explorer.exe, then Open the Process, then Open the Process Token then use ImpersonateLoggedOnUser from the Process Token. However I can't seem to get it to work, I have no idea when it comes to Windows API so if anyone can assist it would be much appreciated. Here is what I've tried so far: #Include <WinAPI.au3> $ProcessID = ProcessExists("EXPLORER.exe") $ProcessHandle = _WinAPI_OpenProcess(0x0400, True, $ProcessID) $ProcessToken = _WinAPI_OpenProcessToken($ProcessHandle) MsgBox(0,'', $ProcessToken) ; Keeps returning 0, although $ProcessHandle Func _WinAPI_OpenProcessToken($pHandle) Local $hToken, $aResult $aResult = DllCall("Kernel32.dll", "int", "OpenProcessToken", "int", $pHandle, "int", "TOKEN_ALL_ACCESS", "int", $hToken) Return $aResult EndFunc Link to comment Share on other sites More sharing options...
Authenticity Posted November 14, 2009 Share Posted November 14, 2009 expandcollapse popup#Include <WinAPI.au3> Global Const $STANDARD_RIGHTS_REQUIRED = 0x000F0000 Global Const $TOKEN_ASSIGN_PRIMARY = 0x0001 Global Const $TOKEN_DUPLICATE = 0x0002 Global Const $TOKEN_IMPERSONATE = 0x0004 Global Const $TOKEN_QUERY = 0x0008 Global Const $TOKEN_QUERY_SOURCE = 0x0010 Global Const $TOKEN_ADJUST_PRIVILEGES = 0x0020 Global Const $TOKEN_ADJUST_GROUPS = 0x0040 Global Const $TOKEN_ADJUST_DEFAULT = 0x0080 Global Const $TOKEN_ADJUST_SESSIONID = 0x0100 Global Const $TOKEN_ALL_ACCESS_P = BitOR($STANDARD_RIGHTS_REQUIRED, $TOKEN_ASSIGN_PRIMARY, $TOKEN_DUPLICATE, $TOKEN_IMPERSONATE, $TOKEN_QUERY, $TOKEN_QUERY_SOURCE, $TOKEN_ADJUST_PRIVILEGES, $TOKEN_ADJUST_GROUPS, $TOKEN_ADJUST_DEFAULT) Global Const $TOKEN_ALL_ACCESS = BitOR($TOKEN_ALL_ACCESS_P, $TOKEN_ADJUST_SESSIONID) $ProcessID = ProcessExists("EXPLORER.exe") $ProcessHandle = _WinAPI_OpenProcess(0x0400, False, $ProcessID) ConsoleWrite($ProcessHandle & @CRLF) $ProcessToken = _WinAPI_OpenProcessToken($ProcessHandle, $TOKEN_ALL_ACCESS) ConsoleWrite($ProcessToken & @CRLF) If $ProcessToken Then ConsoleWrite(_WinAPI_ImpersonateLoggedOnUser($ProcessToken) & @CRLF) If $ProcessToken Then _WinAPI_CloseHandle($ProcessToken) If $ProcessHandle Then _WinAPI_CloseHandle($ProcessHandle) Func _WinAPI_OpenProcessToken($pHandle, $iAccess) Local $aResult = DllCall("advapi32.dll", "int", "OpenProcessToken", "hwnd", $pHandle, "int", $iAccess, "int*", 0) If @error Or $aResult[0] = 0 Then Return SetError(1, 0, 0) Return SetError(0, 0, $aResult[3]) EndFunc Func _WinAPI_ImpersonateLoggedOnUser($hToken) Local $aResult = DllCall("advapi32.dll", "int", "ImpersonateLoggedOnUser", "hwnd", $hToken) If @error Then Return SetError(@error, @extended, 0) Return SetError(0, 0, $aResult[0] <> 0) EndFunc Link to comment Share on other sites More sharing options...
matrixnz Posted November 14, 2009 Author Share Posted November 14, 2009 Hi Authenticity Thanks for the post, all I can say is woah, I can run this as the logged on user without any problems, but running it as a different user (runas) for example the local Administrator, I get the following error: _WinAPI_OpenProcess:Standard: Access is denied. Cheers Link to comment Share on other sites More sharing options...
Authenticity Posted November 14, 2009 Share Posted November 14, 2009 The last parameter of _WinAPI_OpenProcess() is false by default, you may want to supply true instead. Read the function description. Link to comment Share on other sites More sharing options...
matrixnz Posted November 14, 2009 Author Share Posted November 14, 2009 Hi Authenticity Sorry for the delay, had already tried that before posting, (I assume you were referring to $fDebugPriv) same problem unfortunately. Cheers Link to comment Share on other sites More sharing options...
Authenticity Posted November 14, 2009 Share Posted November 14, 2009 Try this one, it's taken from NomadMemory.au3.expandcollapse popup#include <WinAPI.au3> SetPrivilege("SeDebugPrivilege", True) $PID = ProcessExists("svchost.exe") $hProc = _WinAPI_OpenProcess(0x400, False, $PID) ConsoleWrite($hProc & @CRLF) If $hProc Then _WinAPI_CloseHandle($hProc) ;================================================================================== ; Function: SetPrivilege( $privilege, $bEnable ) ; Description: Enables (or disables) the $privilege on the current process ; (Probably) requires administrator privileges to run ; ; Author(s): Larry (from autoitscript.com's Forum) ; Notes(s): ; http://www.autoitscript.com/forum/index.php?s=&showtopic=31248&view=findpost&p=223999 ;================================================================================== Func SetPrivilege( $privilege, $bEnable ) Const $MY_TOKEN_ADJUST_PRIVILEGES = 0x0020 Const $MY_TOKEN_QUERY = 0x0008 Const $MY_SE_PRIVILEGE_ENABLED = 0x0002 Local $hToken, $SP_auxret, $SP_ret, $hCurrProcess, $nTokens, $nTokenIndex, $priv $nTokens = 1 $LUID = DLLStructCreate("dword;int") If IsArray($privilege) Then $nTokens = UBound($privilege) $TOKEN_PRIVILEGES = DLLStructCreate("dword;dword[" & (3 * $nTokens) & "]") $NEWTOKEN_PRIVILEGES = DLLStructCreate("dword;dword[" & (3 * $nTokens) & "]") $hCurrProcess = DLLCall("kernel32.dll","hwnd","GetCurrentProcess") $SP_auxret = DLLCall("advapi32.dll","int","OpenProcessToken","hwnd",$hCurrProcess[0], _ "int",BitOR($MY_TOKEN_ADJUST_PRIVILEGES,$MY_TOKEN_QUERY),"int*",0) If $SP_auxret[0] Then $hToken = $SP_auxret[3] DLLStructSetData($TOKEN_PRIVILEGES,1,1) $nTokenIndex = 1 While $nTokenIndex <= $nTokens If IsArray($privilege) Then $priv = $privilege[$nTokenIndex-1] Else $priv = $privilege EndIf $ret = DLLCall("advapi32.dll","int","LookupPrivilegeValue","str","","str",$priv, _ "ptr",DLLStructGetPtr($LUID)) If $ret[0] Then If $bEnable Then DLLStructSetData($TOKEN_PRIVILEGES,2,$MY_SE_PRIVILEGE_ENABLED,(3 * $nTokenIndex)) Else DLLStructSetData($TOKEN_PRIVILEGES,2,0,(3 * $nTokenIndex)) EndIf DLLStructSetData($TOKEN_PRIVILEGES,2,DllStructGetData($LUID,1),(3 * ($nTokenIndex-1)) + 1) DLLStructSetData($TOKEN_PRIVILEGES,2,DllStructGetData($LUID,2),(3 * ($nTokenIndex-1)) + 2) DLLStructSetData($LUID,1,0) DLLStructSetData($LUID,2,0) EndIf $nTokenIndex += 1 WEnd $ret = DLLCall("advapi32.dll","int","AdjustTokenPrivileges","hwnd",$hToken,"int",0, _ "ptr",DllStructGetPtr($TOKEN_PRIVILEGES),"int",DllStructGetSize($NEWTOKEN_PRIVILEGES), _ "ptr",DllStructGetPtr($NEWTOKEN_PRIVILEGES),"int*",0) $f = DLLCall("kernel32.dll","int","GetLastError") EndIf $NEWTOKEN_PRIVILEGES=0 $TOKEN_PRIVILEGES=0 $LUID=0 If $SP_auxret[0] = 0 Then Return 0 $SP_auxret = DLLCall("kernel32.dll","int","CloseHandle","hwnd",$hToken) If Not $ret[0] And Not $SP_auxret[0] Then Return 0 return $ret[0] EndFunc ;==>SetPrivilege Link to comment Share on other sites More sharing options...
matrixnz Posted November 14, 2009 Author Share Posted November 14, 2009 Thanks AuthenticityUnfortunately still no go, however by chance I found "http://www.autoitscript.com/forum/index.php?showtopic=104735&st=20&gopid=745505& it doesn't work exactly how I thought it should, I've left a comment with what I've found so far.Cheers Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now