브레이크포인트
소프트 브레이크 포인트
프로세스의 메모리를 읽고 쓸 수 있어야 한다.
이를 위해 ReadProcessMemory() 함수와 WriteProcessMemory()함수를 이용한다.
두 함수의 프로토타입. 순서대로
------------------------------------------------------
BOOL WINAPI ReadProcessMemory(
HANDLE hProcess,
LPCVOID lpBaseAddress,
LPVOID lqBuffer,
SIZE_T nSize,
SIZE_T* lpNumberOfBytesRead
);
BOOL WINAPID WriteProcessMemory(
HANDLE hProcess,
LPCVOID lpBaseAddress,
LPCVOID lpBuffer,
SIZE_T nSize,
SIZE_T* lpNumberOfBytesWritten
);
------------------------------------------------------
이 두함수를 이용하면 디버깅 대상 프로세스의 메모리를 조사하거나 변경할 수 있다.
lpBaseAddress 파라미터는 읽거나 쓰기 위한 메모리 영역의 시작 주소를 나타낸다.
lpBuffer 파라미터는 데이터를 읽거나 쓰기 위해 사용하는 버퍼에 대한 포인터며, nSize 파라미터는 읽거나 쓸 데이터의 바이트 수를 나타낸다.
my_debugger.py가 소프트 브레이크포인트를 지원하게 변경해보자.
my_debugger.py
------------------------------------------------------
def __init__(self):
self.h_process = None
self.pid = None
self.debugger_active = False
self.h_thread = None
self.context = None
self.breakpoints = {} << 이것만 추가
.....
def read_process_memory(self,address,length):
data = ""
read_buf = create_string_buffer(length)
count = c_long(0)
if not kernel32.ReadProcessMemory(self.h_process,
address,
read_buf,
length,
byref(count)):
return False
else:
data += read_buf.raw
return data
def write_process_memory(self,address,data):
count = c_long(0)
length = len(data)
c_data = c_char_p(data[count.value:])
if not kernel32.WriteProcessMemory(self,h_process,
address,
c_data,
length,
byref(count)):
return False
else:
return True
def bp_set(self,address):
if not self.breakpoints.has_key(address):
try:
original_byte=self.read_process_memory(address,1)
self.write_process_memory(address,"\xCC")
self.breakpoints[address] = (original_byte)
except:
return False
return True
을 추가해야 한다.
------------------------------------------------------
이제 소프트 브레이크포인트를 설정할 수 있게 되었다.
어느 곳에 브레이크포인트를 설정할 것인지만 결정하면 된다.
여기서는 printf() 함수에 브레이크포인트를 설정해 볼 것이다.
GetProcAddress() 윈도우 디버그 API를 사용하면 특정 함수의 가상 메모리 주소를 쉽게 알아낼 수 있다.
이 함수는 kernel32.dll이 익스포트 하는 함수다.
GetProcAddress()함수를 호출하려면 해당 함수가 속한 모듈의 핸들이 필요하다.
이 핸들은 GetModuleHandle() 함수를 이용해 얻을 수 있다.
다음은 두 개의 함수의 프로토 타입이다.
------------------------------------------------------
FARPROC WINAPI GetProcAddress(
HMODULE hModule,
LPCSTR lqProcName
);
HMODULE WINAPI GetModuleHandle(
LPCSTR lpModuleName
);
------------------------------------------------------
과정은 매우 단순하다.
모듈의 핸들을 구하고 해당 모듈에서 브레이크 포인트를 설정할 익스포트의 함수의 주소를 구하는 것이다.
my_debugger.py 파일에서 브레이크포인트를 설정할 함수의 주소를 구하는 기능을 추가하자.
my_debugger.py
------------------------------------------------------
def func_resolve(self,dll,function):
handle=kernel32.GetModuleHandleA(dll)
address =kernel32.GetProcAddress(handle,function)
kernel32.CloseHandle(handle)
return address
------------------------------------------------------
위의 소스에 저 소스를 추가한다.
이제는 테스트를 위해 루프를 돌며 printf() 함수를 호출하는 테스트 프로그램을 작성하자.
printf() 함수의 주소를 구하고 그 곳에 소프트 브레이크포인트를 설정한다.
printf() 함수가 호출돼 브레이크포인트가 발생하면 그에 따른 내용을 출력하고 프로세스는 루프를 도는 작업을 계속 수행할 것이다.
print_loop.py라는 파일을 새로 만들자
pritn_loop.py
------------------------------------------------------
from ctypes import *
import time
msvcrt = cdll.msvcrt
counter=0
while 1:
msvcrt.printf("loop iteration %d! \n" %counter)
time.sleep(2)
counter +=1
------------------------------------------------------
다음은 printf()함수에 대한 브레이크포인트를 테스트할 수 있게 변경한 테스트 프로그램이다.
my.test.py
------------------------------------------------------
import my_debugger
debugger = my_debugger.debugger()
pid = raw_input("enter the PID of the process to attach to : ")
debugger.attach(int(pid))
printf_address = debugger.func_resolve("msvcrt.dll","printf")
print"[*] address of printf : 0x%08x" % printf_address
debugger.bp_set(printf_address)
debugger.run()
input()
------------------------------------------------------
먼저 printf_loop.py 를 커맨드라인에서 실행시키고 작업관리자를 통해 python.exe 프로세스의 PID를 구한다.
그 후 테스트 프로그램인 my_test.py스크립트를 실행시켜 python.exe의 PID를 입력한다.
실행화면(소스는 공개를 안할것이다)
'파이썬 스터디 과제 > 파이썬 해킹 프로그래밍' 카테고리의 다른 글
3장-4 브레이크포인트-3 (메모리브레이크포인트) (0) | 2015.01.17 |
---|---|
3장-4 브레이크포인트-2 (하드브레이크포인트) (0) | 2015.01.17 |
3장-3 디버그 이벤트 핸들러 구현 (0) | 2015.01.15 |
3장-2 CPU 레지스터 상태 얻기 (0) | 2015.01.14 |
3장-1 디버기 (0) | 2015.01.14 |
댓글