E1M1 Posted August 27, 2012 Share Posted August 27, 2012 (edited) HelloI can't seem to find solution for my CreateProcessAsUserproblem. I keep getting The parameter is incorrect error. but I dont even know which parameter is incorrect. Could anyone please look into my code and help me to find out what causes this error. Link to function: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682429%28v=vs.85%29.aspxexpandcollapse popup;~ CreateProcessAsUser(hToken,NULL,app_path,NULL,NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,NULL,&StartUPInfo,&ProcessInfo)) #include <winapi.au3> #include <array.au3> GUICreate("") GUISetState(@SW_SHOW) $force_gui = false $NULL = 0 $WTS_CURRENT_SERVER_HANDLE = $NULL $WTSActive = 0 $WTSShadow = 1 $WTSConnectQuery = 2 $CREATE_UNICODE_ENVIRONMENT = 0x00000400 $DETACHED_PROCESS = 0x00000008 $MAX_PATH = 260 Global Const $tagWTS_SESSION_INFO = 'dword SessionId;ptr WinStationName;uint State' ;testing ;~ $s = "" ;~ GetModuleFileName(0,$s,260) ;~ MsgBox(0,0,$s) #cs typedef struct _STARTUPINFO { DWORD cb; 1 LPTSTR lpReserved; 2 LPTSTR lpDesktop; 3 LPTSTR lpTitle; 4 DWORD dwX; 5 DWORD dwY; 6 DWORD dwXSize; 7 DWORD dwYSize; 8 DWORD dwXCountChars; 9 DWORD dwYCountChars; 10 DWORD dwFillAttribute; 11 DWORD dwFlags; 12 WORD wShowWindow; 13 WORD cbReserved2; 14 LPBYTE lpReserved2; 15 HANDLE hStdInput; 16 HANDLE hStdOutput; 17 HANDLE hStdError; 18 } STARTUPINFO, *LPSTARTUPINFO; typedef struct _PROCESS_INFORMATION { HANDLE hProcess; HANDLE hThread; DWORD dwProcessId; DWORD dwThreadId; } PROCESS_INFORMATION, *LPPROCESS_INFORMATION; #ce LaunchProcessWin() Func LaunchProcessWin() $bReturn = False $hToken = 0 $env = 0 $StartUPInfo = DllStructCreate("DWORD;LPTSTR;LPTSTR;LPTSTR;DWORD;DWORD;DWORD;DWORD;DWORD;DWORD;DWORD;DWORD;WORD;WORD;BYTE;HANDLE;HANDLE;HANDLE") DllStructSetData($StartUPInfo, 13, @SW_SHOW) DllStructSetData($StartUPInfo, 3, "Winsta0\\Winlogon") DllStructSetData($StartUPInfo, 1, DllStructGetSize($StartUPInfo)) $ProcessInfo = DllStructCreate("HANDLE;HANDLE;DWORD;DWORD") $app_path = "" $id = GetRDPSessionID() _MsgBox(0, 1, "abc") $hToken = WTSQueryUserToken($id) _MsgBox(0, 2, "abc") CreateEnvironmentBlock($env, $hToken, False) _MsgBox(0, 2.1, "abc") GetModuleFileName(0,$app_path,$MAX_PATH) _MsgBox(0, 3, "abc") CreateProcessAsUser($hToken, $NULL, $app_path, $NULL, $NULL, 0, $CREATE_UNICODE_ENVIRONMENT + $DETACHED_PROCESS, $env, $NULL, DllStructGetPtr($StartUPInfo), DllStructGetPtr($ProcessInfo)) _MsgBox(0, 4, "abc") ;CreateProcessAsUser(hToken,NULL,app_path,NULL,NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,NULL,&StartUPInfo,&ProcessInfo)// C++ _MsgBox(0, $env, DllStructGetData($ProcessInfo, 3)) EndFunc ;==>LaunchProcessWin ;~ CreateProcessAsUser(hToken,$NULL,app_path,$NULL,$NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,$NULL,&StartUPInfo,&ProcessInfo)) Func GetWinLogonHandle() $bResult = False; $hProcess = 0; $hAccessToken = $NULL; $hTokenThis = $NULL; $dwID_session = 0; $dwID = 0 If WTSGetActiveConsoleSessionId() > 0 Then $dwID_session = WTSGetActiveConsoleSessionId() EndIf ;W2k handler needed ;following is for xp and up ;~ $dwID EndFunc ;==>GetWinLogonHandle Func CreateEnvironmentBlock(ByRef $lpEnvironment, $hToken, $bInherit) $struct = DllStructCreate("ptr") $Ret = DllCall('Userenv.dll', 'bool', 'CreateEnvironmentBlock', _ 'ptr', DllStructGetPtr($struct), _ 'HANDLE', $hToken, _ 'bool', $bInherit) $lpEnvironment = DllStructGetData($struct, 1) Return $Ret[0] EndFunc ;==>CreateEnvironmentBlock Func WTSQueryUserToken($SessionId) $struct = DllStructCreate("HANDLE") $Ret = DllCall('wtsapi32.dll', 'bool', 'WTSQueryUserToken', _ 'ULONG', $SessionId, _ 'ptr*', DllStructGetPtr($struct)) If $Ret[0] <> 0 Then Return $Ret[2] Else _MsgBox(16, "Error (you must run me as system service)", _WinAPI_GetLastErrorMessage(), 10) Exit EndIf EndFunc ;==>WTSQueryUserToken Func GetRDPSessionID() $Ret = WTSEnumerateSessions($WTS_CURRENT_SERVER_HANDLE, 0, 1, 0, 0) $Offset = 0 For $i = 1 To $Ret[5] $tInfo = DllStructCreate($tagWTS_SESSION_INFO, $Ret[4] + $Offset) $Offset += DllStructGetSize($tInfo) $SessionId = DllStructGetData($tInfo, 'SessionId') $SessionName = DllStructGetData(DllStructCreate('wchar[1024]', DllStructGetData($tInfo, 'WinStationName')), 1) $SessionState = DllStructGetData($tInfo, 'State') If $SessionName = "Console" _ And ($SessionState = $WTSActive Or _ $SessionState = $WTSShadow Or _ $SessionState = $WTSConnectQuery _ ) Then Return $SessionId EndIf Next Return -1 EndFunc ;==>GetRDPSessionID Func WTSGetActiveConsoleSessionId() $Ret = DllCall('Kernel32.dll', 'dword', 'WTSGetActiveConsoleSessionId') Return $Ret[0] EndFunc ;==>WTSGetActiveConsoleSessionId Func WTSEnumerateSessions($hServer, $Reserved, $Version, $ppSessionInfo, $pCount) $Ret = DllCall('wtsapi32.dll', 'int', 'WTSEnumerateSessionsW', _ 'ptr', $hServer, _ 'dword', $Reserved, _ 'dword', $Version, _ 'ptr*', $ppSessionInfo, _ 'dword*', $pCount) Return $Ret EndFunc ;==>WTSEnumerateSessions Func GetModuleFileName($hModule,byref $lpFilename, $nSize) $Ret = DllCall('Kernel32.dll', 'int', 'GetModuleFileNameW', _ 'handle', $hModule, _ 'wstr', 0, _ 'int', $nSize) $lpFilename = $Ret[2] Return $Ret[0] EndFunc Func CreateProcessAsUser($hToken, $lpApplicationName, $lpCommandline, $lpProcessAttributes, $lpThreadAttributes, $bInheritHandles, $dwCreationFlags, $lpEnvironment, $lpCurrentDirectory, $lpStartupInfo, $lpProcessInformation) $ret = DllCall("advapi32.dll", "bool", "CreateProcessAsUserW", _ ; W is better "handle", $hToken, _ "ptr", $lpApplicationName, _ "wstr", $lpCommandline, _ ; wstr for CreateProcessAsUserW "ptr", $lpProcessAttributes, _ "ptr", $lpThreadAttributes, _ "bool", $bInheritHandles, _ "dword", $dwCreationFlags, _ "ptr", $lpEnvironment, _ "ptr", $lpCurrentDirectory, _ "ptr", $lpStartupInfo, _ "ptr", $lpProcessInformation) If $ret[0] = 0 Then _MsgBox(16, "proc e "&@error&" "&$hToken, _WinAPI_GetLastErrorMessage()) Return $ret EndFunc ;==>CreateProcessAsUser Func _MsgBox($a, $b, $c, $d = 0) If @UserName <> "SYSTEM" Or $force_gui Then MsgBox($a, $b, $c, $d) Else FileWrite(@ScriptDir & "\mb.txt", '"' & $b & '"' & ", " & '"' & $c & '"' & @CRLF) EndIf EndFunc ;==>_MsgBox Func __ArrayDisplay($a, $b = "array") If @UserName <> "SYSTEM" Or $force_gui Then _ArrayDisplay($a, $b) Else $dat = $b & @CRLF For $i = 0 To UBound($a) - 1 $dat &= @TAB & $a[$i] & @CRLF Next FileWrite(@ScriptDir & "\arr.txt", $dat) EndIf EndFunc ;==>__ArrayDisplayThanks in advance Edited August 29, 2012 by E1M1 edited Link to comment Share on other sites More sharing options...
JohnOne Posted August 27, 2012 Share Posted August 27, 2012 For starters, your second parameter "lpApplicationName" should be type LPCTSTR which I believe is "str" in AutoIt3, or perhaps "wstr" if you are using wide. plus a few more further down. And I'm uncertain where you got "LPTSTR" from as part of your $StartUPInfo struct. AutoIt Absolute Beginners  Require a serial  Pause Script  Video Tutorials by Morthawt  ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
E1M1 Posted August 28, 2012 Author Share Posted August 28, 2012 (edited) For starters, your second parameter "lpApplicationName" should be type LPCTSTR which I believe is "str" in AutoIt3, or perhaps "wstr" if you are using wide. Ok edited function Func CreateProcessAsUser($hToken, $lpApplicationName, $lpCommandline, $lpProcessAttributes, $lpThreadAttributes, $bInheritHandles, $dwCreationFlags, $lpEnvironment, $lpCurrentDirectory, $lpStartupInfo, $lpProcessInformation) $ret = DllCall("advapi32.dll", "bool", "CreateProcessAsUserW", _ ; W is better "handle", $hToken, _ "wstr", $lpApplicationName, _ "wstr", $lpCommandline, _ ; wstr for CreateProcessAsUserW "ptr", $lpProcessAttributes, _ "ptr", $lpThreadAttributes, _ "bool", $bInheritHandles, _ "dword", $dwCreationFlags, _ "ptr", $lpEnvironment, _ "wstr", $lpCurrentDirectory, _ "ptr", $lpStartupInfo, _ "ptr", $lpProcessInformation) If $ret[0] = 0 Then _MsgBox(16, "proc e "&@error&" "&$hToken, _WinAPI_GetLastErrorMessage()) Return $ret EndFunc ;==>CreateProcessAsUser and call: CreateProcessAsUser($hToken, "", $app_path, $NULL, $NULL, 0, $CREATE_UNICODE_ENVIRONMENT + $DETACHED_PROCESS, $env, "", DllStructGetPtr($StartUPInfo), DllStructGetPtr($ProcessInfo)) And I'm uncertain where you got "LPTSTR" from as part of your $StartUPInfo struct.Thanks. Now I shanged it to following which solved this problem. $StartUPInfo = DllstructCreate("DWORD;char;char[19];char;DWORD;DWORD;DWORD;DWORD;DWORD;DWORD;DWORD;DWORD;WORD;WORD;BYTE;HANDLE;HANDLE;HANDLE") But now get: I the filename, directoryname or volume label syntax is incorrect. I really dont know why this happens because GetModuleFileName should give it correct info. Edited August 28, 2012 by E1M1 edited Link to comment Share on other sites More sharing options...
E1M1 Posted August 28, 2012 Author Share Posted August 28, 2012 After some coding I get this: Invalid access to memory location. expandcollapse popup;~ CreateProcessAsUser(hToken,NULL,app_path,NULL,NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,NULL,&StartUPInfo,&ProcessInfo)) #include <winapi.au3> #include <array.au3> GUICreate("") GUISetState(@SW_SHOW) $force_gui = true $NULL = 0 $WTS_CURRENT_SERVER_HANDLE = $NULL $WTSActive = 0 $WTSShadow = 1 $WTSConnectQuery = 2 $CREATE_UNICODE_ENVIRONMENT = 0x00000400 $DETACHED_PROCESS = 0x00000008 $MAX_PATH = 260 Global Const $tagWTS_SESSION_INFO = 'dword SessionId;ptr WinStationName;uint State' ;testing ;~ $s = "" ;~ GetModuleFileName(0,$s,260) ;~ MsgBox(0,0,$s) #cs typedef struct _STARTUPINFO { DWORD cb; 1 LPTSTR lpReserved; 2 LPTSTR lpDesktop; 3 LPTSTR lpTitle; 4 DWORD dwX; 5 DWORD dwY; 6 DWORD dwXSize; 7 DWORD dwYSize; 8 DWORD dwXCountChars; 9 DWORD dwYCountChars; 10 DWORD dwFillAttribute; 11 DWORD dwFlags; 12 WORD wShowWindow; 13 WORD cbReserved2; 14 LPBYTE lpReserved2; 15 HANDLE hStdInput; 16 HANDLE hStdOutput; 17 HANDLE hStdError; 18 } STARTUPINFO, *LPSTARTUPINFO; typedef struct _PROCESS_INFORMATION { HANDLE hProcess; HANDLE hThread; DWORD dwProcessId; DWORD dwThreadId; } PROCESS_INFORMATION, *LPPROCESS_INFORMATION; #ce LaunchProcessWin() Func LaunchProcessWin() $bReturn = False $hToken = 0 $env = 0 $StartUPInfo = DllstructCreate("DWORD;char;char[19];char;DWORD;DWORD;DWORD;DWORD;DWORD;DWORD;DWORD;DWORD;WORD;WORD;BYTE;HANDLE;HANDLE;HANDLE") DllStructSetData($StartUPInfo, 13, @SW_SHOW) DllStructSetData($StartUPInfo, 3, "Winsta0Winlogon") DllStructSetData($StartUPInfo, 1, DllStructGetSize($StartUPInfo)) $ProcessInfo = DllStructCreate("HANDLE;HANDLE;DWORD;DWORD") $app_path = "" $id = GetRDPSessionID() ;~ _MsgBox(0, 1, "abc") $hToken = WTSQueryUserToken($id) ;~ _MsgBox(0, 2, "abc") CreateEnvironmentBlock($env, $hToken, False) ;~ _MsgBox(0, 2.1, "abc") GetModuleFileName(0,$app_path,$MAX_PATH) _MsgBox(0, 3, DllStructGetData($StartUPInfo,3)) $file = DllStructCreate("char[260]") $lpProcessAttributes=dllstructcreate($tagSECURITY_ATTRIBUTES) $lpThreadAttributes=dllstructcreate($tagSECURITY_ATTRIBUTES) DLLStructSetData($lpThreadAttributes,"Descriptor",0) $ta_size=dllstructgetsize($lpThreadAttributes) DLLStructSetData($lpThreadAttributes,"Length",$ta_size) DLLStructSetData($lpProcessAttributes,"Descriptor",0) $pa_size=dllstructgetsize($lpProcessAttributes) DLLStructSetData($lpProcessAttributes,"Length",$pa_size) CreateProcessAsUser($hToken, "", $app_path, DllStructGetPtr($lpProcessAttributes), DllStructGetPtr($lpThreadAttributes), 0, $CREATE_UNICODE_ENVIRONMENT + $DETACHED_PROCESS, $env,"", DllStructGetPtr($StartUPInfo), DllStructGetPtr($ProcessInfo)) _MsgBox(0, 4, "abc") ;CreateProcessAsUser(hToken,NULL,app_path,NULL,NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,NULL,&StartUPInfo,&ProcessInfo)// C++ _MsgBox(0, $env, DllStructGetData($ProcessInfo, 3)) EndFunc ;==>LaunchProcessWin ;~ CreateProcessAsUser(hToken,$NULL,app_path,$NULL,$NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,$NULL,&StartUPInfo,&ProcessInfo)) Func GetWinLogonHandle() $bResult = False; $hProcess = 0; $hAccessToken = $NULL; $hTokenThis = $NULL; $dwID_session = 0; $dwID = 0 If WTSGetActiveConsoleSessionId() > 0 Then $dwID_session = WTSGetActiveConsoleSessionId() EndIf ;W2k handler needed ;following is for xp and up ;~ $dwID EndFunc ;==>GetWinLogonHandle Func CreateEnvironmentBlock(ByRef $lpEnvironment, $hToken, $bInherit) $struct = DllStructCreate("ptr") $Ret = DllCall('Userenv.dll', 'bool', 'CreateEnvironmentBlock', _ 'ptr', DllStructGetPtr($struct), _ 'HANDLE', $hToken, _ 'bool', $bInherit) $lpEnvironment = DllStructGetData($struct, 1) Return $Ret[0] EndFunc ;==>CreateEnvironmentBlock Func WTSQueryUserToken($SessionId) $struct = DllStructCreate("HANDLE") $Ret = DllCall('wtsapi32.dll', 'bool', 'WTSQueryUserToken', _ 'ULONG', $SessionId, _ 'ptr*', DllStructGetPtr($struct)) If $Ret[0] <> 0 Then Return $Ret[2] Else _MsgBox(16, "Error (you must run me as system service)", _WinAPI_GetLastErrorMessage(), 10) Exit EndIf EndFunc ;==>WTSQueryUserToken Func GetRDPSessionID() $Ret = WTSEnumerateSessions($WTS_CURRENT_SERVER_HANDLE, 0, 1, 0, 0) $Offset = 0 For $i = 1 To $Ret[5] $tInfo = DllStructCreate($tagWTS_SESSION_INFO, $Ret[4] + $Offset) $Offset += DllStructGetSize($tInfo) $SessionId = DllStructGetData($tInfo, 'SessionId') $SessionName = DllStructGetData(DllStructCreate('wchar[1024]', DllStructGetData($tInfo, 'WinStationName')), 1) $SessionState = DllStructGetData($tInfo, 'State') If $SessionName = "Console" _ And ($SessionState = $WTSActive Or _ $SessionState = $WTSShadow Or _ $SessionState = $WTSConnectQuery _ ) Then Return $SessionId EndIf Next Return -1 EndFunc ;==>GetRDPSessionID Func WTSGetActiveConsoleSessionId() $Ret = DllCall('Kernel32.dll', 'dword', 'WTSGetActiveConsoleSessionId') Return $Ret[0] EndFunc ;==>WTSGetActiveConsoleSessionId Func WTSEnumerateSessions($hServer, $Reserved, $Version, $ppSessionInfo, $pCount) $Ret = DllCall('wtsapi32.dll', 'int', 'WTSEnumerateSessionsW', _ 'ptr', $hServer, _ 'dword', $Reserved, _ 'dword', $Version, _ 'ptr*', $ppSessionInfo, _ 'dword*', $pCount) Return $Ret EndFunc ;==>WTSEnumerateSessions Func GetModuleFileName($hModule,byref $lpFilename, $nSize) $Ret = DllCall('Kernel32.dll', 'int', 'GetModuleFileNameW', _ 'handle', $hModule, _ 'wstr', 0, _ 'int', $nSize) $lpFilename = $Ret[2] Return $Ret[0] EndFunc #cs BOOL WINAPI CreateProcessAsUser( _In_opt_ HANDLE hToken, _In_opt_ LPCTSTR lpApplicationName, _Inout_opt_ LPTSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCTSTR lpCurrentDirectory, _In_ LPSTARTUPINFO lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation ); #ce Func CreateProcessAsUser($hToken, $lpApplicationName, $lpCommandline, $lpProcessAttributes, $lpThreadAttributes, $bInheritHandles, $dwCreationFlags, $lpEnvironment, $lpCurrentDirectory, $lpStartupInfo, $lpProcessInformation) $ret = DllCall("advapi32.dll", "bool", "CreateProcessAsUser", _ ; W is better "handle", $hToken, _ "ptr", 0, _ "str", $lpCommandline, _ ; wstr for CreateProcessAsUserW "int", $lpProcessAttributes, _ "int", $lpThreadAttributes, _ "bool", $bInheritHandles, _ "dword", $dwCreationFlags, _ "ptr", 0, _ "ptr", 0, _ "ptr", $lpStartupInfo, _ "ptr", $lpProcessInformation) If $ret[0] = 0 Then _MsgBox(16, "proc e "&@error&" "&$hToken, _WinAPI_GetLastErrorMessage()) Return $ret EndFunc ;==>CreateProcessAsUser Func _MsgBox($a, $b, $c, $d = 0) If @UserName <> "SYSTEM" Or $force_gui Then MsgBox($a, $b, $c, $d) Else FileWrite(@ScriptDir & "mb.txt", '"' & $b & '"' & ", " & '"' & $c & '"' & @CRLF) EndIf EndFunc ;==>_MsgBox Func __ArrayDisplay($a, $b = "array") If @UserName <> "SYSTEM" Or $force_gui Then _ArrayDisplay($a, $b) Else $dat = $b & @CRLF For $i = 0 To UBound($a) - 1 $dat &= @TAB & $a[$i] & @CRLF Next FileWrite(@ScriptDir & "arr.txt", $dat) EndIf EndFunc ;==>__ArrayDisplay I dont even know now which version of code is better this or post above. It would be great if someone could help me. edited Link to comment Share on other sites More sharing options...
E1M1 Posted August 28, 2012 Author Share Posted August 28, 2012 (edited) I also tried this: (source: http://forums.codeguru.com/showthread.php?208225-CreateProcess-fails-and-GetLastError-returns-quot-Invalid-access-to-memory-location-quot)MemSet(DllStructGetPtr($StartUPInfo),Chr(0),DllStructGetSize($StartUPInfo)) MemSet(DllStructGetPtr($ProcessInfo),Chr(0),DllStructGetSize($ProcessInfo))but I still get: invalid access to memory locationHere's full code:expandcollapse popup;~ CreateProcessAsUser(hToken,NULL,app_path,NULL,NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,NULL,&StartUPInfo,&ProcessInfo)) #include <winapi.au3> #include <array.au3> #include <security.au3> GUICreate("") GUISetState(@SW_SHOW) $force_gui = true $NULL = 0 $WTS_CURRENT_SERVER_HANDLE = $NULL $WTSActive = 0 $WTSShadow = 1 $WTSConnectQuery = 2 $CREATE_UNICODE_ENVIRONMENT = 0x00000400 $DETACHED_PROCESS = 0x00000008 $MAX_PATH = 260 $PROCESS_ALL_ACCESS = 0x001F0FFF ;~ $TOKEN_ALL_ACCESS = 0xf01ff $ERROR_SUCCESS = 0 Global Const $tagWTS_SESSION_INFO = 'dword SessionId;ptr WinStationName;uint State' ;testing ;~ $s = "" ;~ GetModuleFileName(0,$s,260) ;~ MsgBox(0,0,$s) #cs typedef struct _STARTUPINFO { DWORD cb; 1 LPTSTR lpReserved; 2 LPTSTR lpDesktop; 3 LPTSTR lpTitle; 4 DWORD dwX; 5 DWORD dwY; 6 DWORD dwXSize; 7 DWORD dwYSize; 8 DWORD dwXCountChars; 9 DWORD dwYCountChars; 10 DWORD dwFillAttribute; 11 DWORD dwFlags; 12 WORD wShowWindow; 13 WORD cbReserved2; 14 LPBYTE lpReserved2; 15 HANDLE hStdInput; 16 HANDLE hStdOutput; 17 HANDLE hStdError; 18 } STARTUPINFO, *LPSTARTUPINFO; typedef struct _PROCESS_INFORMATION { HANDLE hProcess; HANDLE hThread; DWORD dwProcessId; DWORD dwThreadId; } PROCESS_INFORMATION, *LPPROCESS_INFORMATION; #ce LaunchProcessWin() Func LaunchProcessWin() $bReturn = False $hToken = 0 $env = 0 $StartUPInfo = DllstructCreate("DWORD;char;char[19];char;DWORD;DWORD;DWORD;DWORD;DWORD;DWORD;DWORD;DWORD;WORD;WORD;BYTE;HANDLE;HANDLE;HANDLE") $ProcessInfo = DllStructCreate("HANDLE;HANDLE;DWORD;DWORD") MemSet(DllStructGetPtr($StartUPInfo),Chr(0),DllStructGetSize($StartUPInfo)) MemSet(DllStructGetPtr($ProcessInfo),Chr(0),DllStructGetSize($ProcessInfo)) DllStructSetData($StartUPInfo, 13, @SW_SHOW) DllStructSetData($StartUPInfo, 3, "Winsta0Winlogon") DllStructSetData($StartUPInfo, 1, DllStructGetSize($StartUPInfo)) $app_path = "" SetTBCPrivileges() $id = WTSGetActiveConsoleSessionId() ;~ _MsgBox(0, 1, $id ) $hToken = WTSQueryUserToken($id) ;~ _MsgBox(0, 2, "abc") CreateEnvironmentBlock($env, $hToken, False) ;~ _MsgBox(0, 2.1, "abc") GetModuleFileName(0,$app_path,$MAX_PATH) _MsgBox(0, 3, DllStructGetData($StartUPInfo,3)) $file = DllStructCreate("char[260]") $lpProcessAttributes=dllstructcreate($tagSECURITY_ATTRIBUTES) $lpThreadAttributes=dllstructcreate($tagSECURITY_ATTRIBUTES) DLLStructSetData($lpThreadAttributes,"Descriptor",0) $ta_size=dllstructgetsize($lpThreadAttributes) DLLStructSetData($lpThreadAttributes,"Length",$ta_size) DLLStructSetData($lpProcessAttributes,"Descriptor",0) $pa_size=dllstructgetsize($lpProcessAttributes) DLLStructSetData($lpProcessAttributes,"Length",$pa_size) CreateProcessAsUser($hToken, "", $app_path, DllStructGetPtr($lpProcessAttributes), DllStructGetPtr($lpThreadAttributes), 0, $CREATE_UNICODE_ENVIRONMENT + $DETACHED_PROCESS, $env,"", DllStructGetPtr($StartUPInfo), DllStructGetPtr($ProcessInfo)) _MsgBox(0, 4, "abc") ;CreateProcessAsUser(hToken,NULL,app_path,NULL,NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,NULL,&StartUPInfo,&ProcessInfo)// C++ _MsgBox(0, $env, DllStructGetData($ProcessInfo, 3)) EndFunc ;==>LaunchProcessWin Func MemSet($pDest, $nChar, $nCount) DllCall("msvcrt.dll", "ptr:cdecl", "memset", "ptr", $pDest, "int", $nChar, "int", $nCount) If @error Then Return SetError(1,0,False) Return True EndFunc ;~ CreateProcessAsUser(hToken,$NULL,app_path,$NULL,$NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,$NULL,&StartUPInfo,&ProcessInfo)) Func GetWinLogonHandle() $bResult = False; $hProcess = 0; $hAccessToken = $NULL; $hTokenThis = $NULL; $dwID_session = 0; $dwID = 0 If WTSGetActiveConsoleSessionId() > 0 Then $dwID_session = WTSGetActiveConsoleSessionId() EndIf ;W2k handler needed ;following is for xp and up ;~ $dwID EndFunc ;==>GetWinLogonHandle Func CreateEnvironmentBlock(ByRef $lpEnvironment, $hToken, $bInherit) $struct = DllStructCreate("ptr") $Ret = DllCall('Userenv.dll', 'bool', 'CreateEnvironmentBlock', _ 'ptr', DllStructGetPtr($struct), _ 'HANDLE', $hToken, _ 'bool', $bInherit) $lpEnvironment = DllStructGetData($struct, 1) Return $Ret[0] EndFunc ;==>CreateEnvironmentBlock Func WTSQueryUserToken($SessionId) $struct = DllStructCreate("HANDLE") $Ret = DllCall('wtsapi32.dll', 'bool', 'WTSQueryUserToken', _ 'ULONG', $SessionId, _ 'ptr*', DllStructGetPtr($struct)) If $Ret[0] <> 0 Then Return $Ret[2] Else _MsgBox(16, "Error (you must run me as system service)", _WinAPI_GetLastErrorMessage(), 10) Exit EndIf EndFunc ;==>WTSQueryUserToken Func GetRDPSessionID() $Ret = WTSEnumerateSessions($WTS_CURRENT_SERVER_HANDLE, 0, 1, 0, 0) $Offset = 0 For $i = 1 To $Ret[5] $tInfo = DllStructCreate($tagWTS_SESSION_INFO, $Ret[4] + $Offset) $Offset += DllStructGetSize($tInfo) $SessionId = DllStructGetData($tInfo, 'SessionId') $SessionName = DllStructGetData(DllStructCreate('wchar[1024]', DllStructGetData($tInfo, 'WinStationName')), 1) $SessionState = DllStructGetData($tInfo, 'State') MsgBox(0,"sid: "&$SessionId,$SessionState) If $SessionName <> "Console" _ And ($SessionState = $WTSActive Or _ $SessionState = $WTSShadow Or _ $SessionState = $WTSConnectQuery _ ) Then Return $SessionId EndIf Next Return -1 EndFunc ;==>GetRDPSessionID Func WTSGetActiveConsoleSessionId() $Ret = DllCall('Kernel32.dll', 'dword', 'WTSGetActiveConsoleSessionId') Return $Ret[0] EndFunc ;==>WTSGetActiveConsoleSessionId Func WTSEnumerateSessions($hServer, $Reserved, $Version, $ppSessionInfo, $pCount) $Ret = DllCall('wtsapi32.dll', 'int', 'WTSEnumerateSessionsW', _ 'ptr', $hServer, _ 'dword', $Reserved, _ 'dword', $Version, _ 'ptr*', $ppSessionInfo, _ 'dword*', $pCount) Return $Ret EndFunc ;==>WTSEnumerateSessions Func GetModuleFileName($hModule,byref $lpFilename, $nSize) $Ret = DllCall('Kernel32.dll', 'int', 'GetModuleFileNameW', _ 'handle', $hModule, _ 'wstr', 0, _ 'int', $nSize) $lpFilename = $Ret[2] Return $Ret[0] EndFunc #cs BOOL WINAPI CreateProcessAsUser( _In_opt_ HANDLE hToken, _In_opt_ LPCTSTR lpApplicationName, _Inout_opt_ LPTSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCTSTR lpCurrentDirectory, _In_ LPSTARTUPINFO lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation ); #ce Func CreateProcessAsUser($hToken, $lpApplicationName, $lpCommandline, $lpProcessAttributes, $lpThreadAttributes, $bInheritHandles, $dwCreationFlags, $lpEnvironment, $lpCurrentDirectory, $lpStartupInfo, $lpProcessInformation) $ret = DllCall("advapi32.dll", "bool", "CreateProcessAsUser", _ ; W is better "handle", $hToken, _ "ptr", 0, _ "str", $lpCommandline, _ ; wstr for CreateProcessAsUserW "int", $lpProcessAttributes, _ "int", $lpThreadAttributes, _ "bool", $bInheritHandles, _ "dword", $dwCreationFlags, _ "ptr", 0, _ "ptr", 0, _ "ptr", $lpStartupInfo, _ "ptr", $lpProcessInformation) If $ret[0] = 0 Then _MsgBox(16, "proc e "&@error&" "&$hToken, _WinAPI_GetLastErrorMessage()) Return $ret EndFunc ;==>CreateProcessAsUser #cs BOOL SetTBCPrivileges(VOID) { DWORD dwPID; HANDLE hProcess; HANDLE hToken; LUID Luid; TOKEN_PRIVILEGES tpDebug; dwPID = GetCurrentProcessId(); if ((hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) == NULL) return FALSE; if (OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken) == 0) return FALSE; if ((LookupPrivilegeValue(NULL, SE_TCB_NAME, &Luid)) == 0) return FALSE; tpDebug.PrivilegeCount = 1; tpDebug.Privileges[0].Luid = Luid; tpDebug.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if ((AdjustTokenPrivileges(hToken, FALSE, &tpDebug, sizeof(tpDebug), NULL, NULL)) == 0) return FALSE; if (GetLastError() != ERROR_SUCCESS) return FALSE; CloseHandle(hToken); CloseHandle(hProcess); return TRUE; } #ce Func SetTBCPrivileges() $dwPID = @AutoItPID $hToken = 0 $hProcess = 0 $tpDebug = DllStructCreate($tagTOKEN_PRIVILEGES) $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS,False,$dwPID) If not $hProcess Then return False If not _WinAPI_OpenProcessToken($hProcess,$TOKEN_ALL_ACCESS,$hToken) Then return False $LUID = _Security__LookupPrivilegeValue("", $SE_DEBUG_NAME) if $LUID == 0 Then Return False DllStructSetData($tpDebug,"Count",1) DllStructSetData($tpDebug,"LUID",$LUID,1) DllStructSetData($tpDebug,"Attributes",$SE_PRIVILEGE_ENABLED,1) if _Security__AdjustTokenPrivileges($hToken,False,DllStructGetPtr($tpDebug),DllStructGetSize($tpDebug),$NULL,$NULL) = False Then Return false if _WinAPI_GetLastError() <> $ERROR_SUCCESS Then Return False _WinAPI_CloseHandle($hToken); _WinAPI_CloseHandle($hProcess); Return true EndFunc Func _WinAPI_OpenProcessToken($pHandle, $iAccess, byref $hToken) 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) $hToken = $aResult[3] Return $aResult[0] EndFunc ;Not all privileges or groups referenced are assigned to the caller. Func _MsgBox($a, $b, $c, $d = 0) If @UserName <> "SYSTEM" Or $force_gui Then MsgBox($a, $b, $c, $d) Else FileWrite(@ScriptDir & "mb.txt", '"' & $b & '"' & ", " & '"' & $c & '"' & @CRLF) EndIf EndFunc ;==>_MsgBox Func __ArrayDisplay($a, $b = "array") If @UserName <> "SYSTEM" Or $force_gui Then _ArrayDisplay($a, $b) Else $dat = $b & @CRLF For $i = 0 To UBound($a) - 1 $dat &= @TAB & $a[$i] & @CRLF Next FileWrite(@ScriptDir & "arr.txt", $dat) EndIf EndFunc ;==>__ArrayDisplayE: I was using struct wrong. Edited August 29, 2012 by E1M1 edited Link to comment Share on other sites More sharing options...
bitboy Posted October 12, 2013 Share Posted October 12, 2013 Hi E1M1, did you find a solution for the invalid memory error? 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