例子代码:
调试器需要具备两种基本能力:打开执行程序作为自身子进程运行、附加一个现有进程的能力
第一种使用CreateProcessA函数,重要的参数是:lpApplicationName(可执行文件所在路径)、lpCommandLine(命令行参数)、dwCreationFlags(可调式设置)、lpStartupInfo(结构体STARINFO)和lpProcessInformation(结构体PROCESS_INFORMATION),其余参数可以设置为NULL。
my_debugger_defines.py
#__author__ = 'zt' #coding=utf-8 from ctypes import * #为ctype变量创建符合匈牙利命名风格的匿名,这样可以使代码更接近Win32的风格 WORD = c_ushort DWORD = c_ulong LPBYTE = POINTER(c_ubyte) LPTSTR = POINTER(c_char) HANDLE = c_void_p #常值定义 DEBUG_RPOCESS = 0x00000001 CREATE_NEW_CONSOLE = 0x00000010 #定义函数CreateProcessA()所需的结构体 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), ]my_debugger.py
#__author__ = 'zt' #coding=utf-8 from ctypes import * from my_debugger_defines import * kernel32 = windll.kernel32 class debugger(): def __init__(self): pass def load(self,path_to_exe): #参数dwCreationFlags中的标志位控制着进程的创建方式。你若希望新创建的进程独占一个新的控制台窗口,而不是与父进程 #共用同一个控制台,你可以加上标志位CREATE_NEW_CONSOLE creation_flags = DEBUG_PROCESS creation_flags = DEBUG_RPOCESS #实例化之前定义的结构体 startupinfo = STARTUPINFO() process_information = PROCESS_INFORMATION() #在以下两个成员变量的共同作用下,新建进程将在一个单独的窗体中被显示,你可以通过改变结构体STARTUPINFO中的各成员 #变量的值来控制debugee进程的行为。 startupinfo.dwFlags = 0x1 startupinfo.wShowWindow = 0x0 #设置结构体STARTUPINFO中的成员变量 #cb的值,用以表示结构体本身的大小 startupinfo.cb = sizeof(startupinfo) if kernel32.CreateProcessA( path_to_exe, None, None, None, None, creation_flags, None, None, byref(startupinfo), byref(process_information) ): print "[*] We have successfully lauched the process!" print "[*] PID: %d" % process_information.dwProcessId else: print "[*] Error: 0x%08x." % kernel32.GetLastError()my_test.py
__author__ = 'zt' import my_debugger debugger = my_debugger.debugger() debugger.load("C:\\WINDOWS\\system32\\calc.exe")