본문 바로가기

스터디/└ 소스파일들

my_debugger.py

# -*- coding: cp949 -*-
from ctypes import *
from my_debugger_defines import *

kernel32 = windll.kernel32

class debugger():

    def __init__(self):
        self.h_process       =     None
        self.pid             =     None
        self.debugger_active =     False
        self.h_thread        =     None
        self.context         =     None

        # Here let's determine and store 
        # the default page size for the system
        # determine the system page size.


    def load(self,path_to_exe):

        # dwCreation flag determines how to create the process
        # set creation_flags = CREATE_NEW_CONSOLE if you want
        # to see the calculator GUI
        creation_flags = DEBUG_PROCESS

        # instantiate the structs
        startupinfo         = STARTUPINFO()
        process_information = PROCESS_INFORMATION()

        # The following two options allow the started process
        # to be shown as a separate window. This also illustrates
        # how different settings in the STARTUPINFO struct can affect
        # the debuggee.
        startupinfo.dwFlags     = 0x1
        # We then initialize the cb variable in the STARTUPINFO struct
        # which is just the size of the struct itself
        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 launched the process!"
            print "[*] PID : %d" % process_information.dwProcessId

            # 새로 생성한 프로세스의 핸들을 구한 후
            # 나중에 접근하기 위해 저장한다.
            self.h_process = self.open_process(process_information.dwProcessId)

        else:
            print "[*] Error : 0x%08x." % kernel32.GetLastError()
    def open_process(self,pid):

        # PROCESS_ALL_ACCESS = 0x0x001F0FFF
        h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS,False,pid)
        return h_process


        h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS, None, thread_id)

        if h_thread is not None:
            return h_thread
        else:
            print "[*] Could not obtain a valid thread handle."
            return False
    def enumerate_threads(self):
        thread_entry = THREADENTRY32()    # Thread32First 실행인자로 전달되는 구조체
        thread_list = []
        snapshot = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, self.pid)

        if snapshot is not None:
            # 먼저 구조체의 크기를 설정해야 한다.
            thread_entry.dwSize = sizeof(thread_entry)
            success = kernel32.Thread32First(snapshot, byref(thread_entry))

            while success:
                if thread_entry.th32OwnerProcessID == self.pid:
                    thread_list.append(thread_entry.th32ThreadID)

                success = kernel32.Thread32Next(snapshot, byref(thread_entry))

            kernel32.CloseHandle(snapshot)
            return thread_list
        else:
            return False


    def get_thread_context (self, thread_id=None, h_thread=None):
        context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS

        # 스레드의 핸들을 구한다.
        h_thread = self.open_thread(thread_id)
        if kernel32.GetThreadContext(h_thread, byref(context)):
            # 레지스터 정보를 얻기 위해서 GetThreadContext 함수를 사용한다.
            kernel32.CloseHandle(h_thread)
            return context
        else:
            return False


    def attach(self,pid):

        self.h_process = self.open_process(pid)

        # 프로세스에 대한 어태치를 시도한다.
        # 실패하면 호출을 종료한다.
        if kernel32.DebugActiveProcess(pid):
            self.debugger_active = True
            self.pid             = int(pid)

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


    def run(self):

        # 이제 디버기에 대한 디버그 이벤트를 처리해야 한다. 
        # 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):

            # 아직은 디버그 이벤트를 처리할 핸들러를 작성하지 않았다.
            # 따라서 여기서는 단순히 프로세스가 실행을 계속하게 만든다.
            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
지식 출처 : http://scytalezz.tistory.com/21

'스터디 > └ 소스파일들' 카테고리의 다른 글

Memory Breakpoint 까지의 소스  (0) 2015.01.17
Hardware Breakpoint 까지 소스  (0) 2015.01.17
Soft Breakpoint 까지의 소스들  (0) 2015.01.17
my_test.py  (0) 2015.01.15
my_debugger_defines.py  (0) 2015.01.15