Chinaunix首页 | 论坛 | 博客
  • 博客访问: 19726482
  • 博文数量: 679
  • 博客积分: 10495
  • 博客等级: 上将
  • 技术积分: 9308
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-18 10:51
文章分类

全部博文(679)

文章存档

2012年(5)

2011年(38)

2010年(86)

2009年(145)

2008年(170)

2007年(165)

2006年(89)

分类: Python/Ruby

2011-04-19 18:10:09

构建windows调试器

 

2011-4-19磁针石 草译,略有删节

#承接软件自动化实施与培训等gtalk ouyangchongwu#gmail.com qq 37391319 博客:oychw.cublog.cn

#版权所有,转载刊登请来函联系
#python qq group: 深圳自动化测试python群:113938272
#武冈深圳qq群:66250781

参考资料:《Gray Hat Python Python Programming for Hackers and Reverse Engineers 2009

也可以使用OpenProcess()打开已有进程进行调试,位于kernel32.dll中,

HANDLE WINAPI OpenProcess(

DWORD dwDesiredAccess,

BOOL bInheritHandle

DWORD dwProcessId

);

dwDesiredAccess指明了访问权限,为了执行调试,需要设置为:PROCESS_ALL_ACCESSbInheritHandle我们设置为FalsePID是进程ID。更多资料,参见

调试已有进程的方法为:DebugActiveProcess()

BOOL WINAPI DebugActiveProcess(

DWORD dwProcessId

);

 

捕捉调试事件,使用WaitForDebugEvent()

BOOL WINAPI WaitForDebugEvent(

LPDEBUG_EVENT lpDebugEvent,

DWORD dwMilliseconds

);

第一个参数是DEBUG_EVENT结构体,第2个参数要设置为INFINITE。更多参考:

 

事件处理完毕后,继续执行,需要使用ContinueDebugEvent(),函数定义如下:

BOOL WINAPI ContinueDebugEvent(

DWORD dwProcessId,

DWORD dwThreadId,

DWORD dwContinueStatus

);

2个参数是DEBUG_EVENT中的字段,dwContinueStatus通知进程继续执行DBG_CONTINUE。或者继续处理例外DBG_EXCEPTION_NOT_HANDLED.

 

最后需要使用DebugActiveProcessStop()退出调试,唯一的参数是PID。更多参考:(

 

代码:

my_debugger_defines.py

from ctypes import *

 

# Let's map the Microsoft types to ctypes for clarity

BYTE      = c_ubyte

WORD      = c_ushort

DWORD     = c_ulong

LPBYTE    = POINTER(c_ubyte)

LPTSTR    = POINTER(c_char)

HANDLE    = c_void_p

PVOID     = c_void_p

LPVOID    = c_void_p

UINT_PTR  = c_ulong

SIZE_T    = c_ulong

 

# Constants

DEBUG_PROCESS         = 0x00000001

CREATE_NEW_CONSOLE    = 0x00000010

PROCESS_ALL_ACCESS    = 0x001F0FFF

INFINITE              = 0xFFFFFFFF

DBG_CONTINUE          = 0x00010002

 

 

# Debug event constants

EXCEPTION_DEBUG_EVENT      =    0x1

CREATE_THREAD_DEBUG_EVENT  =    0x2

CREATE_PROCESS_DEBUG_EVENT =    0x3

EXIT_THREAD_DEBUG_EVENT    =    0x4

EXIT_PROCESS_DEBUG_EVENT   =    0x5

LOAD_DLL_DEBUG_EVENT       =    0x6

UNLOAD_DLL_DEBUG_EVENT     =    0x7

OUTPUT_DEBUG_STRING_EVENT  =    0x8

RIP_EVENT                  =    0x9

 

# debug exception codes.

EXCEPTION_ACCESS_VIOLATION     = 0xC0000005

EXCEPTION_BREAKPOINT           = 0x80000003

EXCEPTION_GUARD_PAGE           = 0x80000001

EXCEPTION_SINGLE_STEP          = 0x80000004

 

 

# Thread constants for CreateToolhelp32Snapshot()

TH32CS_SNAPHEAPLIST = 0x00000001

TH32CS_SNAPPROCESS  = 0x00000002

TH32CS_SNAPTHREAD   = 0x00000004

TH32CS_SNAPMODULE   = 0x00000008

TH32CS_INHERIT      = 0x80000000

TH32CS_SNAPALL      = (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE)

THREAD_ALL_ACCESS   = 0x001F03FF

 

# Context flags for GetThreadContext()

CONTEXT_FULL                   = 0x00010007

CONTEXT_DEBUG_REGISTERS        = 0x00010010

 

# Memory permissions

PAGE_EXECUTE_READWRITE         = 0x00000040

 

# Hardware breakpoint conditions

HW_ACCESS                      = 0x00000003

HW_EXECUTE                     = 0x00000000

HW_WRITE                       = 0x00000001

 

# Memory page permissions, used by VirtualProtect()

PAGE_NOACCESS                  = 0x00000001

PAGE_READONLY                  = 0x00000002

PAGE_READWRITE                 = 0x00000004

PAGE_WRITECOPY                 = 0x00000008

PAGE_EXECUTE                   = 0x00000010

PAGE_EXECUTE_READ              = 0x00000020

PAGE_EXECUTE_READWRITE         = 0x00000040

PAGE_EXECUTE_WRITECOPY         = 0x00000080

PAGE_GUARD                     = 0x00000100

PAGE_NOCACHE                   = 0x00000200

PAGE_WRITECOMBINE              = 0x00000400

 

 

# When the dwDebugEventCode is evaluated

class EXCEPTION_RECORD(Structure):

    pass

   

EXCEPTION_RECORD._fields_ = [

        ("ExceptionCode",        DWORD),

        ("ExceptionFlags",       DWORD),

        ("ExceptionRecord",      POINTER(EXCEPTION_RECORD)),

        ("ExceptionAddress",     PVOID),

        ("NumberParameters",     DWORD),

        ("ExceptionInformation", UINT_PTR * 15),

        ]

 

class _EXCEPTION_RECORD(Structure):

    _fields_ = [

        ("ExceptionCode",        DWORD),

        ("ExceptionFlags",       DWORD),

        ("ExceptionRecord",      POINTER(EXCEPTION_RECORD)),

        ("ExceptionAddress",     PVOID),

        ("NumberParameters",     DWORD),

        ("ExceptionInformation", UINT_PTR * 15),

        ]

 

# Exceptions

class EXCEPTION_DEBUG_INFO(Structure):

    _fields_ = [

        ("ExceptionRecord",    EXCEPTION_RECORD),

        ("dwFirstChance",      DWORD),

        ]

   

# it populates this union appropriately

class DEBUG_EVENT_UNION(Union):

    _fields_ = [

        ("Exception",         EXCEPTION_DEBUG_INFO),

#        ("CreateThread",      CREATE_THREAD_DEBUG_INFO),

#        ("CreateProcessInfo", CREATE_PROCESS_DEBUG_INFO),

#        ("ExitThread",        EXIT_THREAD_DEBUG_INFO),

#        ("ExitProcess",       EXIT_PROCESS_DEBUG_INFO),

#        ("LoadDll",           LOAD_DLL_DEBUG_INFO),

#        ("UnloadDll",         UNLOAD_DLL_DEBUG_INFO),

#        ("DebugString",       OUTPUT_DEBUG_STRING_INFO),

#        ("RipInfo",           RIP_INFO),

        ]  

 

# DEBUG_EVENT describes a debugging event

# that the debugger has trapped

class DEBUG_EVENT(Structure):

    _fields_ = [

        ("dwDebugEventCode", DWORD),

        ("dwProcessId",      DWORD),

        ("dwThreadId",       DWORD),

        ("u",                DEBUG_EVENT_UNION),

        ]

 

 

 

my_debugger.py

from ctypes import *

from my_debugger_defines import *

kernel32 = windll.kernel32

class debugger():

    def __init__(self):

        pass

           

    def open_process(self,pid):

        h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS,pid,False)

        return h_process

    def attach(self,pid):

        self.h_process = self.open_process(pid)

        # We attempt to attach to the process

        # if this fails we exit the call

        if kernel32.DebugActiveProcess(pid):

            self.debugger_active = True

            self.pid = int(pid)

            self.run()

        else:

            print "[*] Unable to attach to the process."

    def run(self):

        # Now we have to poll the debuggee for

        # debugging events

        while self.debugger_active == True:

            self.get_debug_event()   

           

    def get_debug_event(self):

        debug_event = DEBUG_EVENT()

        continue_status= DBG_CONTINUE

        if kernel32.WaitForDebugEvent(byref(debug_event),INFINITE):

            # We aren't going to build any event handlers

            # just yet. Let's just resume the process for now.

            raw_input("Press a key to continue...")

            self.debugger_active = False

            kernel32.ContinueDebugEvent( \

                debug_event.dwProcessId, \

                debug_event.dwThreadId, \

                continue_status )

    def detach(self):

        if kernel32.DebugActiveProcessStop(self.pid):

            print "[*] Finished debugging. Exiting..."

            return True

        else:

            print "There was an error"

            return False           

执行结果:

Enter the PID of the process to attach to: 9676

Press a key to continue...

[*] Finished debugging. Exiting...

文件:2.rar
大小:2KB
下载:下载
阅读(8342) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~