1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 """
32 Debugging.
33
34 @group Debugging:
35 Debug
36
37 @group Warnings:
38 MixedBitsWarning
39 """
40
41 __revision__ = "$Id: debug.py 1299 2013-12-20 09:30:55Z qvasimodo $"
42
43 __all__ = [ 'Debug', 'MixedBitsWarning' ]
44
45 import win32
46 from system import System
47 from process import Process
48 from thread import Thread
49 from module import Module
50 from window import Window
51 from breakpoint import _BreakpointContainer, CodeBreakpoint
52 from event import Event, EventHandler, EventDispatcher, EventFactory
53 from interactive import ConsoleDebugger
54
55 import warnings
64 """
65 This warning is issued when mixing 32 and 64 bit processes.
66 """
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 -class Debug (EventDispatcher, _BreakpointContainer):
84 """
85 The main debugger class.
86
87 @group Debugging:
88 interactive, attach, detach, detach_from_all, execv, execl,
89 kill, kill_all,
90 get_debugee_count, get_debugee_pids,
91 is_debugee, is_debugee_attached, is_debugee_started,
92 in_hostile_mode,
93 add_existing_session
94
95 @group Debugging loop:
96 loop, stop, next, wait, dispatch, cont
97
98 @undocumented: force_garbage_collection
99
100 @type system: L{System}
101 @ivar system: A System snapshot that is automatically updated for
102 processes being debugged. Processes not being debugged in this snapshot
103 may be outdated.
104 """
105
106
107 _debug_static_init = False
108
109 - def __init__(self, eventHandler = None, bKillOnExit = False,
110 bHostileCode = False):
111 """
112 Debugger object.
113
114 @type eventHandler: L{EventHandler}
115 @param eventHandler:
116 (Optional, recommended) Custom event handler object.
117
118 @type bKillOnExit: bool
119 @param bKillOnExit: (Optional) Kill on exit mode.
120 If C{True} debugged processes are killed when the debugger is
121 stopped. If C{False} when the debugger stops it detaches from all
122 debugged processes and leaves them running (default).
123
124 @type bHostileCode: bool
125 @param bHostileCode: (Optional) Hostile code mode.
126 Set to C{True} to take some basic precautions against anti-debug
127 tricks. Disabled by default.
128
129 @warn: When hostile mode is enabled, some things may not work as
130 expected! This is because the anti-anti debug tricks may disrupt
131 the behavior of the Win32 debugging APIs or WinAppDbg itself.
132
133 @note: The L{eventHandler} parameter may be any callable Python object
134 (for example a function, or an instance method).
135 However you'll probably find it more convenient to use an instance
136 of a subclass of L{EventHandler} here.
137
138 @raise WindowsError: Raises an exception on error.
139 """
140 EventDispatcher.__init__(self, eventHandler)
141 _BreakpointContainer.__init__(self)
142
143 self.system = System()
144 self.lastEvent = None
145 self.__firstDebugee = True
146 self.__bKillOnExit = bKillOnExit
147 self.__bHostileCode = bHostileCode
148 self.__breakOnEP = set()
149 self.__attachedDebugees = set()
150 self.__startedDebugees = set()
151
152 if not self._debug_static_init:
153 self._debug_static_init = True
154
155
156
157
158 self.system.request_debug_privileges(bIgnoreExceptions = False)
159
160
161
162
163 self.system.fix_symbol_store_path(remote = False, force = False)
164
165
166
167
168
169
170
171
173 """
174 Compatibility with the "C{with}" Python statement.
175 """
176 return self
177
178 - def __exit__(self, type, value, traceback):
179 """
180 Compatibility with the "C{with}" Python statement.
181 """
182 self.stop()
183
185 """
186 @rtype: int
187 @return: Number of processes being debugged.
188 """
189 return self.get_debugee_count()
190
191
192
193
194
195
196
209
210 - def attach(self, dwProcessId):
211 """
212 Attaches to an existing process for debugging.
213
214 @see: L{detach}, L{execv}, L{execl}
215
216 @type dwProcessId: int
217 @param dwProcessId: Global ID of a process to attach to.
218
219 @rtype: L{Process}
220 @return: A new Process object. Normally you don't need to use it now,
221 it's best to interact with the process from the event handler.
222
223 @raise WindowsError: Raises an exception on error.
224 Depending on the circumstances, the debugger may or may not have
225 attached to the target process.
226 """
227
228
229
230 try:
231 aProcess = self.system.get_process(dwProcessId)
232 except KeyError:
233 aProcess = Process(dwProcessId)
234
235
236
237
238 if System.bits != aProcess.get_bits():
239 msg = "Mixture of 32 and 64 bits is considered experimental." \
240 " Use at your own risk!"
241 warnings.warn(msg, MixedBitsWarning)
242
243
244 win32.DebugActiveProcess(dwProcessId)
245
246
247 self.__attachedDebugees.add(dwProcessId)
248
249
250 self.__setSystemKillOnExitMode()
251
252
253 if not self.system.has_process(dwProcessId):
254 self.system._add_process(aProcess)
255
256
257
258
259 aProcess.scan_threads()
260 aProcess.scan_modules()
261
262
263 return aProcess
264
265 - def execv(self, argv, **kwargs):
266 """
267 Starts a new process for debugging.
268
269 This method uses a list of arguments. To use a command line string
270 instead, use L{execl}.
271
272 @see: L{attach}, L{detach}
273
274 @type argv: list( str... )
275 @param argv: List of command line arguments to pass to the debugee.
276 The first element must be the debugee executable filename.
277
278 @type bBreakOnEntryPoint: bool
279 @keyword bBreakOnEntryPoint: C{True} to automatically set a breakpoint
280 at the program entry point.
281
282 @type bConsole: bool
283 @keyword bConsole: True to inherit the console of the debugger.
284 Defaults to C{False}.
285
286 @type bFollow: bool
287 @keyword bFollow: C{True} to automatically attach to child processes.
288 Defaults to C{False}.
289
290 @type bInheritHandles: bool
291 @keyword bInheritHandles: C{True} if the new process should inherit
292 it's parent process' handles. Defaults to C{False}.
293
294 @type bSuspended: bool
295 @keyword bSuspended: C{True} to suspend the main thread before any code
296 is executed in the debugee. Defaults to C{False}.
297
298 @keyword dwParentProcessId: C{None} or C{0} if the debugger process
299 should be the parent process (default), or a process ID to
300 forcefully set as the debugee's parent (only available for Windows
301 Vista and above).
302
303 In hostile mode, the default is not the debugger process but the
304 process ID for "explorer.exe".
305
306 @type iTrustLevel: int or None
307 @keyword iTrustLevel: Trust level.
308 Must be one of the following values:
309 - 0: B{No trust}. May not access certain resources, such as
310 cryptographic keys and credentials. Only available since
311 Windows XP and 2003, desktop editions. This is the default
312 in hostile mode.
313 - 1: B{Normal trust}. Run with the same privileges as a normal
314 user, that is, one that doesn't have the I{Administrator} or
315 I{Power User} user rights. Only available since Windows XP
316 and 2003, desktop editions.
317 - 2: B{Full trust}. Run with the exact same privileges as the
318 current user. This is the default in normal mode.
319
320 @type bAllowElevation: bool
321 @keyword bAllowElevation: C{True} to allow the child process to keep
322 UAC elevation, if the debugger itself is running elevated. C{False}
323 to ensure the child process doesn't run with elevation. Defaults to
324 C{True}.
325
326 This flag is only meaningful on Windows Vista and above, and if the
327 debugger itself is running with elevation. It can be used to make
328 sure the child processes don't run elevated as well.
329
330 This flag DOES NOT force an elevation prompt when the debugger is
331 not running with elevation.
332
333 Note that running the debugger with elevation (or the Python
334 interpreter at all for that matter) is not normally required.
335 You should only need to if the target program requires elevation
336 to work properly (for example if you try to debug an installer).
337
338 @rtype: L{Process}
339 @return: A new Process object. Normally you don't need to use it now,
340 it's best to interact with the process from the event handler.
341
342 @raise WindowsError: Raises an exception on error.
343 """
344 if type(argv) in (str, unicode):
345 raise TypeError("Debug.execv expects a list, not a string")
346 lpCmdLine = self.system.argv_to_cmdline(argv)
347 return self.execl(lpCmdLine, **kwargs)
348
349 - def execl(self, lpCmdLine, **kwargs):
350 """
351 Starts a new process for debugging.
352
353 This method uses a command line string. To use a list of arguments
354 instead, use L{execv}.
355
356 @see: L{attach}, L{detach}
357
358 @type lpCmdLine: str
359 @param lpCmdLine: Command line string to execute.
360 The first token must be the debugee executable filename.
361 Tokens with spaces must be enclosed in double quotes.
362 Tokens including double quote characters must be escaped with a
363 backslash.
364
365 @type bBreakOnEntryPoint: bool
366 @keyword bBreakOnEntryPoint: C{True} to automatically set a breakpoint
367 at the program entry point. Defaults to C{False}.
368
369 @type bConsole: bool
370 @keyword bConsole: True to inherit the console of the debugger.
371 Defaults to C{False}.
372
373 @type bFollow: bool
374 @keyword bFollow: C{True} to automatically attach to child processes.
375 Defaults to C{False}.
376
377 @type bInheritHandles: bool
378 @keyword bInheritHandles: C{True} if the new process should inherit
379 it's parent process' handles. Defaults to C{False}.
380
381 @type bSuspended: bool
382 @keyword bSuspended: C{True} to suspend the main thread before any code
383 is executed in the debugee. Defaults to C{False}.
384
385 @type dwParentProcessId: int or None
386 @keyword dwParentProcessId: C{None} or C{0} if the debugger process
387 should be the parent process (default), or a process ID to
388 forcefully set as the debugee's parent (only available for Windows
389 Vista and above).
390
391 In hostile mode, the default is not the debugger process but the
392 process ID for "explorer.exe".
393
394 @type iTrustLevel: int
395 @keyword iTrustLevel: Trust level.
396 Must be one of the following values:
397 - 0: B{No trust}. May not access certain resources, such as
398 cryptographic keys and credentials. Only available since
399 Windows XP and 2003, desktop editions. This is the default
400 in hostile mode.
401 - 1: B{Normal trust}. Run with the same privileges as a normal
402 user, that is, one that doesn't have the I{Administrator} or
403 I{Power User} user rights. Only available since Windows XP
404 and 2003, desktop editions.
405 - 2: B{Full trust}. Run with the exact same privileges as the
406 current user. This is the default in normal mode.
407
408 @type bAllowElevation: bool
409 @keyword bAllowElevation: C{True} to allow the child process to keep
410 UAC elevation, if the debugger itself is running elevated. C{False}
411 to ensure the child process doesn't run with elevation. Defaults to
412 C{True} in normal mode and C{False} in hostile mode.
413
414 This flag is only meaningful on Windows Vista and above, and if the
415 debugger itself is running with elevation. It can be used to make
416 sure the child processes don't run elevated as well.
417
418 This flag DOES NOT force an elevation prompt when the debugger is
419 not running with elevation.
420
421 Note that running the debugger with elevation (or the Python
422 interpreter at all for that matter) is not normally required.
423 You should only need to if the target program requires elevation
424 to work properly (for example if you try to debug an installer).
425
426 @rtype: L{Process}
427 @return: A new Process object. Normally you don't need to use it now,
428 it's best to interact with the process from the event handler.
429
430 @raise WindowsError: Raises an exception on error.
431 """
432 if type(lpCmdLine) not in (str, unicode):
433 warnings.warn("Debug.execl expects a string")
434
435
436 kwargs['bDebug'] = True
437
438
439 bBreakOnEntryPoint = kwargs.pop('bBreakOnEntryPoint', False)
440
441
442 if 'iTrustLevel' not in kwargs:
443 if self.__bHostileCode:
444 kwargs['iTrustLevel'] = 0
445 else:
446 kwargs['iTrustLevel'] = 2
447
448
449 if 'bAllowElevation' not in kwargs:
450 kwargs['bAllowElevation'] = not self.__bHostileCode
451
452
453
454 if self.__bHostileCode and not kwargs.get('dwParentProcessId', None):
455 try:
456 vista_and_above = self.__vista_and_above
457 except AttributeError:
458 osi = win32.OSVERSIONINFOEXW()
459 osi.dwMajorVersion = 6
460 osi.dwMinorVersion = 0
461 osi.dwPlatformId = win32.VER_PLATFORM_WIN32_NT
462 mask = 0
463 mask = win32.VerSetConditionMask(mask,
464 win32.VER_MAJORVERSION,
465 win32.VER_GREATER_EQUAL)
466 mask = win32.VerSetConditionMask(mask,
467 win32.VER_MAJORVERSION,
468 win32.VER_GREATER_EQUAL)
469 mask = win32.VerSetConditionMask(mask,
470 win32.VER_PLATFORMID,
471 win32.VER_EQUAL)
472 vista_and_above = win32.VerifyVersionInfoW(osi,
473 win32.VER_MAJORVERSION | \
474 win32.VER_MINORVERSION | \
475 win32.VER_PLATFORMID,
476 mask)
477 self.__vista_and_above = vista_and_above
478 if vista_and_above:
479 dwParentProcessId = self.system.get_explorer_pid()
480 if dwParentProcessId:
481 kwargs['dwParentProcessId'] = dwParentProcessId
482 else:
483 msg = ("Failed to find \"explorer.exe\"!"
484 " Using the debugger as parent process.")
485 warnings.warn(msg, RuntimeWarning)
486
487
488 aProcess = None
489 try:
490 aProcess = self.system.start_process(lpCmdLine, **kwargs)
491 dwProcessId = aProcess.get_pid()
492
493
494 self.__setSystemKillOnExitMode()
495
496
497
498
499 if System.bits != aProcess.get_bits():
500 msg = "Mixture of 32 and 64 bits is considered experimental." \
501 " Use at your own risk!"
502 warnings.warn(msg, MixedBitsWarning)
503
504
505 self.__startedDebugees.add(dwProcessId)
506
507
508 if bBreakOnEntryPoint:
509 self.__breakOnEP.add(dwProcessId)
510
511
512 return aProcess
513
514
515 except:
516 if aProcess is not None:
517 try:
518 try:
519 self.__startedDebugees.remove(aProcess.get_pid())
520 except KeyError:
521 pass
522 finally:
523 try:
524 try:
525 self.__breakOnEP.remove(aProcess.get_pid())
526 except KeyError:
527 pass
528 finally:
529 try:
530 aProcess.kill()
531 except Exception:
532 pass
533 raise
534
536 """
537 Use this method only when for some reason the debugger's been attached
538 to the target outside of WinAppDbg (for example when integrating with
539 other tools).
540
541 You don't normally need to call this method. Most users should call
542 L{attach}, L{execv} or L{execl} instead.
543
544 @type dwProcessId: int
545 @param dwProcessId: Global process ID.
546
547 @type bStarted: bool
548 @param bStarted: C{True} if the process was started by the debugger,
549 or C{False} if the process was attached to instead.
550
551 @raise WindowsError: The target process does not exist, is not attached
552 to the debugger anymore.
553 """
554
555
556 if not self.system.has_process(dwProcessId):
557 aProcess = Process(dwProcessId)
558 self.system._add_process(aProcess)
559 else:
560 aProcess = self.system.get_process(dwProcessId)
561
562
563
564 aProcess.get_handle()
565
566
567 if bStarted:
568 self.__attachedDebugees.add(dwProcessId)
569 else:
570 self.__startedDebugees.add(dwProcessId)
571
572
573 self.__setSystemKillOnExitMode()
574
575
576
577
578 aProcess.scan_threads()
579 aProcess.scan_modules()
580
582 """
583 Perform the necessary cleanup of a process about to be killed or
584 detached from.
585
586 This private method is called by L{kill} and L{detach}.
587
588 @type dwProcessId: int
589 @param dwProcessId: Global ID of a process to kill.
590
591 @type bIgnoreExceptions: bool
592 @param bIgnoreExceptions: C{True} to ignore any exceptions that may be
593 raised when killing the process.
594
595 @raise WindowsError: Raises an exception on error, unless
596 C{bIgnoreExceptions} is C{True}.
597 """
598
599 if self.is_debugee(dwProcessId):
600
601
602 if not self.system.has_process(dwProcessId):
603 aProcess = Process(dwProcessId)
604 try:
605 aProcess.get_handle()
606 except WindowsError:
607 pass
608 self.system._add_process(aProcess)
609
610
611 try:
612 self.erase_process_breakpoints(dwProcessId)
613 except Exception, e:
614 if not bIgnoreExceptions:
615 raise
616 warnings.warn(str(e), RuntimeWarning)
617
618
619 try:
620 self.stop_tracing_process(dwProcessId)
621 except Exception, e:
622 if not bIgnoreExceptions:
623 raise
624 warnings.warn(str(e), RuntimeWarning)
625
626
627 try:
628 if dwProcessId in self.__attachedDebugees:
629 self.__attachedDebugees.remove(dwProcessId)
630 if dwProcessId in self.__startedDebugees:
631 self.__startedDebugees.remove(dwProcessId)
632 except Exception, e:
633 if not bIgnoreExceptions:
634 raise
635 warnings.warn(str(e), RuntimeWarning)
636
637
638
639
640 try:
641 if self.system.has_process(dwProcessId):
642 try:
643 self.system.get_process(dwProcessId).clear()
644 finally:
645 self.system._del_process(dwProcessId)
646 except Exception, e:
647 if not bIgnoreExceptions:
648 raise
649 warnings.warn(str(e), RuntimeWarning)
650
651
652 try:
653 if self.lastEvent and self.lastEvent.get_pid() == dwProcessId:
654 self.lastEvent = None
655 except Exception, e:
656 if not bIgnoreExceptions:
657 raise
658 warnings.warn(str(e), RuntimeWarning)
659
660 - def kill(self, dwProcessId, bIgnoreExceptions = False):
661 """
662 Kills a process currently being debugged.
663
664 @see: L{detach}
665
666 @type dwProcessId: int
667 @param dwProcessId: Global ID of a process to kill.
668
669 @type bIgnoreExceptions: bool
670 @param bIgnoreExceptions: C{True} to ignore any exceptions that may be
671 raised when killing the process.
672
673 @raise WindowsError: Raises an exception on error, unless
674 C{bIgnoreExceptions} is C{True}.
675 """
676
677
678 try:
679 aProcess = self.system.get_process(dwProcessId)
680 except KeyError:
681 aProcess = Process(dwProcessId)
682
683
684 self.__cleanup_process(dwProcessId,
685 bIgnoreExceptions = bIgnoreExceptions)
686
687
688 try:
689 try:
690 if self.is_debugee(dwProcessId):
691 try:
692 if aProcess.is_alive():
693 aProcess.suspend()
694 finally:
695 self.detach(dwProcessId,
696 bIgnoreExceptions = bIgnoreExceptions)
697 finally:
698 aProcess.kill()
699 except Exception, e:
700 if not bIgnoreExceptions:
701 raise
702 warnings.warn(str(e), RuntimeWarning)
703
704
705 try:
706 aProcess.clear()
707 except Exception, e:
708 if not bIgnoreExceptions:
709 raise
710 warnings.warn(str(e), RuntimeWarning)
711
712 - def kill_all(self, bIgnoreExceptions = False):
713 """
714 Kills from all processes currently being debugged.
715
716 @type bIgnoreExceptions: bool
717 @param bIgnoreExceptions: C{True} to ignore any exceptions that may be
718 raised when killing each process. C{False} to stop and raise an
719 exception when encountering an error.
720
721 @raise WindowsError: Raises an exception on error, unless
722 C{bIgnoreExceptions} is C{True}.
723 """
724 for pid in self.get_debugee_pids():
725 self.kill(pid, bIgnoreExceptions = bIgnoreExceptions)
726
727 - def detach(self, dwProcessId, bIgnoreExceptions = False):
728 """
729 Detaches from a process currently being debugged.
730
731 @note: On Windows 2000 and below the process is killed.
732
733 @see: L{attach}, L{detach_from_all}
734
735 @type dwProcessId: int
736 @param dwProcessId: Global ID of a process to detach from.
737
738 @type bIgnoreExceptions: bool
739 @param bIgnoreExceptions: C{True} to ignore any exceptions that may be
740 raised when detaching. C{False} to stop and raise an exception when
741 encountering an error.
742
743 @raise WindowsError: Raises an exception on error, unless
744 C{bIgnoreExceptions} is C{True}.
745 """
746
747
748 try:
749 aProcess = self.system.get_process(dwProcessId)
750 except KeyError:
751 aProcess = Process(dwProcessId)
752
753
754
755 try:
756 win32.DebugActiveProcessStop
757 can_detach = True
758 except AttributeError:
759 can_detach = False
760
761
762
763 try:
764 if can_detach and self.lastEvent and \
765 self.lastEvent.get_pid() == dwProcessId:
766 self.cont(self.lastEvent)
767 except Exception, e:
768 if not bIgnoreExceptions:
769 raise
770 warnings.warn(str(e), RuntimeWarning)
771
772
773 self.__cleanup_process(dwProcessId,
774 bIgnoreExceptions = bIgnoreExceptions)
775
776 try:
777
778
779 if can_detach:
780 try:
781 win32.DebugActiveProcessStop(dwProcessId)
782 except Exception, e:
783 if not bIgnoreExceptions:
784 raise
785 warnings.warn(str(e), RuntimeWarning)
786 else:
787 try:
788 aProcess.kill()
789 except Exception, e:
790 if not bIgnoreExceptions:
791 raise
792 warnings.warn(str(e), RuntimeWarning)
793
794 finally:
795
796
797 aProcess.clear()
798
800 """
801 Detaches from all processes currently being debugged.
802
803 @note: To better handle last debugging event, call L{stop} instead.
804
805 @type bIgnoreExceptions: bool
806 @param bIgnoreExceptions: C{True} to ignore any exceptions that may be
807 raised when detaching.
808
809 @raise WindowsError: Raises an exception on error, unless
810 C{bIgnoreExceptions} is C{True}.
811 """
812 for pid in self.get_debugee_pids():
813 self.detach(pid, bIgnoreExceptions = bIgnoreExceptions)
814
815
816
817 - def wait(self, dwMilliseconds = None):
818 """
819 Waits for the next debug event.
820
821 @see: L{cont}, L{dispatch}, L{loop}
822
823 @type dwMilliseconds: int
824 @param dwMilliseconds: (Optional) Timeout in milliseconds.
825 Use C{INFINITE} or C{None} for no timeout.
826
827 @rtype: L{Event}
828 @return: An event that occured in one of the debugees.
829
830 @raise WindowsError: Raises an exception on error.
831 If no target processes are left to debug,
832 the error code is L{win32.ERROR_INVALID_HANDLE}.
833 """
834
835
836 raw = win32.WaitForDebugEvent(dwMilliseconds)
837 event = EventFactory.get(self, raw)
838
839
840 self.lastEvent = event
841
842
843 return event
844
921
922 - def cont(self, event = None):
977
978 - def stop(self, bIgnoreExceptions = True):
979 """
980 Stops debugging all processes.
981
982 If the kill on exit mode is on, debugged processes are killed when the
983 debugger is stopped. Otherwise when the debugger stops it detaches from
984 all debugged processes and leaves them running (default). For more
985 details see: L{__init__}
986
987 @note: This method is better than L{detach_from_all} because it can
988 gracefully handle the last debugging event before detaching.
989
990 @type bIgnoreExceptions: bool
991 @param bIgnoreExceptions: C{True} to ignore any exceptions that may be
992 raised when detaching.
993 """
994
995
996 try:
997 event = self.lastEvent
998 has_event = bool(event)
999 except Exception, e:
1000 if not bIgnoreExceptions:
1001 raise
1002 warnings.warn(str(e), RuntimeWarning)
1003 has_event = False
1004
1005
1006 if has_event:
1007
1008
1009 try:
1010 pid = event.get_pid()
1011 self.disable_process_breakpoints(pid)
1012 except Exception, e:
1013 if not bIgnoreExceptions:
1014 raise
1015 warnings.warn(str(e), RuntimeWarning)
1016
1017
1018 try:
1019 tid = event.get_tid()
1020 self.disable_thread_breakpoints(tid)
1021 except Exception, e:
1022 if not bIgnoreExceptions:
1023 raise
1024 warnings.warn(str(e), RuntimeWarning)
1025
1026
1027 try:
1028 event.continueDebugEvent = win32.DBG_CONTINUE
1029 self.cont(event)
1030 except Exception, e:
1031 if not bIgnoreExceptions:
1032 raise
1033 warnings.warn(str(e), RuntimeWarning)
1034
1035
1036 try:
1037 if self.__bKillOnExit:
1038 self.kill_all(bIgnoreExceptions)
1039 else:
1040 self.detach_from_all(bIgnoreExceptions)
1041 except Exception, e:
1042 if not bIgnoreExceptions:
1043 raise
1044 warnings.warn(str(e), RuntimeWarning)
1045
1046
1047 try:
1048 self.system.clear()
1049 except Exception, e:
1050 if not bIgnoreExceptions:
1051 raise
1052 warnings.warn(str(e), RuntimeWarning)
1053
1054
1055 self.force_garbage_collection(bIgnoreExceptions)
1056
1058 """
1059 Handles the next debug event.
1060
1061 @see: L{cont}, L{dispatch}, L{wait}, L{stop}
1062
1063 @raise WindowsError: Raises an exception on error.
1064
1065 If the wait operation causes an error, debugging is stopped
1066 (meaning all debugees are either killed or detached from).
1067
1068 If the event dispatching causes an error, the event is still
1069 continued before returning. This may happen, for example, if the
1070 event handler raises an exception nobody catches.
1071 """
1072 try:
1073 event = self.wait()
1074 except Exception:
1075 self.stop()
1076 raise
1077 try:
1078 self.dispatch()
1079 finally:
1080 self.cont()
1081
1083 """
1084 Simple debugging loop.
1085
1086 This debugging loop is meant to be useful for most simple scripts.
1087 It iterates as long as there is at least one debugee, or an exception
1088 is raised. Multiple calls are allowed.
1089
1090 This is a trivial example script::
1091 import sys
1092 debug = Debug()
1093 try:
1094 debug.execv( sys.argv [ 1 : ] )
1095 debug.loop()
1096 finally:
1097 debug.stop()
1098
1099 @see: L{next}, L{stop}
1100
1101 U{http://msdn.microsoft.com/en-us/library/ms681675(VS.85).aspx}
1102
1103 @raise WindowsError: Raises an exception on error.
1104
1105 If the wait operation causes an error, debugging is stopped
1106 (meaning all debugees are either killed or detached from).
1107
1108 If the event dispatching causes an error, the event is still
1109 continued before returning. This may happen, for example, if the
1110 event handler raises an exception nobody catches.
1111 """
1112 while self:
1113 self.next()
1114
1116 """
1117 @rtype: int
1118 @return: Number of processes being debugged.
1119 """
1120 return len(self.__attachedDebugees) + len(self.__startedDebugees)
1121
1123 """
1124 @rtype: list( int... )
1125 @return: Global IDs of processes being debugged.
1126 """
1127 return list(self.__attachedDebugees) + list(self.__startedDebugees)
1128
1130 """
1131 Determine if the debugger is debugging the given process.
1132
1133 @see: L{is_debugee_attached}, L{is_debugee_started}
1134
1135 @type dwProcessId: int
1136 @param dwProcessId: Process global ID.
1137
1138 @rtype: bool
1139 @return: C{True} if the given process is being debugged
1140 by this L{Debug} instance.
1141 """
1142 return self.is_debugee_attached(dwProcessId) or \
1143 self.is_debugee_started(dwProcessId)
1144
1146 """
1147 Determine if the given process was started by the debugger.
1148
1149 @see: L{is_debugee}, L{is_debugee_attached}
1150
1151 @type dwProcessId: int
1152 @param dwProcessId: Process global ID.
1153
1154 @rtype: bool
1155 @return: C{True} if the given process was started for debugging by this
1156 L{Debug} instance.
1157 """
1158 return dwProcessId in self.__startedDebugees
1159
1161 """
1162 Determine if the debugger is attached to the given process.
1163
1164 @see: L{is_debugee}, L{is_debugee_started}
1165
1166 @type dwProcessId: int
1167 @param dwProcessId: Process global ID.
1168
1169 @rtype: bool
1170 @return: C{True} if the given process is attached to this
1171 L{Debug} instance.
1172 """
1173 return dwProcessId in self.__attachedDebugees
1174
1176 """
1177 Determine if we're in hostile mode (anti-anti-debug).
1178
1179 @rtype: bool
1180 @return: C{True} if this C{Debug} instance was started in hostile mode,
1181 C{False} otherwise.
1182 """
1183 return self.__bHostileCode
1184
1185
1186
1187 - def interactive(self, bConfirmQuit = True, bShowBanner = True):
1188 """
1189 Start an interactive debugging session.
1190
1191 @type bConfirmQuit: bool
1192 @param bConfirmQuit: Set to C{True} to ask the user for confirmation
1193 before closing the session, C{False} otherwise.
1194
1195 @type bShowBanner: bool
1196 @param bShowBanner: Set to C{True} to show a banner before entering
1197 the session and after leaving it, C{False} otherwise.
1198
1199 @warn: This will temporarily disable the user-defined event handler!
1200
1201 This method returns when the user closes the session.
1202 """
1203 print
1204 print "-" * 79
1205 print "Interactive debugging session started."
1206 print "Use the \"help\" command to list all available commands."
1207 print "Use the \"quit\" command to close this session."
1208 print "-" * 79
1209 if self.lastEvent is None:
1210 print
1211 console = ConsoleDebugger()
1212 console.confirm_quit = bConfirmQuit
1213 console.load_history()
1214 try:
1215 console.start_using_debugger(self)
1216 console.loop()
1217 finally:
1218 console.stop_using_debugger()
1219 console.save_history()
1220 print
1221 print "-" * 79
1222 print "Interactive debugging session closed."
1223 print "-" * 79
1224 print
1225
1226
1227
1228 @staticmethod
1230 """
1231 Close all Win32 handles the Python garbage collector failed to close.
1232
1233 @type bIgnoreExceptions: bool
1234 @param bIgnoreExceptions: C{True} to ignore any exceptions that may be
1235 raised when detaching.
1236 """
1237 try:
1238 import gc
1239 gc.collect()
1240 bRecollect = False
1241 for obj in list(gc.garbage):
1242 try:
1243 if isinstance(obj, win32.Handle):
1244 obj.close()
1245 elif isinstance(obj, Event):
1246 obj.debug = None
1247 elif isinstance(obj, Process):
1248 obj.clear()
1249 elif isinstance(obj, Thread):
1250 obj.set_process(None)
1251 obj.clear()
1252 elif isinstance(obj, Module):
1253 obj.set_process(None)
1254 elif isinstance(obj, Window):
1255 obj.set_process(None)
1256 else:
1257 continue
1258 gc.garbage.remove(obj)
1259 del obj
1260 bRecollect = True
1261 except Exception, e:
1262 if not bIgnoreExceptions:
1263 raise
1264 warnings.warn(str(e), RuntimeWarning)
1265 if bRecollect:
1266 gc.collect()
1267 except Exception, e:
1268 if not bIgnoreExceptions:
1269 raise
1270 warnings.warn(str(e), RuntimeWarning)
1271
1272
1273
1327
1329 """
1330 Notify the creation of a new thread.
1331
1332 @warning: This method is meant to be used internally by the debugger.
1333
1334 @type event: L{CreateThreadEvent}
1335 @param event: Create thread event.
1336
1337 @rtype: bool
1338 @return: C{True} to call the user-defined handle, C{False} otherwise.
1339 """
1340 return event.get_process()._notify_create_thread(event)
1341
1343 """
1344 Notify the load of a new module.
1345
1346 @warning: This method is meant to be used internally by the debugger.
1347
1348 @type event: L{LoadDLLEvent}
1349 @param event: Load DLL event.
1350
1351 @rtype: bool
1352 @return: C{True} to call the user-defined handle, C{False} otherwise.
1353 """
1354
1355
1356 bCallHandler = _BreakpointContainer._notify_load_dll(self, event)
1357
1358
1359 aProcess = event.get_process()
1360
1361
1362 bCallHandler = aProcess._notify_load_dll(event) and bCallHandler
1363
1364
1365 if self.__bHostileCode:
1366 aModule = event.get_module()
1367 if aModule.match_name('ntdll.dll'):
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378 self.break_at(aProcess.get_pid(),
1379 aProcess.resolve_label('ntdll!DbgUiRemoteBreakin'))
1380
1381 return bCallHandler
1382
1384 """
1385 Notify the termination of a process.
1386
1387 @warning: This method is meant to be used internally by the debugger.
1388
1389 @type event: L{ExitProcessEvent}
1390 @param event: Exit process event.
1391
1392 @rtype: bool
1393 @return: C{True} to call the user-defined handle, C{False} otherwise.
1394 """
1395 bCallHandler1 = _BreakpointContainer._notify_exit_process(self, event)
1396 bCallHandler2 = self.system._notify_exit_process(event)
1397
1398 try:
1399 self.detach( event.get_pid() )
1400 except WindowsError, e:
1401 if e.winerror != win32.ERROR_INVALID_PARAMETER:
1402 warnings.warn(
1403 "Failed to detach from dead process, reason: %s" % str(e),
1404 RuntimeWarning)
1405 except Exception, e:
1406 warnings.warn(
1407 "Failed to detach from dead process, reason: %s" % str(e),
1408 RuntimeWarning)
1409
1410 return bCallHandler1 and bCallHandler2
1411
1413 """
1414 Notify the termination of a thread.
1415
1416 @warning: This method is meant to be used internally by the debugger.
1417
1418 @type event: L{ExitThreadEvent}
1419 @param event: Exit thread event.
1420
1421 @rtype: bool
1422 @return: C{True} to call the user-defined handle, C{False} otherwise.
1423 """
1424 bCallHandler1 = _BreakpointContainer._notify_exit_thread(self, event)
1425 bCallHandler2 = event.get_process()._notify_exit_thread(event)
1426 return bCallHandler1 and bCallHandler2
1427
1429 """
1430 Notify the unload of a module.
1431
1432 @warning: This method is meant to be used internally by the debugger.
1433
1434 @type event: L{UnloadDLLEvent}
1435 @param event: Unload DLL event.
1436
1437 @rtype: bool
1438 @return: C{True} to call the user-defined handle, C{False} otherwise.
1439 """
1440 bCallHandler1 = _BreakpointContainer._notify_unload_dll(self, event)
1441 bCallHandler2 = event.get_process()._notify_unload_dll(event)
1442 return bCallHandler1 and bCallHandler2
1443
1445 """
1446 Notify of a RIP event.
1447
1448 @warning: This method is meant to be used internally by the debugger.
1449
1450 @type event: L{RIPEvent}
1451 @param event: RIP event.
1452
1453 @rtype: bool
1454 @return: C{True} to call the user-defined handle, C{False} otherwise.
1455 """
1456 event.debug.detach( event.get_pid() )
1457 return True
1458
1460 """
1461 Notify of a Debug Ctrl-C exception.
1462
1463 @warning: This method is meant to be used internally by the debugger.
1464
1465 @note: This exception is only raised when a debugger is attached, and
1466 applications are not supposed to handle it, so we need to handle it
1467 ourselves or the application may crash.
1468
1469 @see: U{http://msdn.microsoft.com/en-us/library/aa363082(VS.85).aspx}
1470
1471 @type event: L{ExceptionEvent}
1472 @param event: Debug Ctrl-C exception event.
1473
1474 @rtype: bool
1475 @return: C{True} to call the user-defined handle, C{False} otherwise.
1476 """
1477 if event.is_first_chance():
1478 event.continueStatus = win32.DBG_EXCEPTION_HANDLED
1479 return True
1480
1522