why python: kernel32.CreateProcessA() get error 0x000003e6

1

Here is my code:

from ctypes import *
WORD = c_ushort
DWORD = c_ulong
LPBYTE = POINTER(c_ubyte)
LPTSTR = POINTER(c_char)
HANDLE = c_void_p
DEBUG_PROCESS = 0x00000001
CREATE_NEW_CONSOLE = 0x00000010
class STARTUPINFO(Structure):
    _fields_ = [
    ("cb", DWORD),
    ("lpReserved", LPTSTR),
    ("lpDesktop", LPTSTR),
    ("lpTitle", LPTSTR),
    ("dwX", DWORD),
    ("dwY", DWORD),
    ("dwXSize", DWORD),
    ("dwYSize", DWORD),
    ("dwXCountChars", DWORD),
    ("dwYCountChars", DWORD),
    ("dwFillAttribute",DWORD),
    ("dwFlags", DWORD),
    ("wShowWindow", WORD),
    ("cbReserved2", WORD),
    ("lpReserved2", LPBYTE),
    ("hStdInput", HANDLE),
    ("hStdOutput", HANDLE),
    ("hStdError", HANDLE),
    ]
class PROCESS_INFORMATION(Structure):
    _fields_ = [
    ("hProcess", HANDLE),
    ("hThread", HANDLE),
    ("dwProcessId", DWORD),
    ("dwThreadId", DWORD),
    ]


kernel32 = windll.kernel32
class debugger():
    def __init__(self):
        pass

    def load(path_to_exe):
        creation_flags = DEBUG_PROCESS
        startupinfo = STARTUPINFO()
        processinfo = PROCESS_INFORMATION()
        startupinfo.dwFlags = 0x1
        startupinfo.wShowWindow = 0x0
        startupinfo.cb = sizeof(startupinfo)
        if kernel32.CreateProcessA(path_to_exe,None,None,None,None,creation_flags,None,None,byref(startupinfo),byref(processinfo)):
            print("[*] Process launched")
            print("[*] PID: %d" % (PROCESS_INFORMATION.dwProcessId))
        else:
            print("[*] Error: 0x%08x." % (kernel32.GetLastError()))

debugger.load("C:\\WINDOWS\\system32\\calc.exe")

I'm actually following along Gray hat python right now, and I'm converting this code to python2.7 as I read it.

Whenever I run it, it goes to the error: [*] Error: 0x000003e6.

but when my friend try this code in his computer, he can get: []We have successfully launched the process! []PID: 1208

and both our systems are 64-bit windows7.

Any help would be much appreciated!

python
memory
ctypes
asked on Stack Overflow Nov 4, 2018 by ttfy • edited Nov 5, 2018 by Mark Tolonen

1 Answer

0

Do you both have 64-bit Python installed? .argtypes and .restype should be set on your function or ctypes defaults to passing 32-bit parameters. On 64-bit Python that truncates your byref values, which are 64-bit pointers.

As a reference, here's a fully tested version that works on Python 2 and 3, both 32- and 64-bit:

from __future__ import print_function,unicode_literals

from ctypes import *
from ctypes.wintypes import BYTE,WORD,DWORD,LPWSTR,LPCWSTR,HANDLE,LPVOID,BOOL

LPBYTE = POINTER(BYTE)

DEBUG_PROCESS = 0x00000001
CREATE_NEW_CONSOLE = 0x00000010

class STARTUPINFOW(Structure):
    _fields_ = [('cb', DWORD),
                ('lpReserved', LPWSTR),
                ('lpDesktop', LPWSTR),
                ('lpTitle', LPWSTR),
                ('dwX', DWORD),
                ('dwY', DWORD),
                ('dwXSize', DWORD),
                ('dwYSize', DWORD),
                ('dwXCountChars', DWORD),
                ('dwYCountChars', DWORD),
                ('dwFillAttribute',DWORD),
                ('dwFlags', DWORD),
                ('wShowWindow', WORD),
                ('cbReserved2', WORD),
                ('lpReserved2', LPBYTE),
                ('hStdInput', HANDLE),
                ('hStdOutput', HANDLE),
                ('hStdError', HANDLE)]

class PROCESS_INFORMATION(Structure):
    _fields_ = [('hProcess', HANDLE),
                ('hThread', HANDLE),
                ('dwProcessId', DWORD),
                ('dwThreadId', DWORD)]

class SECURITY_ATTRIBUTES(Structure):
    _fields_ = [('nLength', DWORD),
                ('lpSecurityDescriptor', LPVOID),
                ('bInheritHandle', BOOL)]

LPSECURITY_ATTRIBUTES = POINTER(SECURITY_ATTRIBUTES)
LPSTARTUPINFOW = POINTER(STARTUPINFOW)
LPPROCESS_INFORMATION = POINTER(PROCESS_INFORMATION)

kernel32 = WinDLL('kernel32',use_last_error=True)
kernel32.CreateProcessW.argtypes = (LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,
                                    BOOL,DWORD,LPVOID,LPCWSTR,LPSTARTUPINFOW,LPPROCESS_INFORMATION)
kernel32.restype = BOOL

def load(path_to_exe):
    creation_flags = DEBUG_PROCESS
    startupinfo = STARTUPINFOW()
    processinfo = PROCESS_INFORMATION()
    startupinfo.dwFlags = 0x1
    startupinfo.wShowWindow = 0x0
    startupinfo.cb = sizeof(startupinfo)
    if kernel32.CreateProcessW(path_to_exe,None,None,None,False,creation_flags,None,None,byref(startupinfo),byref(processinfo)):
        print('[*] Process launched')
        print('[*] PID: {}'.format(processinfo.dwProcessId))
    else:
        print('[*] Error: 0x{:08x}.'.format(get_last_error()))

load(r'C:\WINDOWS\System32\calc.exe')
answered on Stack Overflow Nov 5, 2018 by Mark Tolonen • edited Nov 5, 2018 by Mark Tolonen

User contributions licensed under CC BY-SA 3.0