스터디/└ 소스파일들
my_debugger.py
kcrong
2015. 1. 15. 04:06
# -*- 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