반응형

 

파이썬 디버기를 만들다 보면 GetSystemInfo 함수를 사용하려고 하는데

Windows 7에서는 사용하지 못하게 된다.

따라서, 해당 내용을 찾아 보면 GetSystemInfo는 Windows 7에서는 지원하지 않는 API 함수 이다.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms724381(v=vs.85).aspx

 

하지만 다행히도 GetSystemInfo와 동일한 함수가 있다.

wow64에서 돌아가는 application에서 사용하는 함수~~!!

"GetNativeSystemInfo"

http://msdn.microsoft.com/en-us/library/windows/desktop/ms724340(v=vs.85).aspx

 

GetSystemInfo와 동일한 함수이므로

스크립트를 짜는데 아무 문제가 없게 된다.

 

적용한 내용이다.

 

        system_infor = SYSTEM_INFO()

        # wow64에서 사용하는 함수
        # wow64가 아닌 환경 GetSystemInfo 함수를 사용하면 된다.
        kernel32.GetNativeSystemInfo(byref(system_infor))

 

그럼 오늘도 즐거운 삽질이 되시길...

반응형
반응형

 

 

 

 버전을 끊어가면서 해야할 것 같아

중간 중간 마무리 되면 버전을 남기기로 하였다.

 

W7PD by crattack. (v.0.3)

- 기능

  ★  Memory break point 적용

 

 

W7PD by crattack. (v.0.2)

- 기능

  ★  hardware break point 적용

 

 

 

Win7 Python Debugger by crattack. (v. 0.1) (- 이후 부턴 W7PD by crattack)

- 기능

  ★  GetModuleHandle 사용한 메모리 주소 찍기

  ★  해당 함수 주소 찍기

  ★  soft break point 적용

 

 

반응형
반응형

 

python 2.7.5 버전을 사용하다가 python 3.x 버전을 사용하니 has_key() 를 사용하지 못하게 되었다.

따라서, 이 것을 대응 할 수 있는 함수가 바로 in 어떻게 사용하는지 예시로 남긴다.

 

[초기 값] 

d = {'a': 1, 'b': 2}

 

 

[has_key 이용 - 3.x 이전 버전]

if d.has_key('a'):

    print "포함되어 있네"

else:

    print "포함되지 않음"

 

[in 이용 - 3.x 이후 버전]

if 'a' in d:

    print "포함되어 있네"

else:

    print "포함되지 않음"

 

이렇게 사용하면 된다.

누군가가 나와 같은 삽질이 안했으면 하는 바램으로....

반응형
반응형

 

코딩을 하다보니, 문자열 타입에 따라서 인자가 반영되는 것도 있고

아닌 것도 있다.

 

따라서, 인자가 반영 되기 위해서는 해당 문자열의 타입을 확인해야 하는데 그걸 육안으로 하기 쉽지 않으니

아래의 함수를 이용하면 쉽게 bytes, str 인지 확인이 가능하다.

 

print (type(string)) 

 

 

>>> print (type(b'test'))
<class 'bytes'>
>>> print (type('test'))
<class 'str'>
>>> print (type(u'test'))
<class 'str'> 

 

추가로 문자열 convert 방식을 예시로 넣도록 하겠다. (향후 찾는걸 방지..ㅋㅋ)

 

[String To Bytes]

 

bytestr = str.encode(string)

 

[Bytes To String]

 

str = str.decode(bytes)

 

반응형
반응형

 

Windows 7에서는 Unicode 형태로 지원하고 있어서 문자열을 유니코드 또는 바이너리 형으로

변환하여 호출 해야 된다.

 

 

def Get_DLL_Function(self, dll, function)

        handle = kernel32.GetModuleHandleW(dll)

        if handle <= 0:
            print ("[##] GetModuleHandle False\n")
            return False

        print ("[##] \"%s\" GetModudleHandle : 0x%08x\n" % (dll, handle))

        address = kernel32.GetProcAddress(handle,function)

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

            print ("[##] GetProcAddress \"%s\" False\n" % function)
            kernel32.CloseHandle(handle)
            return False

        print ("[##] \"%s\" GetProcAddress : 0x%08x\n" % (function, address))
        kernel32.CloseHandle(handle)
        return address

 

해당 코드는 크게 다를 것이 없다.

그러나 호출하는 과정에서 문자열을 b"..." 형태로 변환하여 사용하지 않으면 호출되지 않는다.

(u"..." 형태도 있지만 python 3.x 에서부터는 사용하지 못하고 있다.)

http://docs.python.org/3.0/whatsnew/3.0.html

 You can no longer use u"..." literals for Unicode text. However, you must use b"..." literals for binary data.

 

위 내용을 기반으로 b"..."로 변환하니 결과가 나오게 된다.

 

Get_DLL_Function("msvcrt.dll",b"printf") 

 

[결과 값]

 

[##] "msvcrt.dll" GetModudleHandle : 0x77250000

[##] "b'printf'" GetProcAddress : 0x7726c5b9 

 

이걸 얻기 위해 얼마나 삽질을 했던가...

비로소 해결을 했다.~!!!

반응형

'프로그래밍 > Python' 카테고리의 다른 글

python 3.x has_key 없어짐!!!!  (0) 2013.07.23
문자열 타입 확인  (0) 2013.07.23
Windows 7에서 GetModuleHandle 사용하기  (0) 2013.07.12
64bit debugger 만들기  (0) 2013.07.02
python thread context 보기(win7 64bit)  (2) 2013.07.02
반응형

 

아..이 문제 때문에 얼마나 고생 했는지 정말 짜증이 난다.

나와 같은 상황이 발생하지 않길 바라며, Windows 7에서의 GetMoudleHandle과 kernel32.dll, kernelbase.dll에 대한

내용을 언급하도록 하겠다.

 

먼저, Windows Vista 이후 바뀐 부분은  kernel32.dll을 사용하느냐 사용하지 않느냐 이다.

Vista까지는 kernel32.dll에서 모든걸 관장하였다. 따라서, kernel32.dll만 사용하더라도 아무 이상이 없었다.

 

그러나,~~

Windows 7으로 넘어오면서 kernel32.dll에서 사용하는 거의 모든 함수들이 kernelbase.dll로 이관되었다.

(그냥 kernel32.dll을 사용해도 된다.

어짜피 kernel32.dll에서 kernelbase.dll를 jmp 하기 때문에 문제 없을 것 이다.)

-> 만약, 잘 안되거나 하면 kernelbase.dll과 kernel32.dll를 뒤져보길 바란다. 그럼 안되는 이유를 알 수 있을 것이다.

 

그럼, python에서 GetModuleHandle을 사용하기 위한 방법을 알려주겠다.

결론부터 말하자면 Windows 7에서는 GetModuleHandleA는 없어졌다.

따라서, 아무리 GetMoudleHandleA()를 이용해봤자 return 값은 "0" 이다.

 

이걸 알기 위해서 일주일이 걸렸다..

몬 짓을 한건지..

괜히 디버기 만든다고 삽질을 하는 거 같은 느낌이 들지만, 그럼 어떻게 찾았는지 History를 적어보도록 하겠다.

 

ollydbg로 모듈 상태를 확인 한다.

해당 Windows 7에서는 kernelbase.dll이 기본으로 올라가 있는 것을 확인 할 수 있다.

kernel32.dll를 열어 보면, kernelbase.dll로 링크가 걸려 있는 것을 확인 할 수 있다.

 

 

Memory Map을 통해 Load된 내용을 확인 하였으니, 이젠 찾아 보도록 하자.

kernel32.dll 내부에서 GetMoudleHandle을 찾아 보면 딱하니

GetMoudleHandleW만 존제하는 것을 볼 수 있다.

 

 

그래서 코드를 아래와 같이 수정하면, Module의 시작 주소를 얻어 올 수 있다.

 

 

 

        handle = kernel32.GetModuleHandleW(dll)

        if handle <= 0:
            print ("[##] GetModuleHandle False\n")
            return False

        print ("[##] \"%s\" GetModudleHandle : 0x%08x\n" % (dll, handle))

 

GetModueHandle을 가지고 나와 같이 삽질 하지 않길 바라며,

이 글을 올린다.

 

반응형

'프로그래밍 > Python' 카테고리의 다른 글

문자열 타입 확인  (0) 2013.07.23
Windows 7에서 GetProcAddress 사용하기  (0) 2013.07.22
64bit debugger 만들기  (0) 2013.07.02
python thread context 보기(win7 64bit)  (2) 2013.07.02
Context 32bit / 64bit 선언  (0) 2013.06.29
반응형

 

 

겁나 빡시다.

ㅡ.ㅡ;

나온것들은 다 32bit에서 동작하는 방식...ㅡㅡ

된장~!!!

왜 64bit로는 포팅을 안한거얏~!!

이번 기회에 내가 만들어서 혼자만 가지고 있어?

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

 

여하튼 빡시게 하고 있음..겁나 빡셔~~~

ㅋㅋㅋ

 

 

 

반응형
반응형

 

디버기를 만드는 과정에서 호출 하는 py코드를 공유한다.

 

my_loader.py 

# -*- coding: euc-kr -*-
import my_debugger
import sys

debugger = my_debugger.debugger()

pid = input("\nEnter The PID of the process to attach to : ")

if (pid == ""):
    print ("[#] Warning Please Enter PID Number")
    sys.exit()

print ("[*] Select PID %d" % int(pid))

debugger.attach(int(pid))

list = debugger.enumerate_threads()

# 스레드 리스트의 각 스레드에 대한 레지스터 값을 출력
for thread in list:
    thread_context = debugger.get_thread_context(thread)
   
    print ("[*] Dumping registers for Thread ID: 0x%08x" % thread)
    print ("[*] RIP : 0x{0:016x}" .format(thread_context.Rip))
    print ("[*] RSP : 0x{0:016x}" .format(thread_context.Rsp))
    print ("[*] RBP : 0x{0:016x}" .format(thread_context.Rbp))
    print ("[*] RAX : 0x{0:016x}" .format(thread_context.Rax))
    print ("[*] RBX : 0x{0:016x}" .format(thread_context.Rbx))
    print ("[*] RCX : 0x{0:016x}" .format(thread_context.Rcx))
    print ("[*] RDX : 0x{0:016x}" .format(thread_context.Rdx))
    print ("[*] End DUMP")


debugger.detach() 

 

 my_debugger.py

 # -*- coding: euc-kr -*-

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
        self.exception          = None
        self.exception_address  = None

    def load(self, path_to_exe):

        # dwCreation 플래그를 이용해 프로세스를 어떻게 생성할 것인지 판단한다.
        # 계산기의 GUI를 보고자 한다면 creation)flags를 CREATE_NEW_CONSOLE로 설정하면 된다.
        # creation_flags = CREATE_NEW_CONSOLE
        # DEBUG_PROCESS로 넣을 경우 메모리에 올라갔다가 내려 간다.
        creation_flags = DEBUG_PROCESS
       
       
        # 구조체 인스턴스화
        startupinfo = STARTUPINFO()
        process_information = PROCESS_INFORMATION()
       
        # 다음의 두 옵션은 프로세스가 독립적인 창으로 실행되게 만들어준다.
        # 이는 STARTUPINFOR 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 ("\n[*] We have successfully launched the process!")
            print ("[*] PID : %d" % process_information.dwProcessId)
       
        else:
            print ("[*] Error: 0x%08x." % kernel32.GetLastError())
    
    def open_process(self, pid):
       
        h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, pid)
        print ("[*] OpenProcess Handle : %d" % h_process)
        return h_process
   
    def attach(self, pid):
       
        self.h_process = self.open_process(pid)
        print ("[*] self.h_process : %d" % self.h_process)
       
        # 프로세스에 대한 어태치를 시도한다.
        # 실패하면 호출을 종료한다.
       
        if kernel32.DebugActiveProcess(pid):
            self.debugger_active = True
            self.pid = int(pid)
        else:
            print ("[*] Error: 0x%08x." % kernel32.GetLastError())
            print ("[*] Unable to attach to the process.")
            exit
       
    def run(self):
       
        # 이제는 디버기에 대한 디버그 이벤트를 처리해야 한다.
       
        while self.debugger_active == True:
            self.get_debug_event()


    def get_debug_event(self):
       
        debug_event = DEBUG_EVENT()
        continue_status = DBG_CONTINUE
       
        event_group = {1:"EXCEPTION_DEBUG_EVENT",
                       2:"CREATE_THREAD_DEBUG_EVENT",
                       3:"CREATE_PROCESS_DEBUG_EVENT",
                       4:"EXIT_THREAD_DEBUG_EVENT",
                       5:"EXIT_PROCESS_DEBUG_EVENT",
                       6:"LOAD_DLL_DEBUG_EVENT",
                       7:"UNLOAD_DLL_DEBUG_EVENT",
                       8:"OUPUT_DEBUG_STRING_EVENT",
                       9:"RIP_EVENT"
                       }
       
        if kernel32.WaitForDebugEvent(byref(debug_event), INFINITE):
           
            # 스레드의 컨텍스트 정보를 구한다.
            self.h_thread = self.open_thread(debug_event.dwThreadId)
            self.context = self.get_thread_context(self.h_thread)
           
            print "[##] Event Code : %d (%s)\t[##] thread ID: %d" % (debug_event.dwDebugEventCode,
                                                                     event_group.get(debug_event.dwDebugEventCode),
                                                                     debug_event.dwThreadId)
          
            # 발생한 이벤트의 종류가 예외 이벤트이면 그것을 좀 더 자세하게 출력한다.
            if debug_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT:
                # 예외코드 구하기
                exception = debug_event.u.Exception.ExceptionRecord.ExceptionCode
                self.exception_address = debug_event.u.Exception.ExceptionRecord.ExceptionAddress
           
                if exception == EXCEPTION_ACCESS_VIOLATION:
                    print "Access Violation Detected."
           
                #브레이크 포인트인 경우에는 내부 핸들러를 호출한다.
                elif exception == EXCEPTION_BREAKPOINT:
                    continue_status = self.exception_handler_breakpoint()
           
                elif exception == EXCEPTION_GUARD_PAGE:
                    print "Guard Page Access Detected."
           
                elif exception == EXCEPTION_SINGLE_STEP:
                    print "Single Stepping."   

 

            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
   
   
    def open_thread (self, thread_id):
       
        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()
        thread_list = []
        snapshot = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, self.pid)
       
        print ("[*] Enumerate Thread inside")
       
        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 = CONTEXT()
        context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS
       
        if not h_thread:
            h_thread = self.open_thread(thread_id)
      
        # 스페드의 핸들을 구한다.
        if kernel32.GetThreadContext(h_thread, byref(context)):
            kernel32.CloseHandle(h_thread)
            # 64bit의 경우 확장이기 때문에 변환을 해야 함.
            kernel32.RtlCaptureContext(byref(context))
           
            return context
        else:
            #print "[##] thread_id(0x%x) GetThreadContext False" % (thread_id)
            return False
       

    def exception_handler_breakpoint(self):
        print "[*] Inside the breakpoint handler."
        print "Exception Address : 0x%08x" % self.exception_address
       
        return DBG_CONTINUE

 

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
DWORD64   = c_ulonglong
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


# Structures for CreateProcessA() function
# STARTUPINFO describes how to spawn the process
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),
        ]

# PROCESS_INFORMATION receives its information
# after the target process has been successfully
# started.
class PROCESS_INFORMATION(Structure):
    _fields_ = [
        ("hProcess",    HANDLE),
        ("hThread",     HANDLE),
        ("dwProcessId", DWORD),
        ("dwThreadId",  DWORD),
        ]

# 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),
        ]

# Used by the CONTEXT structure
class FLOATING_SAVE_AREA(Structure):
   _fields_ = [
  
        ("ControlWord", DWORD),
        ("StatusWord", DWORD),
        ("TagWord", DWORD),
        ("ErrorOffset", DWORD),
        ("ErrorSelector", DWORD),
        ("DataOffset", DWORD),
        ("DataSelector", DWORD),
        ("RegisterArea", BYTE * 80),
        ("Cr0NpxState", DWORD),
]

# The CONTEXT structure which holds all of the
# register values after a GetThreadContext() call
class CONTEXT(Structure):
    _fields_ = [
   
        ("ContextFlags", DWORD),
        ("Dr0", DWORD),
        ("Dr1", DWORD),
        ("Dr2", DWORD),
        ("Dr3", DWORD),
        ("Dr6", DWORD),
        ("Dr7", DWORD),
        ("FloatSave", FLOATING_SAVE_AREA),
        ("SegGs", DWORD),
        ("SegFs", DWORD),
        ("SegEs", DWORD),
        ("SegDs", DWORD),

# 64bit Register
        ("Rdi", DWORD64),
        ("Rsi", DWORD64),
        ("Rbx", DWORD64),
        ("Rdx", DWORD64),
        ("Rcx", DWORD64),
        ("Rax", DWORD64),
        ("Rbp", DWORD64),
        ("Rip", DWORD64),
        ("Rsp", DWORD64),
       
        ("SegCs", DWORD),
        ("EFlags", DWORD),
        ("SegSs", DWORD),
        ("ExtendedRegisters", BYTE * 512),
]

# THREADENTRY32 contains information about a thread
# we use this for enumerating all of the system threads

class THREADENTRY32(Structure):
    _fields_ = [
        ("dwSize",             DWORD),
        ("cntUsage",           DWORD),
        ("th32ThreadID",       DWORD),
        ("th32OwnerProcessID", DWORD),
        ("tpBasePri",          DWORD),
        ("tpDeltaPri",         DWORD),
        ("dwFlags",            DWORD),
    ]

# Supporting struct for the SYSTEM_INFO_UNION union
class PROC_STRUCT(Structure):
    _fields_ = [
        ("wProcessorArchitecture",    WORD),
        ("wReserved",                 WORD),
]


# Supporting union for the SYSTEM_INFO struct
class SYSTEM_INFO_UNION(Union):
    _fields_ = [
        ("dwOemId",    DWORD),
        ("sProcStruc", PROC_STRUCT),
]
# SYSTEM_INFO structure is populated when a call to
# kernel32.GetSystemInfo() is made. We use the dwPageSize
# member for size calculations when setting memory breakpoints
class SYSTEM_INFO(Structure):
    _fields_ = [
        ("uSysInfo", SYSTEM_INFO_UNION),
        ("dwPageSize", DWORD),
        ("lpMinimumApplicationAddress", LPVOID),
        ("lpMaximumApplicationAddress", LPVOID),
        ("dwActiveProcessorMask", DWORD),
        ("dwNumberOfProcessors", DWORD),
        ("dwProcessorType", DWORD),
        ("dwAllocationGranularity", DWORD),
        ("wProcessorLevel", WORD),
        ("wProcessorRevision", WORD),
]

# MEMORY_BASIC_INFORMATION contains information about a
# particular region of memory. A call to kernel32.VirtualQuery()
# populates this structure.
class MEMORY_BASIC_INFORMATION(Structure):
    _fields_ = [
        ("BaseAddress", PVOID),
        ("AllocationBase", PVOID),
        ("AllocationProtect", DWORD),
        ("RegionSize", SIZE_T),
        ("State", DWORD),
        ("Protect", DWORD),
        ("Type", DWORD),

 

나도 인터넷에서 떠돌아다니는 것을 모으고 수정한 것이니,

참고해서 사용하기 바란다.

 

출력 형태

 

Enter The PID of the process to attach to : 7320
[*] Select PID 7320
[*] OpenProcess Handle : 536
[*] self.h_process : 536
[*] Enumerate Thread inside
[*] Dumping registers for Thread ID: 0x000015a8
[*] RIP : 0x00000000025d1588
[*] RSP : 0x000000000021e7f0
[*] RBP : 0x000000000021e5d0
[*] RAX : 0x000000000021e800
[*] RBX : 0x0000000000001100
[*] RCX : 0x00000000025d3128
[*] RDX : 0x000000000021e5d0
[*] End DUMP
[*] Dumping registers for Thread ID: 0x00001d6c
[*] RIP : 0x00000000025d1588
[*] RSP : 0x000000000021e7f0
[*] RBP : 0x000000000021e5d0
[*] RAX : 0x000000000021e800
[*] RBX : 0x0000000000001100
[*] RCX : 0x000000007301692d
[*] RDX : 0x000000000021e5d0
[*] End DUMP
[*] Dumping registers for Thread ID: 0x00001ca0
[*] RIP : 0x00000000025d1588
[*] RSP : 0x000000000021e7f0
[*] RBP : 0x000000000021e5d0
[*] RAX : 0x000000000021e800
[*] RBX : 0x0000000000001100
[*] RCX : 0x000000007301692d
[*] RDX : 0x000000000021e5d0
[*] End DUMP
[*] Dumping registers for Thread ID: 0x00000fa0
[*] RIP : 0x00000000025d1588
[*] RSP : 0x000000000021e7f0
[*] RBP : 0x000000000021e5d0
[*] RAX : 0x000000000021e800
[*] RBX : 0x0000000000001100
[*] RCX : 0x000000007301692d
[*] RDX : 0x000000000021e5d0
[*] End DUMP
[*] Dumping registers for Thread ID: 0x0000218c
[*] RIP : 0x00000000025d1588
[*] RSP : 0x000000000021e7f0
[*] RBP : 0x000000000021e5d0
[*] RAX : 0x000000000021e800
[*] RBX : 0x0000000000001100
[*] RCX : 0x000000007301692d
[*] RDX : 0x000000000021e5d0
[*] End DUMP
[*] finished debugging. Exiting...
done. 

 

반응형
반응형

 

참조 : http://riguo.hateblo.jp/entry/2012/04/22/113400

 

python 디버기를 만드는 과정에서 발생하는 32bit와 64bit의 차이를 알지 못하면

엄청 짜증이 난다.

책이 나올때는 32bit 환경에서 만들어졌기 때문에 64bit의 환경에서의 내용이 나오지 않는다.

따라서, 관련 내용을 정리하여 올린다.

 

32bit Context Defines 

64bit Context Defines

DWORD     = c_ulong

 

class CONTEXT(Structure):
    _fields_ = [
   
        ("ContextFlags", DWORD),
        ("Dr0", DWORD),
        ("Dr1", DWORD),
        ("Dr2", DWORD),
        ("Dr3", DWORD),
        ("Dr6", DWORD),
        ("Dr7", DWORD),
        ("FloatSave", FLOATING_SAVE_AREA),
        ("SegGs", DWORD),
        ("SegFs", DWORD),
        ("SegEs", DWORD),
        ("SegDs", DWORD),

# 32bit Register
        ("Edi", DWORD),
        ("Esi", DWORD),
        ("Ebx", DWORD),
        ("Edx", DWORD),
        ("Ecx", DWORD),
        ("Eax", DWORD),
        ("Ebp", DWORD),
        ("Eip", DWORD),
        ("Esp", DWORD),
       
        ("SegCs", DWORD),
        ("EFlags", DWORD),
        ("SegSs", DWORD),
        ("ExtendedRegisters", BYTE * 512),
]

DWORD        = c_ulong

DWORD64     = c_ulonglong

 

class CONTEXT(Structure):
    _fields_ = [
   
        ("ContextFlags", DWORD),
        ("Dr0", DWORD),
        ("Dr1", DWORD),
        ("Dr2", DWORD),
        ("Dr3", DWORD),
        ("Dr6", DWORD),
        ("Dr7", DWORD),
        ("FloatSave", FLOATING_SAVE_AREA),
        ("SegGs", DWORD),
        ("SegFs", DWORD),
        ("SegEs", DWORD),
        ("SegDs", DWORD),

# 64bit Register
        ("Rdi", DWORD64),
        ("Rsi", DWORD64),
        ("Rbx", DWORD64),
        ("Rdx", DWORD64),
        ("Rcx", DWORD64),
        ("Rax", DWORD64),
        ("Rbp", DWORD64),
        ("Rip", DWORD64),
        ("Rsp", DWORD64),
       
        ("SegCs", DWORD),
        ("EFlags", DWORD),
        ("SegSs", DWORD),
        ("ExtendedRegisters", BYTE * 512),
]

 

참고해서 쓰기 바란다.

 

ps : 출력 형태는 다음과 같다.

 

32bit print format 

64bit print format

 

    print ("[*] Dumping registers for Thread ID: 0x%08x" % thread)
    print ("[*] RIP : 0x{0:016x}" .format(thread_context.Rip))
    print ("[*] RSP : 0x{0:016x}" .format(thread_context.Rsp))
    print ("[*] RBP : 0x{0:016x}" .format(thread_context.Rbp))
    print ("[*] RAX : 0x{0:016x}" .format(thread_context.Rax))
    print ("[*] RBX : 0x{0:016x}" .format(thread_context.Rbx))
    print ("[*] RCX : 0x{0:016x}" .format(thread_context.Rcx))
    print ("[*] RDX : 0x{0:016x}" .format(thread_context.Rdx))
    print ("[*] End DUMP")

 

    print ("[*] Dumping registers for Thread ID: 0x%08x" % thread)
    print ("[*] RIP : 0x{0:016x}" .format(thread_context.Rip))
    print ("[*] RSP : 0x{0:016x}" .format(thread_context.Rsp))
    print ("[*] RBP : 0x{0:016x}" .format(thread_context.Rbp))
    print ("[*] RAX : 0x{0:016x}" .format(thread_context.Rax))
    print ("[*] RBX : 0x{0:016x}" .format(thread_context.Rbx))
    print ("[*] RCX : 0x{0:016x}" .format(thread_context.Rcx))
    print ("[*] RDX : 0x{0:016x}" .format(thread_context.Rdx))
    print ("[*] End DUMP")

 

반응형
반응형

 

파이썬 해킹 프로그래밍으로 현재 디버기를 만들고 있는 상황인데

Context 값을 얻어오지 못하는 현상이 발생했다.

과연 무엇 때문에 그럴까????

 

>>>>> 현재 내 환경은 Windows7 64bit 이다.

 

Enter The PID of the process to attach to : 3692
[*] Select PID 3692
[*] OpenProcess Handle : 124
[*] self.h_process : 124
[*] Enumerate Thread inside
[*] Dumping registers for Thread ID: 0x00001928
[*] EIP : 0x00000000
[*] ESP : 0x00000000
[*] EBP : 0x00000000
[*] EAX : 0x00000000
[*] EBX : 0x00000000
[*] ECX : 0x00000000
[*] EDX : 0x00000000
[*] End DUMP

이유는 64bit에서는 32bit 레지스터를 사용하지 않는다.

따라서, RIP, RSP, RBP 등등 확장된 레지스터를 사용하기 때문에 담는 그릇도 틀리다.

32bit에서 실행할 경우 아래와 같이 출력이 가능하다.

 

 

32bit 

 64bit

Enter The PID of the process to attach to : 3364
[*] Select PID 3364
[*] OpenProcess Handle : 1900
[*] self.h_process : 1900
[*] Enumerate Thread inside
[*] Dumping registers for Thread ID: 0x00000d1c
[*] EIP : 0x7c93e514
[*] ESP : 0x0007fde0
[*] EBP : 0x0007fdfc
[*] EAX : 0x00b50088
[*] EBX : 0x00000000
[*] ECX : 0x00001f40
[*] EDX : 0x000adea8
[*] End DUMP
[*] Dumping registers for Thread ID: 0x000001d0
[*] EIP : 0x7c9820ec
[*] ESP : 0x00acfff8
[*] EBP : 0x00000000
[*] EAX : 0x00000000
[*] EBX : 0x00000001
[*] ECX : 0x00000002
[*] EDX : 0x00000003
[*] End DUMP
[*] finished debugging. Exiting...

[*] self.h_process : 124
[*] Enumerate Thread inside
[*] Get Thread Context inside
[##] Thread Handle : 0xac
[*] Dumping registers for Thread ID: 0x00001dc0
[*] RIP : 0x0000000002535318
[*] RSP : 0x000000000021f690
[*] RBP : 0x000000000021f470
[*] RAX : 0x000000000021f6a0
[*] RBX : 0x0000000000001100
[*] RCX : 0x000000000258c0b8
[*] RDX : 0x000000000021f470
[*] End DUMP
[*] Get Thread Context inside
[##] Thread Handle : 0xac
[*] Dumping registers for Thread ID: 0x000003c0
[*] RIP : 0x0000000002535318
[*] RSP : 0x000000000021f690
[*] RBP : 0x000000000021f470
[*] RAX : 0x000000000021f6a0
[*] RBX : 0x0000000000001100
[*] RCX : 0x00000000738e692d
[*] RDX : 0x000000000021f470
[*] End DUMP

 

이런 어처구니 없는 삽질을 할 줄이야...ㅡ.ㅡ;;;

다른 사람은 이런 일이 없길....

 

반응형

'프로그래밍 > Python' 카테고리의 다른 글

Windows 7에서 GetModuleHandle 사용하기  (0) 2013.07.12
64bit debugger 만들기  (0) 2013.07.02
python thread context 보기(win7 64bit)  (2) 2013.07.02
Context 32bit / 64bit 선언  (0) 2013.06.29
GetLastError() - 0x00000032  (0) 2013.06.27

+ Recent posts