2013. 1. 29. 21:26

[출처 : 파이썬 해킹프로그래밍 ] 



간단한 디버거을 만드는 큰 흐름은 아래 와 같다.




위 내용을 우선 winapi를 사용하는 방법으로 파이썬에서 실행시키는 것부터 시작 하였다.

아래는 기본적인 createProcessA() 함수를 받을수 있도록 선언된 상태에서 calc 를 실행시키는 부분까지 이다. 

즉 위 표에서 파란색 부분만이다.






test.py



import my_debugger


debugger = my_debugger.debugger()

debugger.load("C:\\WINDOWS\\system32\\calc.exe")








my_debugger_defines.py



from ctypes import *


#Ctypes 형태의 타입을 마이크로 소포트의 타입으로 매핑시켜서 사용하기 위한 정의이다.

# 이 이후부터는 아래의 마이크로 소포트타입형은 우측의 ctype으로 재정의 된다.


WORD    =   c_ushort

DWORD   =   c_ulong

LPBYTE  =   POINTER(c_ubyte)

LPTSTR  =   POINTER(c_char)

HANDLE  =   c_void_p


DEBUG_PROCESS = 0x00000001

CREATE_NEW_CONSOLE  =   0x00000010


#윈도우에서 프로세스를 직접 실행시키는 방법은 CreateProcessA() 함수를 호출해야 한다.

#아래 구조체는  CreateProccessA() 를위한 구조체이다. 

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



from ctypes import *

from my_debugger_defines import *


kernel32 = windll.kernel32


class debugger():

    

    #생성자와 같은 연락을 하고 초기화를 담당한다.

    def __init__(self):

        pass

    

    #클래스 debgger가 로드될시 자기 자신과 실행할주소가 들어가게된다. 첫번째 인자는 반드시 self 여야 한다.

    

    def load(self,path_to_exe):

        

        #계산기의 GUI를 보고자 한다면 creation_flags를 

        #CREATE_NEW_CONSOLE로 설정하면된다.

        creation_flags = DEBUG_PROCESS

        

        #구조체를 인스턴스화시킨다.

        startupinfo = STARTUPINFO()

        process_information = PROCESS_INFORMATION()

        

        #다음의 두 옵션은 프로세스가 도립적인 창으로 실행되게 만들어준다

        #이는 STARTUPINFO struct 구조체의 설정 내용에 따라 디버깅 프로세스에 어떤 영향을 미치는지 보여준다.

        startupinfo.dwFlags = 0x1

        startupinfo_wShowWindow = 0x0

        

        #다음에는 STARTUPINFO struct 구조체 자신의 크기를 나타내는 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 lanunched the process!"

                                                print "[*]Pid : %d" %process_information.dwProcessId

        

        else:

            print "[*]Error :0x%08x." %kernel32.GetLastError()

            





Posted by k1rha