본문 바로가기
정상을향해/Program Analysis

Python Hacking Programming (3)

by 사이테일 2013. 11. 10.


파이썬 해킹 프로그래밍 (Python Hacking Programming)


저자 : 저스틴 지이츠

출판사 : 에이콘



3장. 윈도우 디버거 개발

[3.4] 브레이크포인트



소스파일 my_debugger.py


소스파일 my_test.py


소스파일 print_loop.py


my_debugger_defines.py

 


[3.4 브레이크포인트]

1. 소프트 브레이크포인트


소프트 브레이크포인트를 설정하기 위해서는 프로세스의 메모리를 읽고 쓸 수 있어야 한다.


이를 위해 사용하는 함수가 바로


ReadProcessMemory()WriteProcessMemory() 이 두 함수다.



BOOL ReadProcessMemory(
  HANDLE hProcess,
  LPCVOID lpBaseAddress,
  LPVOID lpBuffer,
  DWORD nSize,
  LPDWORD lpNumberOfBytesRead 
 );
 
 BOOL WriteProcessMemory(
  HANDLE hProcess,
  LPVOID lpBaseAddress,
  LPVOID lpBuffer,
  DWORD nSize,
  LPDWORD lpNumberOfBytesWritten
);


이 두 함수를 이용해 대상 프로세스의 메모리를 읽거나 변경할 수 있다.


lpBaseAddress 파라미터는 읽거나 쓰기 위한 메모리 영역의 시작 주소를 나타낸다.


lpBuffer 파라미터는 데이터를 읽거나 쓰기 위해 사용하는 버퍼에 대한 포인터이며,


nSize 파라미터는 읽거나 쓸 데이터의 바이트 수를 나타낸다.



read_process_memory()와 write_process_memory()를 정의하고 이를 이용해 다음과 같이 소프트 브레이크포인트를 구현한다.



브레이크포인트를 설정할 곳의 바이트 값을 저장해두고, 그 값을 0xCC로 변경한다.


따라서 이제 어느 곳에 소프트 브레이크포인트를 설정할 것인지만 결정하면 된다.



일반적으로 함수 호출 부분에 브레이크포인트를 설정하는데, 여기서는 printf() 함수에 브레이크포인트를 설정해 보겠다.


이 때 kernel32.dll에서 익스포트하는


GetProcAddress() 윈도우 디버그 API를 사용하면 특정 함수의 가상 메모리 주소를 쉽게 알아낼 수 있다.


FARPROC GetProcAddress(
  HMODULE hModule,
  LPCWSTR lpProcName 
 ); 

HMODULE GetModuleHandle(
  LPCTSTR lpModuleName
);


GetProcAddress()를 호출하려면 해당 함수가 속한 모듈(.dll이나 .exe 파일)의 핸들이 필요하다.


이 핸들은 GetModuleHandle() 함수를 이용해 얻을 수 있다.


이를 이용해 먼저 모듈의 핸들을 구하고, 해당 모듈에서 브레이크포인트를 설정할 익스포트 함수의 주소를 구한다.


다음과 같이 브레이크포인트를 설정할 함수의 주소를 구하는 기능을 추가한다.




이제 다음의 루프를 돌면서 printf() 함수를 호출하는 테스트 프로그램을 이용해


printf() 함수의 주소를 구하고 그 곳에 소프트 브레이크포인트를 설정해보자.