Jump to content

CreateProcessAsUser DLL Call


Recommended Posts

Trying to get CreateProcessAsUser to work with AutoIt. Have it working with C but can't seem to figure-out the right variable types to use in AutoIt. Presently the call doesn't throw any exceptions and @error=0, but it doesn't launch the process either.

#include <StructureConstants.au3> (3.2.6.1)

$lpApplicationName=""
$lpCommandline=$thisProcess
$lpProcessAttributes=dllstructcreate($tagSECURITY_ATTRIBUTES)
$lpThreadAttributes=dllstructcreate($tagSECURITY_ATTRIBUTES)
$bInheritHandles=FALSE
$dwCreationFlags=0x0
$lpEnvironment=""
$lpCurrentDirectory=""
$si=dllstructcreate($tagSTARTUPINFO)
$pi=dllstructcreate($tagPROCESS_INFORMATION)
DLLStructSetData($lpThreadAttributes,"Descriptor","")
$ta_size=dllstructgetsize($lpThreadAttributes)
DLLStructSetData($lpThreadAttributes,"Length",$ta_size)
DLLStructSetData($lpProcessAttributes,"Descriptor","")
$pa_size=dllstructgetsize($lpProcessAttributes)
DLLStructSetData($lpProcessAttributes,"Length",$pa_size)
DLLStructSetData($si,"lpDesktop","winsta0\default")
$pi_size=dllstructgetsize($pi)
$si_size=dllstructgetsize($si)
DLLStructSetData($pi,"Size",$pi_size)
DLLStructSetData($si,"Size",$si_size)


$a_PCall = DllCall("advapi32.dll", "int", "CreateProcessAsUser", _
        "handle", $hToken, _
        "str",$lpApplicationName, _
        "str",$lpCommandline, _
        "ptr",dllstructgetptr($lpProcessAttributes), _
        "ptr",dllstructgetptr($lpThreadAttributes), _
        "bool",$bInheritHandles, _
        "dword",$dwCreationFlags, _
        "int_ptr",$lpEnvironment, _
        "str",$lpCurrentDirectory, _
        "ptr", dllstructgetptr($si), _
        "ptr", dllstructgetptr($pi))

If I test with all of the params set to be null pointers except for the token, commandline and $si/$pi, then it does work. Some C writeups suggest this approach is OK, however in my case I need to set certain parameters.

Any advice welcome.

Edited by Anteaus
Link to comment
Share on other sites

Here's a self-contained function, makes it easier to test:

Uses 3.3.6.1 compiler.

#include <StructureConstants.au3>

SaferLaunchProcess("cmd.exe")
exit

func SaferLaunchProcess($thisProcess)

local $SAFER_LEVELID_NORMALUSER = 0x20000
local $SAFER_SCOPEID_USER = 2
local $SAFER_LEVEL_OPEN = 1


;Open handle
$a_iCall = DllCall("advapi32.dll", "int", "SaferCreateLevel", _
        "dword", $SAFER_SCOPEID_USER, _
        "dword", $SAFER_LEVELID_NORMALUSER, _
        "dword", $SAFER_LEVEL_OPEN, _
        "hwnd*", 0, _
        "ptr", 0)

If @error Or Not $a_iCall[0] Then
    msgbox(0,"Error","Failure opening handle occured!")
EndIf

$hHandle = $a_iCall[4]

$a_LCall = DllCall("advapi32.dll", "int", "SaferComputeTokenFromLevel", _
        "dword", $hHandle, _
        "ptr",0, _
        "hwnd*",0, _
        "ptr",0, _
        "ptr",0) 

If @error Or Not $a_iCall[0] Then
    msgbox(0,"Error","Failure computing Token occured")
    return 0
EndIf

$hToken=$a_LCall[3]
       
$si=dllstructcreate($tagSTARTUPINFO)

$pi=dllstructcreate($tagPROCESS_INFORMATION)

$pi_size=dllstructgetsize($pi)
$si_size=dllstructgetsize($si)
$si_lpDesktop=""
DLLStructSetData($pi,"Size",$pi_size)
DLLStructSetData($si,"Size",$si_size)
$console="0x3"

$a_PCall = DllCall("advapi32.dll", "int", "CreateProcessAsUser", _
        "dword", $hToken, _
        "ptr",0, _
        "str",$thisProcess, _
        "ptr","", _
        "ptr","", _
        "ptr",0, _
        "str*",$console, _
        "ptr","", _
        "ptr","", _
        "ptr", dllstructgetptr($si), _
        "ptr", dllstructgetptr($pi))
         
      $dllerr=@error

if $a_Pcall[0]>0 then
 $pHandle=$a_Pcall[1]
else
 $pHandle=0
endif

;Close handle
$a_iCall = DllCall("advapi32.dll", "int", "SaferCloseLevel", _
        "hwnd", $hHandle)

$pi=""
$si=""

return $pHandle
endfunc

Section in-question is:

$a_PCall = DllCall("advapi32.dll", "int", "CreateProcessAsUser", _
        "dword", $hToken, _
        "ptr",0, _
        "str",$thisProcess, _
        "ptr","", _
        "ptr","", _
        "ptr",0, _
        "str*",$console, _
        "ptr","", _
        "ptr","", _
        "ptr", dllstructgetptr($si), _
        "ptr", dllstructgetptr($pi))

..and basically this is wrong in many respects but for some reason it works, whereas the attempt at correct coding does not.

Link to comment
Share on other sites

When using the DLLCALL 'CreateProcessAsUserW' the call should look like this:

$aResult = DllCall("advapi32.dll", "int", "CreateProcessAsUserW", "ptr", $hToken, "ptr", $pAppName, "wstr", $sCommand, "ptr", $pSecurity, "ptr", $pThread, _
            "int", $fInherit, "dword", $iFlags, "ptr", $pEnviron, "wstr", $sDir, "ptr", $pStartupInfo, "ptr", $pProcess)

hope this helps

Sundance

Edited by Sundance
Link to comment
Share on other sites

Call like this:

DllCall("advapi32.dll", "bool", "CreateProcessAsUser", _ ; W is better
        "handle", $hToken, _
        "ptr", 0, _ ; you don't need this
        "str", $lpCommandline, _ ; wstr for CreateProcessAsUserW
        "ptr", DllStructGetPtr($lpProcessAttributes), _
        "ptr", DllStructGetPtr($lpThreadAttributes), _
        "bool", $bInheritHandles, _
        "dword", $dwCreationFlags, _
        "ptr", 0, _ ; you don't need this
        "ptr", 0, _ ; you don't need this
        "ptr", DllStructGetPtr($si), _
        "ptr", DllStructGetPtr($pi))

Btw, you should close thread an process handles from PROCESS_INFORMATION before returning from the function.

edit: and if "ptr" as type is used then it's more correct to use 0 for NULL (as opposed to ""). You should also check structures you use. Seems you are overdoing on some. As a matter of fact don't set any data to STARTUPINFO nor PROCESS_INFORMATION. They are meant to be filled by CreateProcessAsUser function.

Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

$aResult = DllCall("advapi32.dll", "int", "CreateProcessAsUserW", "ptr", $hToken, "ptr", $pAppName, "wstr", $sCommand, "ptr", $pSecurity, "ptr", $pThread, _
            "int", $fInherit, "dword", $iFlags, "ptr", $pEnviron, "wstr", $sDir, "ptr", $pStartupInfo, "ptr", $pProcess)

Done some testing, and it seems that if you use the CreateProcessAsUserW version, then you use wstr strings. Fair enough. Other than that, the unicode version also won't work unless all parameters between $sCommand and $pStartupInfo are replaced with null ptr's. At least, I can't get it to work with the variable types listed here. Am I missing something? Probably, but question is.. what? Edited by Anteaus
Link to comment
Share on other sites

Call like this:

DllCall("advapi32.dll", "bool", "CreateProcessAsUser", _ ; W is better
        "handle", $hToken, _
        "ptr", 0, _ ; you don't need this
        "str", $lpCommandline, _ ; wstr for CreateProcessAsUserW
        "ptr", DllStructGetPtr($lpProcessAttributes), _
        "ptr", DllStructGetPtr($lpThreadAttributes), _
        "bool", $bInheritHandles, _
        "dword", $dwCreationFlags, _
        "ptr", 0, _ ; you don't need this
        "ptr", 0, _ ; you don't need this
        "ptr", DllStructGetPtr($si), _
        "ptr", DllStructGetPtr($pi))

Thanks, that's much more like it. It now works with the specified data types. The final hurdle is getting it to recognise the $dwCreationFlags values, which it seems to be ignoring. About time I packed-up for the night anyway, will continue tomorrow.
Link to comment
Share on other sites

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