Jump to content

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


E1M1
 Share

Recommended Posts

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

Link to comment
Share on other sites

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

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

  • 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
 Share

  • Recently Browsing   0 members

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