- 8
- 0
- 约3.77万字
- 约 28页
- 2015-08-18 发布于河南
- 举报
灰帽 Python之旅3.doc
3
自己动手写一个windos调试器
现在我们已经讲解完了基础知识,是时候实现一个真正的的调试器的时候了。当微软开发windows的时候,他们增加了一大堆的令人惊喜的调试函数以帮助开发者们保证产品的质量。我们将大量的使用这些函数创建你自己的纯python调试器。有一点很重要,我们本质上是在深入的学习PyDbg(Pedram Amini’s )的使用,这是目前能找到的最简洁的Windows平台下的Python调试器 。拜Pedram所赐,我尽可能用PyDbg完成了我的代码(包括函数名,变量,等等),同时你也可以更容易的用PyDbg实现你的调试器。
为了对一个进程进行调试,你首先必须用一些方法把调试器和进程连接起来。所以,我们的调试器要不然就是装载一个可执行程序然后运行它,要不然就是动态的附加到一个运行的进程。Windows的调试接口(Windows debugging API)提供了一个非常简单的方法完成这两点。
运行一个程序和附加到一个程序有细微的差别。打开一个程序的优点在于他能在程序运行任何代码之前完全的控制程序。这在分析病毒或者恶意代码的时候非常有用。附加到一个进程,仅仅是强行的进入一个已经运行了的进程内部,它允许你跳过启动部分的代码,分析你感兴趣的代码。你正在分析的地方也就是程序目前正在执行的地方。
第一种方法,其实就是从调试器本身调用这个程序(调试器就是父进程,对被调试进程的控制权限更大)。在Windows上创建一个进程用CreateProcessA()函数。将特定的标志传进这个函数,使得目标进程能够被调试。一个CreateProcessA()调用看起来像这样:
BOOL WINAPI CreateProcessA(
LPCSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
初看这个调用相当恐怖,不过,在逆向工程中我们必须把大的部分分解成小的部分以便理解。这里我们只关心在调试器中创建一个进程需要注意的参数。这些参数是lpApplicationName,lpCommandLine,dwCreationFlags,lpStartupInfo, 和 lpProcessInformation。剩余的参数可以设置成空值(NULL)。关于这个函数的详细解释可以查看MSDN(微软之葵花宝典)。最前面的两个参数用于设置,需要执行的程序的路径和我们希望传递给程序的参数。dwCreationFlags (创建标记)参数接受一个特定值,表示我们希望程序以被调试的状态启动。最后两个参数分别分别指向2个结构(STARTUPINFO and PROCESS_INFORMATION),不仅包含了进程如何启动,以及启动后的许多重要信息。(lpStartupInfo:STARTUPINFO 结构,用于在创建子进程时设置各种属性,lpProcessInformation:PROCESS_INFORMATION 结构,用来在进程创建后接收相关信息,该结构由系统填写。)
创建两个Python文件my_debugger.py和my_debugger_defines.py。我们将创建一个父类debugger() 接着逐渐的增加各种调试函数。另外,把所有的结构,联合,常量放到my_debugger_defines.py方便以后维护。
# my_debugger_defines.py
from ctypes import *
# Lets map the Microsoft types to ctypes for clarity
WORD = c_ushort
DWORD = c_ulong
LPBYTE = POINTER(c_ubyte)
LPTSTR = POINTER(c_char)
HANDLE = c_void_p
# Constants
DEBUG_PROCESS = 0CREAT
原创力文档

文档评论(0)