python灰帽子 笔记 二 构建自己的Windows调试器

例子代码:

调试器需要具备两种基本能力:打开执行程序作为自身子进程运行、附加一个现有进程的能力

第一种使用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")

你可能感兴趣的:(笔记,python灰帽子,构建自己的Windows调试器)