Skip to content Skip to sidebar Skip to footer

Python Crashes After Call To Createprocesswithlogonw

Using the code found here one can successfully launch an application as an alternate user. However, after the application is launched Python crashes, and Windows displays 'python.e

Solution 1:

Using a 32-bit DWORD for a HANDLE, or any other pointer type, is incorrect on 64-bit Windows. The ctypes.wintypes module defines types that work on both 32-bit and 64-bit Windows. If it lacks a particular type, you can probably find the definition in Windows Data Types.

Setting _pack_ = 1 incorrectly uses 1-byte alignment instead of padding with native alignment. Also, STARTUPINFOW should use LPWSTR instead of LPSTR.

Try this rewrite:

import ctypes
from ctypes import wintypes

kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
advapi32 = ctypes.WinDLL('advapi32', use_last_error=True)

CREATE_NEW_CONSOLE         = 0x00000010
CREATE_NO_WINDOW           = 0x08000000
DETACHED_PROCESS           = 0x00000008
CREATE_NEW_PROCESS_GROUP   = 0x00000200
CREATE_UNICODE_ENVIRONMENT = 0x00000400ifnothasattr(wintypes, 'LPBYTE'):
    wintypes.LPBYTE = ctypes.POINTER(wintypes.BYTE)

classHANDLE(wintypes.HANDLE):

    defdetach(self):
        handle, self.value = self.value, Nonereturn wintypes.HANDLE(handle)

    defclose(self, CloseHandle=kernel32.CloseHandle):
        if self:
            CloseHandle(self.detach())

    def__del__(self):
        self.close()

classPROCESS_INFORMATION(ctypes.Structure):
    """http://msdn.microsoft.com/en-us/library/ms684873"""
    _fields_ = (('hProcess',    HANDLE),
                ('hThread',     HANDLE),
                ('dwProcessId', wintypes.DWORD),
                ('dwThreadId',  wintypes.DWORD))

LPPROCESS_INFORMATION = ctypes.POINTER(PROCESS_INFORMATION)

classSTARTUPINFOW(ctypes.Structure):
    """http://msdn.microsoft.com/en-us/library/ms686331"""
    _fields_ = (('cb',              wintypes.DWORD),
                ('lpReserved',      wintypes.LPWSTR),
                ('lpDesktop',       wintypes.LPWSTR),
                ('lpTitle',         wintypes.LPWSTR),
                ('dwX',             wintypes.DWORD),
                ('dwY',             wintypes.DWORD),
                ('dwXSize',         wintypes.DWORD),
                ('dwYSize',         wintypes.DWORD),
                ('dwXCountChars',   wintypes.DWORD),
                ('dwYCountChars',   wintypes.DWORD),
                ('dwFillAttribute', wintypes.DWORD),
                ('dwFlags',         wintypes.DWORD),
                ('wShowWindow',     wintypes.WORD),
                ('cbReserved2',     wintypes.WORD),
                ('lpReserved2',     wintypes.LPBYTE),
                ('hStdInput',       wintypes.HANDLE),
                ('hStdOutput',      wintypes.HANDLE),
                ('hStdError',       wintypes.HANDLE))

    def__init__(self, *args, **kwds):
        self.cb = ctypes.sizeof(self)
        super(STARTUPINFOW, self).__init__(*args, **kwds)

LPSTARTUPINFOW = ctypes.POINTER(STARTUPINFOW)

def_check_bool(result, func, args):
    ifnot result:
        raise ctypes.WinError(ctypes.get_last_error())
    return args

# http://msdn.microsoft.com/en-us/library/ms682431
advapi32.CreateProcessWithLogonW.errcheck = _check_bool
advapi32.CreateProcessWithLogonW.argtypes = (
    wintypes.LPCWSTR,      # lpUsername
    wintypes.LPCWSTR,      # lpDomain
    wintypes.LPCWSTR,      # lpPassword
    wintypes.DWORD,        # dwLogonFlags
    wintypes.LPCWSTR,      # lpApplicationName
    wintypes.LPWSTR,       # lpCommandLine (inout)
    wintypes.DWORD,        # dwCreationFlags
    wintypes.LPCWSTR,      # lpEnvironment  (force Unicode)
    wintypes.LPCWSTR,      # lpCurrentDirectory
    LPSTARTUPINFOW,        # lpStartupInfo
    LPPROCESS_INFORMATION) # lpProcessInfo (out)

defCreateProcessWithLogonW(username, password, domain=None, logonflags=0,
                            executable=None, commandline=None, creationflags=0,
                            env=None, cwd=None, startupinfo=None):
    if commandline isnotNone:
        commandline = ctypes.create_unicode_buffer(commandline)
    creationflags |= CREATE_UNICODE_ENVIRONMENT
    if startupinfo isNone:
        startupinfo = STARTUPINFOW()
    pi = PROCESS_INFORMATION()
    advapi32.CreateProcessWithLogonW(username, domain, password, logonflags,
                                     executable, commandline, creationflags,
                                     env, cwd, ctypes.byref(startupinfo),
                                     ctypes.byref(pi))
    return pi.hProcess, pi.hThread, pi.dwProcessId, pi.dwThreadId

if__name__== '__main__':
    import os
    importgetpassusername= input('username: ')
    password = getpass.getpass('password: ')
    exe = os.environ['ComSpec']
    cflags = CREATE_NEW_CONSOLE
    hProcess, hThread, pid, tid = CreateProcessWithLogonW(
            username, password, executable=exe, creationflags=cflags)
    print('PID: %d' % pid)

Post a Comment for "Python Crashes After Call To Createprocesswithlogonw"