Jump to content

[Solved]What's wrong with CreateProcessAsUser - I keep getting "The parameter is incorrect"


Recommended Posts

Posted (edited)

Hello

I can't seem to find solution for my CreateProcessAsUser

problem. 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.aspx

;~ 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 ;==>__ArrayDisplay

Thanks in advance

Edited by E1M1

edited

Posted

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.

Posted (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 by E1M1

edited

Posted

After some coding I get this: Invalid access to memory location.

;~ 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

Posted (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 location

Here's full code:

;~ 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 ;==>__ArrayDisplay

E: I was using struct wrong.

Edited by E1M1

edited

  • 1 year later...

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...