다음은 Fandu 형이 정리하신
"파이썬 해킹 프로그래밍" 서적에 대한 오류 정리 글을 퍼온 것이다.
절대 내가 쓴것이 아님을 다시 한번 밝힌다.
Grat Hat Python을 공부해 보신 분이라면 아마 책을 그대로 배꼈음에도 불구하고 소스코드가 제대로 작동하지 않은 경우를 많이 격어 보셨을 겁니다. 저도 그랬는 데 정말 암 걸리더라구요.
구글링해서 제가 직접 소스코드를 작성도 해보았지만 역부족이더라구요.
그래서 몇 일 동안의 삽질과 구글링을 통해 이 모든 것의 해결 방법을 찾았습니다 ㅎㅎ
이 글은 http://stacksmash.org/2009/06/gray-hat-python-by-justin-seitz-errata/ 와 http://www.nostarch.com/grayhatpython 에서 언급된 책에 있는 오류들을 한국어로 재정리한 것 입니다. 저도 영어 보면서 눈 아퍼서...
원문으로 보신 분들도 있고 번역판을 보시는 분들도 있으실 거 같아서 페이지는 영어판과 한국어판의 페이지를 모두 적어드리겠습니다. (괄호 안에 있는 게 한국어판 페이지입니다. 괄호가 없는 경우에는 한국어판에는 수정할 필요가 없습니다.) 순서는 책의 순서에 따라 작성되었고 각 항목의 제일 밑에 있는 창에는 수정 후의 소스 코드가 적혀 있습니다.
1. 31페이지
attach 함수 안에 있는 self.run()을 지웁니다.
def attach(self, pid): self.h_process = self.open_process(pid) if kernel32.DebugActiveProcess(pid): self.debugger_active = True self.pid = int(pid) else: print "[*] Unable to attach to the process." |
2. 37페이지
whlie함수 안에 있는
kernel32.CloseHandle(snapshot) return thread_list |
이 두 줄을 while 함수와 같은 위치에 둔다.
def enumerate_threads(self): thread_entry = THREADENTRY32() thread_list = [] snapshot = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, self.pid)
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 |
3. 42페이지지 (73,74페이지)
함수에 있는
if self.exception == EXCEPTION_ACCESS_VIOLATION: print "Access Violation Detected." elif self.exception == EXCEPTION_BREAKPOINT: continue_status = self.exception_handler_breakpoint() elif self.exception == EXCEPTION_GUARD_PAGE: print "Guard Page Access Detected." elif self.exception == EXCEPTION_SINGLE_STEP: self.exception_handler_single_step() |
이 부분을 if debug_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT: 안에 들어가야한다.
def get_debug_event(self): debug_event = DEBUG_EVENT() continue_status = DBG_CONTINUE
if kernel32.WaitForDebugEvent(byref(debug_event),100): self.h_thread = self.open_thread(debug_event.dwThreadId) self.context = self.get_thread_context(h_thread=self.h_thread) self.debug_event = debug_event
print "Event Code: %d Thread ID: %d" % \ (debug_event.dwDebugEventCode,debug_event.dwThreadId)
if debug_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT: self.exception = debug_event.u.Exception.ExceptionRecord.ExceptionCode self.exception_address = debug_event.u.Exception.ExceptionRecord.ExceptionAddress
if self.exception == EXCEPTION_ACCESS_VIOLATION: print "Access Violation Detected." elif self.exception == EXCEPTION_BREAKPOINT: continue_status = self.exception_handler_breakpoint() elif self.exception == EXCEPTION_GUARD_PAGE: print "Guard Page Access Detected." elif self.exception == EXCEPTION_SINGLE_STEP: self.exception_handler_single_step()
kernel32.ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, continue_status) |
4. 42페이지
exception_handler_breakpoint()을 exception_handler_breakpoint(self)로 바꾸는 것것을 포함해서 함수의 모든 내용을 바꿔야한다.
def exception_handler_breakpoint(self): print "[*] Exception address: 0x%08x" % self.exception_address if not self.breakpoints.has_key(self.exception_address): if self.first_breakpoint == True: self.first_breakpoint = False print "[*] Hit the first breakpoint." return DBG_CONTINUE
else: print "[*] Hit user defined breakpoint." self.write_process_memory(self.exception_address, self.breakpoints[self.exception_address]) self.context = self.get_thread_context(h_thread=self.h_thread) self.context.Eip -= 1 kernel32.SetThreadContext(self.h_thread,byref(self.context)) continue_status = DBG_CONTINUE return continue_status |
5. 페이지 31
h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS, pid, False)이 부분은 아래와 같이 수정한다.
h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, pid) |
6. 페이지 42
이 페이지에 있는 ec는 exception으로 수정한다.
7. 페이지 42
__inti__(self) 함수에 다음 소스를 추가한다.
self.first_breakpoint = True |
8. 페이지 44
self.breakpoints[address] = (address, orginal_byte)이 부분의 앞에 탭을 지워 위 소스와 위치를 맞추고 address를 지운다.
self.breakpoints[address] = (original_byte) |
9. get_thread_context 함수
이 함수는 전체를 아래의 소스코드로 대체한다.
def get_thread_context (self, thread_id=None,h_thread=None):
context = CONTEXT() context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS
if h_thread is None: self.h_thread = self.open_thread(thread_id)
if kernel32.GetThreadContext(self.h_thread, byref(context)):
return context else: return False |
10. get_debug_event 함수
이 함수는 전체를 아래의 소스코드로 대체한다.
def get_debug_event(self): debug_event = DEBUG_EVENT() continue_status = DBG_CONTINUE
if kernel32.WaitForDebugEvent(byref(debug_event),100): self.h_thread = self.open_thread(debug_event.dwThreadId) self.context = self.get_thread_context(h_thread=self.h_thread) self.debug_event = debug_event
print "Event Code: %d Thread ID: %d" % \ (debug_event.dwDebugEventCode,debug_event.dwThreadId)
if debug_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT: self.exception = debug_event.u.Exception.ExceptionRecord.ExceptionCode self.exception_address = debug_event.u.Exception.ExceptionRecord.ExceptionAddress
if self.exception == EXCEPTION_ACCESS_VIOLATION: print "Access Violation Detected." elif self.exception == EXCEPTION_BREAKPOINT: continue_status = self.exception_handler_breakpoint() elif self.exception == EXCEPTION_GUARD_PAGE: print "Guard Page Access Detected." elif self.exception == EXCEPTION_SINGLE_STEP: self.exception_handler_single_step()
kernel32.ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, continue_status) |
11. 48 페이지
if available == 0: context.Dr0 = address elif available == 1: context.Dr1 = address elif available == 2: context.Dr2 = address elif available == 3: context.Dr3 = address |
이 부분을 for thread_id in self.enumerate_threads(): 안으로 넣는다.
def bp_set_hw(self, address, length, condition): if length not in (1, 2, 4): return False else: length -= 1 if condition not in (HW_ACCESS, HW_EXECUTE, HW_WRITE): return False
if not self.hardware_breakpoints.has_key(0): available = 0 elif not self.hardware_breakpoints.has_key(1): available = 1 elif not self.hardware_breakpoints.has_key(2): available = 2 elif not self.hardware_breakpoints.has_key(3): available = 3 else: return False for thread_id in self.enumerate_threads(): context = self.get_thread_context(thread_id=thread_id) context.Dr7 |= 1 << (available * 2) if available == 0: context.Dr0 = address elif available == 1: context.Dr1 = address elif available == 2: context.Dr2 = address elif available == 3: context.Dr3 = address context.Dr7 |= condition << ((available * 4) + 16) context.Dr7 |= length << ((available * 4) + 18) h_thread = self.open_thread(thread_id) kernel32.SetThreadContext(h_thread,byref(context)) self.hardware_breakpoints[available] = (address,length,condition) return True |
'스터디 > 파이썬 해킹 프로그래밍' 카테고리의 다른 글
Hardware Breakpoint 까지 이론, 함수 정리 (0) | 2015.01.18 |
---|---|
Soft Breakpoint 까지의 이론 정리 (0) | 2015.01.17 |
디버거 이벤트 헨들러 구현 (0) | 2015.01.15 |
디버거와 프로세스를 연결하는 방법, CPU 레지스터 값을 출력하는 방법 (0) | 2015.01.15 |
DLL 기초개념 (0) | 2015.01.14 |