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!
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
STARTF_USESHOWWINDOW = 0x00000001
SW_HIDE = 0
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)
def boolcheck(result, func, args):
if not result:
raise WinError(get_last_error())
return None
kernel32 = WinDLL('kernel32', use_last_error=True)
CreateProcess = kernel32.CreateProcessW
CreateProcess.argtypes = (LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES,
BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION)
CreateProcess.restype = BOOL
CreateProcess.errcheck = boolcheck
def load(path_to_exe):
creation_flags = DEBUG_PROCESS
startupinfo = STARTUPINFOW()
processinfo = PROCESS_INFORMATION()
startupinfo.dwFlags = STARTF_USESHOWWINDOW
startupinfo.wShowWindow = SW_HIDE
startupinfo.cb = sizeof(startupinfo)
CreateProcess(path_to_exe, None, None, None, False, creation_flags, None, None, byref(startupinfo), byref(processinfo))
print('[*] Process launched')
print('[*] PID: {}'.format(processinfo.dwProcessId))
load(r'C:\windows\system32\calc.exe')
Note that the OP used SW_HIDE
and DEBUG_PROCESS
which will not show the process window and also terminate the debugged process when the Python process exits, so only the success message will be visible. Pause at the end of the script with some input()
and the process will be viewable in Task Manager.