Skip to content

Commit 784e669

Browse files
committed
update debugger.py with new on_setup callback"
1 parent 21e259f commit 784e669

1 file changed

Lines changed: 33 additions & 4 deletions

File tree

windows/debug/debugger.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,19 @@ class Debugger(object):
3939
4040
* Standard BP (int3)
4141
* Hardware-Exec BP (DrX)
42-
* Memory BP (virtual_protect)"""
42+
* Memory BP (virtual_protect)
43+
"""
4344

4445
def __init__(self, target):
4546
"""``target`` must be a debuggable :class:`WinProcess`."""
4647
self._init_dispatch_handlers()
4748
self.target = target
4849
self.is_target_launched = False
49-
#if not already_debuggable:
50-
# winproxy.DebugActiveProcess(target.pid)
5150
self.processes = {}
5251
self.threads = {}
5352
self.current_process = None
5453
self.current_thread = None
54+
self.first_bp_encoutered = False
5555
# List of breakpoints
5656
self.breakpoints = {}
5757
self._pending_breakpoints = {} #Breakpoints to put in new process / threads
@@ -497,6 +497,15 @@ def _handle_unknown_debug_event(self, debug_event):
497497

498498
def _handle_exception_breakpoint(self, exception, excp_addr):
499499
excp_bitness = self.get_exception_bitness(exception)
500+
# Sub-method _do_setup() ?
501+
if not self.first_bp_encoutered:
502+
dbg_has_setup = not getattr(self.on_setup, "_abstract_on_setup_", False)
503+
self.first_bp_encoutered = True
504+
if dbg_has_setup:
505+
with self.DisabledMemoryBreakpoint():
506+
continue_flag = self.on_setup() # Handle single-step here ?
507+
# Check killed in action ?
508+
# What if setup + BP object()
500509
if excp_addr in self.breakpoints[self.current_process.pid]:
501510
thread = self.current_thread
502511
if self.current_process.bitness == 32 and excp_bitness == 64:
@@ -517,6 +526,8 @@ def _handle_exception_breakpoint(self, exception, excp_addr):
517526
# Setup BP if not suppressed
518527
self._pass_breakpoint(excp_addr)
519528
return continue_flag
529+
if dbg_has_setup: # setup() was called on this BP-event: no on_exception()
530+
return continue_flag
520531
with self.DisabledMemoryBreakpoint():
521532
return self.on_exception(exception)
522533

@@ -624,7 +635,7 @@ def _handle_exception(self, debug_event):
624635

625636
excp_code = exception.ExceptionRecord.ExceptionCode
626637
excp_addr = exception.ExceptionRecord.ExceptionAddress
627-
if excp_code in [EXCEPTION_BREAKPOINT, STATUS_WX86_BREAKPOINT] and excp_addr in self.breakpoints[self.current_process.pid]:
638+
if excp_code in [EXCEPTION_BREAKPOINT, STATUS_WX86_BREAKPOINT]:
628639
return self._handle_exception_breakpoint(exception, excp_addr)
629640
elif excp_code in [EXCEPTION_SINGLE_STEP, STATUS_WX86_SINGLE_STEP]:
630641
return self._handle_exception_singlestep(exception, excp_addr)
@@ -956,6 +967,24 @@ def get_exception_bitness(self, exc):
956967
return 64
957968

958969
# Public callback
970+
def on_setup(self):
971+
"""Called on the first breakpoint event occuring in the debugger.
972+
This callback allow to setup hook / interact with the debugee when ready:
973+
974+
- If :func:`on_setup` is overriden by a subclass it will be called and :func:`on_exception` will NOT be called for this event (first BP).
975+
- If :func:`on_setup` is not defined the first BP will trigger an :func:`on_exception`.
976+
977+
.. note::
978+
979+
see sample :ref:`sample_debugger_on_setup`
980+
981+
"""
982+
return None
983+
984+
# Help detect if on_setup was override
985+
on_setup._abstract_on_setup_ = True
986+
987+
959988
def on_exception(self, exception):
960989
"""Called on exception event other that known breakpoint or requested single step. ``exception`` is one of the following type:
961990

0 commit comments

Comments
 (0)