Here's the code so far for exception_handler_breakpoint():
def exception_handler_breakpoint(self):
print "[*] Inside the breakpoint handler."
print "Exception Address: 0x%08x" % self.exception_address
return DBG_CONTINUE
The source has this for the function, though:
def exception_handler_breakpoint(self):
print "[*] Exception address: 0x%08x" % self.exception_address
# check if the breakpoint is one that we set
if not self.breakpoints.has_key(self.exception_address):
# if it is the first Windows driven breakpoint
# then let's just continue on
if self.first_breakpoint == True:
self.first_breakpoint = False
print "[*] Hit the first breakpoint."
return DBG_CONTINUE
else:
print "[*] Hit user defined breakpoint."
# this is where we handle the breakpoints we set
# first put the original byte back
self.write_process_memory(self.exception_address, self.breakpoints[self.exception_address])
# obtain a fresh context record, reset EIP back to the
# original byte and then set the thread's context record
# with the new EIP value
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
No other changes are made to exception_handler_breakpoint() anywhere else in Chapter 3, outside of page 42. So, my guess is that the function updates / changes were not fully printed.
Well, not so quite. Adding just all of that text causes an error in self.first_breakpoint. That property is defined on pg. 48. Also define first_breakpoint in __init__ for debugger():
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
self.breakpoints = {}
self.first_breakpoint = True
Almost out of the woods...
Enter the PID of the process to attach to: 2216
[*] Address of printf: 0x77c4186a
Event Code: 3 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 6 Thread ID: 3340
Event Code: 2 Thread ID: 3372
Event Code: 1 Thread ID: 3372
[*] Exception address: 0x7c90120e
[*] Hit the first breakpoint.
Event Code: 4 Thread ID: 3372
Event Code: 1 Thread ID: 3340
[*] Exception address: 0x77c4186a
[*] Hit user defined breakpoint.
Traceback (most recent call last):
File "C:\Documents and Settings\Administrator\workspace\Grey Hat Python\src\my_test.py", line 20, in
debugger.run()
File "C:\Documents and Settings\Administrator\workspace\Grey Hat Python\src\my_debugger.py", line 89, in run
self.get_debug_event()
File "C:\Documents and Settings\Administrator\workspace\Grey Hat Python\src\my_debugger.py", line 118, in get_debug_event
continue_status = self.exception_handler_breakpoint()
File "C:\Documents and Settings\Administrator\workspace\Grey Hat Python\src\my_debugger.py", line 205, in exception_handler_breakpoint
self.context.Eip -= 1
AttributeError: 'bool' object has no attribute 'Eip'
It looks like self.context.Eip is causing some grief. Looking ahead, it looks like it's covered on page 48. Comment out the following:
self.context = self.get_thread_context(h_thread=self.h_thread)
self.context.Eip -= 1
kernel32.SetThreadContext(self.h_thread,byref(self.context))
So now the handler looks like this:
def exception_handler_breakpoint(self):
print "[*] Exception address: 0x%08x" % self.exception_address
# check if the breakpoint is one that we set
if not self.breakpoints.has_key(self.exception_address):
# if it is the first Windows driven breakpoint
# then let's just continue on
if self.first_breakpoint == True:
self.first_breakpoint = False
print "[*] Hit the first breakpoint."
return DBG_CONTINUE
else:
print "[*] Hit user defined breakpoint."
# this is where we handle the breakpoints we set
# first put the original byte back
self.write_process_memory(self.exception_address, self.breakpoints[self.exception_address])
# obtain a fresh context record, reset EIP back to the
# original byte and then set the thread's context record
# with the new EIP value
#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
Seems decent:
Enter the PID of the process to attach to: 3744
[*] Address of printf: 0x77c4186a
Event Code: 3 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 6 Thread ID: 3712
Event Code: 2 Thread ID: 3660
Event Code: 1 Thread ID: 3660
[*] Exception address: 0x7c90120e
[*] Hit the first breakpoint.
Event Code: 4 Thread ID: 3660
Event Code: 1 Thread ID: 3712
[*] Exception address: 0x77c4186a
[*] Hit user defined breakpoint.
Event Code: 1 Thread ID: 3712
Event Code: 1 Thread ID: 3712
Event Code: 1 Thread ID: 3712
[...]
For the anally-included, change bp_set() in my_debugger.py from
def bp_set(self,address):
if not self.breakpoints.has_key(address):
to
def bp_set(self,address):
print "[*] Setting breakpoint at: 0x%08x" % address
if not self.breakpoints.has_key(address):