[2주] 03장 - 윈도우 디버거 개발 (1)

Posted by dw0rdptr
2015. 1. 17. 22:12 Study/파이썬 해킹 프로그래밍

프로세스를 디버깅하려면 해당 프로세스를 연결해야하는데, 두가지 방법이 있다.


첫번째는 디버거가 직접 바이너리를 실행시키는 것이다. 이 경우에는 해당 프로세스의 코드가 실행되기 전에 제어 할 수 있다는 장점이 있으므로 악성코드나 기타 다른 형태의 악의적인 코드를 분석할 때 편리하다.

두번째 방법은 디버거를 이미 실행중인 프로세스에 attach(붙이는) 하는 방법이다. 이는 프로세스가 시작되면서 실행되는 코드를 건너뛸 수 있으며 특정 영역의 코드만을 분석할 수 있다.

윈도우에서는 이 두가지 작업을 쉽게 수행할 수 있게 하는 디버깅 api를 제공한다.

* 구동환경은 윈도우7 32bit


CreateProcessA함수로 계산기(calc.exe)를 열어보자



#my_debugger_defines.py
#-*- coding: utf-8 -*-
from ctypes import *

# ctypes 형태의 타입을 마이크로소프트의 타입으로 매핑
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

#CreateProcesssA() 함수를 위한 구조체
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),
		("hThrea",			HANDLE),
		("dwProcessId",		DWORD),
		("dwThreadId",		DWORD),
	]
구조체,유니온,상수를 미리 정의해놓는다.
#my_debugger.py
#-*- coding: utf-8 -*-
from ctypes import *
from my_debugger_defines import *


kernel32 = windll.kernel32

class debugger():
	def __init__(self):
		pass

	def load(self,path_to_exe):
		#dwCreation 플래그를 이용해 프로세스를 어떻게 생성할 것인지 판단.
		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 launched the process!"
			print "[*] PID : %d" % process_information.dwProcessId

		else:
			print "[*] Error : 0x%08x." % kernel32.GetLastError()
#my_test.py
import my_debugger

debugger = my_debugger.debugger()

debugger.load("C:\\Windows\\System32\\calc.exe")

raw_input("")
세 파일을 같은 디렉토리에 두고 my_test.py를 실행하면  
[*] We have successfully launched the process! 
[*] PID : 1588 

calc.exe 프로세스를 열었다. PID는 1588 
하지만 디버거로부터 실행을 계속하게 하는 명령을 받지 못해서 계산기 프로그램의 GUI를 볼수는 없다. 
이부분은 나중에 하자.


두번째 방법인 디버거를 프로세스에 attach하는 방법은 다음 글에서 정리하겠다.




'Study > 파이썬 해킹 프로그래밍' 카테고리의 다른 글

[2주] 03장 - 윈도우 디버거 개발 (3)  (0) 2015.01.19
[2주] 03장 - 윈도우 디버거 개발 (2)  (0) 2015.01.18
api 기초  (0) 2015.01.12
[1주] 02장-디버거  (0) 2015.01.12
[1주] 01장 - 개발환경 구축  (0) 2015.01.12