Jump to content

How to specify a parent process when creating a process


Go to solution Solved by Rurorita,

Recommended Posts

here is my test code,but it doesn't work:

$s =  _CreatProcess(@ComSpec)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $s = ' & $s & @CRLF & '>Error code: ' & @error & '    Extended code: ' & @extended & ' (0x' & Hex(@extended)  & ')    SystemTime: ' & @hour & ':' & @min & ':' & @sec & @CRLF) ;### Debug Console

Func _CreatProcess($sCommandLine)
    Local Const $PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000  
    Local Const $EXTENDED_STARTUPINFO_PRESENT = 0x00080000

    Local $hTargetProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, ProcessExists('explorer.exe'))
    
    Local $hTargetProcessToken = _Security__OpenProcessToken($hTargetProcess, BitOR($TOKEN_QUERY, $TOKEN_DUPLICATE))
    Local $hTokDuplicate = _Security__DuplicateTokenEx($hTargetProcessToken, $TOKEN_ALL_ACCESS, $SECURITYIDENTIFICATION, $TOKENPRIMARY)
    Local $tStartupInfo = DllStructCreate($tagSTARTUPINFO & ';ptr lpAttributeList') ;maybe error is here
    DllStructSetData($tStartupInfo, "Size", DllStructGetSize($tStartupInfo))
    Local $iResult = DllCall("Kernel32.dll", "int", "InitializeProcThreadAttributeList", 'ptr', NULL, "dword", 1, "dword" , 0, "ulong_ptr*", 0)
    Local $pLIST = _HeapAlloc($iResult[4])
    $iResult = DllCall("Kernel32.dll", "int", "InitializeProcThreadAttributeList", 'ptr', $pLIST, "dword", 1, "dword" , 0, "ulong_ptr*", $iResult[4])   
    Local $iResult = DllCall("Kernel32.dll", "int", "UpdateProcThreadAttribute", 'ptr', $pLIST, "dword", 0, "dword_ptr" , $PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, "HANDLE", $hTargetProcess, "ULONG_PTR", BinaryLen($hTargetProcess), "ptr", Null, "dword", Null )   
    DllStructSetData($tStartupInfo, "lpAttributeList", $pLIST)
    Local $tProcessInfo = DllStructCreate($tagPROCESS_INFORMATION)
    DllStructSetData($tProcessInfo, "Size", DllStructGetSize($tProcessInfo))
    
;~  Local $dwCreationFlags = BitOR($NORMAL_PRIORITY_CLASS, $CREATE_NEW_CONSOLE)
    Local $dwCreationFlags = $EXTENDED_STARTUPINFO_PRESENT
    _WinAPI_CloseHandle($hTargetProcess)    
    _WinAPI_CloseHandle($hTargetProcessToken)   
    
    Local $iResult = DllCall("advapi32.dll", "bool", "CreateProcessWithTokenW", _ ;~            "ptr", $pEnvironment, _  ;$lpEnvironment
            "handle", $hTokDuplicate, _  ;hToken
            "dword", 1, _ ;dwLogonFlags
            "ptr", 0, _ ;lpApplicationName, _
            "wstr", StringFormat("%s", $sCommandLine), _ ; wstr for CreateProcessWithTokenW
            "dword", $dwCreationFlags, _    ;$dwCreationFlags       
            "ptr", Null, _   ;$lpEnvironment
            "wstr", @SystemDir, _        ;$lpCurrentDirectory
            "ptr", DllStructGetPtr($tStartupInfo), _     ;$lpStartupInfo
            "ptr", DllStructGetPtr($tProcessInfo)) ;$lpProcessInformation
    If $iResult[0] Then
        _WinAPI_CloseHandle(DllStructGetData($tProcessInfo, "hProcess"))
        _WinAPI_CloseHandle(DllStructGetData($tProcessInfo, "hThread"))

        Return SetError(0, 0, DllStructGetData($tProcessInfo, "ProcessID"))
    Else
        Local $iError = _WinAPI_GetLastError()
        Local $errmsg = _WinAPI_GetLastErrorMessage()
        _WinAPI_CloseHandle(DllStructGetData($tProcessInfo, "hProcess"))
        _WinAPI_CloseHandle(DllStructGetData($tProcessInfo, "hThread"))
        Return SetError(1, $iError, $errmsg)
    EndIf
EndFunc

Func _HeapFree(ByRef $pMem)
    If $pMem < 1 Then Return SetError(87, 0, False)

    Local $iResult, $hHeap = _GetProcessHeap()
    $iResult = DllCall("Kernel32.dll", "int", "HeapFree", "hWnd", $hHeap, _
            "dword", 0, "ptr", $pMem)
    If $iResult[0] Then $pMem = Ptr(0)
    Return $iResult[0] <> 0
EndFunc   ;==>_HeapFree

Func _HeapAlloc($iSize, $iAllocOption = 8)
    If $iSize < 1 Then Return 0

    Local $pMem, $hHeap = _GetProcessHeap()
    $pMem = DllCall("Kernel32.dll", "ptr", "HeapAlloc", "hWnd", $hHeap, _
            "dword", $iAllocOption, "dword", $iSize)
    Return $pMem[0]
EndFunc ;==>_HeapAlloc

Func _GetProcessHeap()
    Local $hHeap = DllCall("Kernel32.dll", "hWnd", "GetProcessHeap")
    Return $hHeap[0]
EndFunc   ;==>_GetProcessHeap

thanks a lot

Edited by tubaba
Link to post
Share on other sites
  • Developers
26 minutes ago, tubaba said:

but it doesn't work

I am sure you can do better than this explaining your issue with the code! ;) 

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to post
Share on other sites
  • Solution

So you want to spawn the cmd below the explorer.exe. Like if the explorer.exe itself had created the cmd process. No clue how that would work code wise, but why would you want that to happen anyway? just curious.

Link to post
Share on other sites

maybe the StartupInfoEx struct like bellow

struct _ProThreadAttrItem {
    DWORD dwFlags;
    DWORD cbBufSize;
    HANDLE* pHandleBuf;
};

struct _ProcThreadAttrHeader {
    DWORD dwMark;
    DWORD dwTotalNum;
    DWORD dwCurNum;
    DWORD dwUnknown;
    _ProThreadAttrItem* lpLast;
};

struct _StartupInfoExW {
    STARTUPINFOW si;
    _ProcThreadAttrHeader* pEx;
};

Edited by tubaba
Link to post
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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...