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 Miscellaneous utility classes and functions.
33
34 @group Helpers:
35 PathOperations,
36 MemoryAddresses,
37 CustomAddressIterator,
38 DataAddressIterator,
39 ImageAddressIterator,
40 MappedAddressIterator,
41 ExecutableAddressIterator,
42 ReadableAddressIterator,
43 WriteableAddressIterator,
44 ExecutableAndWriteableAddressIterator,
45 DebugRegister,
46 Regenerator,
47 BannerHelpFormatter,
48 StaticClass,
49 classproperty
50 """
51
52 __revision__ = "$Id: util.py 1299 2013-12-20 09:30:55Z qvasimodo $"
53
54 __all__ = [
55
56
57 'PathOperations',
58
59
60 'MemoryAddresses',
61 'CustomAddressIterator',
62 'DataAddressIterator',
63 'ImageAddressIterator',
64 'MappedAddressIterator',
65 'ExecutableAddressIterator',
66 'ReadableAddressIterator',
67 'WriteableAddressIterator',
68 'ExecutableAndWriteableAddressIterator',
69
70
71 'DebugRegister',
72
73
74 'Regenerator',
75 ]
76
77 import os
78 import ctypes
79 import optparse
80
81 import win32
86 """
87 Class property method.
88
89 Only works for getting properties, if you set them
90 the symbol gets overwritten in the class namespace.
91
92 Inspired on: U{http://stackoverflow.com/a/7864317/426293}
93 """
94 - def __init__(self, fget=None, fset=None, fdel=None, doc=""):
95 if fset is not None or fdel is not None:
96 raise NotImplementedError()
97 super(classproperty, self).__init__(fget=classmethod(fget), doc=doc)
99 return self.fget.__get__(None, owner)()
100
109
112 """
113 Calls a generator and iterates it. When it's finished iterating, the
114 generator is called again. This allows you to iterate a generator more
115 than once (well, sort of).
116 """
117
118 - def __init__(self, g_function, *v_args, **d_args):
119 """
120 @type g_function: function
121 @param g_function: Function that when called returns a generator.
122
123 @type v_args: tuple
124 @param v_args: Variable arguments to pass to the generator function.
125
126 @type d_args: dict
127 @param d_args: Variable arguments to pass to the generator function.
128 """
129 self.__g_function = g_function
130 self.__v_args = v_args
131 self.__d_args = d_args
132 self.__g_object = None
133
135 'x.__iter__() <==> iter(x)'
136 return self
137
139 'x.next() -> the next value, or raise StopIteration'
140 if self.__g_object is None:
141 self.__g_object = self.__g_function( *self.__v_args, **self.__d_args )
142 try:
143 return self.__g_object.next()
144 except StopIteration:
145 self.__g_object = None
146 raise
147
150 "Don't try to instance this class, just use the static methods."
151 raise NotImplementedError(
152 "Cannot instance static class %s" % cls.__name__)
153
157 """
158 Static methods for filename and pathname manipulation.
159 """
160
161 @staticmethod
163 """
164 @see: L{path_is_absolute}
165
166 @type path: str
167 @param path: Absolute or relative path.
168
169 @rtype: bool
170 @return: C{True} if the path is relative, C{False} if it's absolute.
171 """
172 return win32.PathIsRelative(path)
173
174 @staticmethod
176 """
177 @see: L{path_is_relative}
178
179 @type path: str
180 @param path: Absolute or relative path.
181
182 @rtype: bool
183 @return: C{True} if the path is absolute, C{False} if it's relative.
184 """
185 return not win32.PathIsRelative(path)
186
187 @staticmethod
189 """
190 @type path: str
191 @param path: Absolute path.
192
193 @type current: str
194 @param current: (Optional) Path to the current directory.
195
196 @rtype: str
197 @return: Relative path.
198
199 @raise WindowsError: It's impossible to make the path relative.
200 This happens when the path and the current path are not on the
201 same disk drive or network share.
202 """
203 return win32.PathRelativePathTo(pszFrom = current, pszTo = path)
204
205 @staticmethod
207 """
208 @type path: str
209 @param path: Relative path.
210
211 @rtype: str
212 @return: Absolute path.
213 """
214 return win32.GetFullPathName(path)[0]
215
216 @staticmethod
218 """
219 @type pathname: str
220 @param pathname: Absolute path.
221
222 @rtype: tuple( str, str )
223 @return:
224 Tuple containing the file and extension components of the filename.
225 """
226 filepart = win32.PathRemoveExtension(pathname)
227 extpart = win32.PathFindExtension(pathname)
228 return (filepart, extpart)
229
230 @staticmethod
232 """
233 @type pathname: str
234 @param pathname: Absolute path.
235
236 @rtype: tuple( str, str )
237 @return: Tuple containing the path to the file and the base filename.
238 """
239 filepart = win32.PathFindFileName(pathname)
240 pathpart = win32.PathRemoveFileSpec(pathname)
241 return (pathpart, filepart)
242
243 @staticmethod
245 """
246 @see: L{join_path}
247
248 @type path: str
249 @param path: Absolute or relative path.
250
251 @rtype: list( str... )
252 @return: List of path components.
253 """
254 components = list()
255 while path:
256 next = win32.PathFindNextComponent(path)
257 if next:
258 prev = path[ : -len(next) ]
259 components.append(prev)
260 path = next
261 return components
262
263 @staticmethod
265 """
266 @see: L{split_path}
267
268 @type components: tuple( str... )
269 @param components: Path components.
270
271 @rtype: str
272 @return: Absolute or relative path.
273 """
274 if components:
275 path = components[0]
276 for next in components[1:]:
277 path = win32.PathAppend(path, next)
278 else:
279 path = ""
280 return path
281
282 @staticmethod
284 """
285 @type name: str
286 @param name: Native (NT) absolute pathname.
287
288 @rtype: str
289 @return: Win32 absolute pathname.
290 """
291
292
293
294 if name.startswith("\\"):
295 if name.startswith("\\??\\"):
296 name = name[4:]
297 elif name.startswith("\\SystemRoot\\"):
298 system_root_path = os.environ['SYSTEMROOT']
299 if system_root_path.endswith('\\'):
300 system_root_path = system_root_path[:-1]
301 name = system_root_path + name[11:]
302 else:
303 for drive_number in xrange(ord('A'), ord('Z') + 1):
304 drive_letter = '%c:' % drive_number
305 try:
306 device_native_path = win32.QueryDosDevice(drive_letter)
307 except WindowsError, e:
308 if e.winerror in (win32.ERROR_FILE_NOT_FOUND, \
309 win32.ERROR_PATH_NOT_FOUND):
310 continue
311 raise
312 if not device_native_path.endswith('\\'):
313 device_native_path += '\\'
314 if name.startswith(device_native_path):
315 name = drive_letter + '\\' + \
316 name[ len(device_native_path) : ]
317 break
318 return name
319
320 @staticmethod
322 """
323 Equivalent to: C{PathOperations.split_filename(pathname)[0]}
324
325 @note: This function is preserved for backwards compatibility with
326 WinAppDbg 1.4 and earlier. It may be removed in future versions.
327
328 @type pathname: str
329 @param pathname: Absolute path to a file.
330
331 @rtype: str
332 @return: Filename component of the path.
333 """
334 return win32.PathFindFileName(pathname)
335
339 """
340 Class to manipulate memory addresses.
341
342 @type pageSize: int
343 @cvar pageSize: Page size in bytes. Defaults to 0x1000 but it's
344 automatically updated on runtime when importing the module.
345 """
346
347 @classproperty
349 """
350 Try to get the pageSize value on runtime.
351 """
352 try:
353 try:
354 pageSize = win32.GetSystemInfo().dwPageSize
355 except WindowsError:
356 pageSize = 0x1000
357 except NameError:
358 pageSize = 0x1000
359 cls.pageSize = pageSize
360 return pageSize
361
362 @classmethod
364 """
365 Align the given address to the start of the page it occupies.
366
367 @type address: int
368 @param address: Memory address.
369
370 @rtype: int
371 @return: Aligned memory address.
372 """
373 return address - ( address % cls.pageSize )
374
375 @classmethod
377 """
378 Align the given address to the end of the page it occupies.
379 That is, to point to the start of the next page.
380
381 @type address: int
382 @param address: Memory address.
383
384 @rtype: int
385 @return: Aligned memory address.
386 """
387 return address + cls.pageSize - ( address % cls.pageSize )
388
389 @classmethod
391 """
392 Align the given address range to the start and end of the page(s) it occupies.
393
394 @type begin: int
395 @param begin: Memory address of the beginning of the buffer.
396 Use C{None} for the first legal address in the address space.
397
398 @type end: int
399 @param end: Memory address of the end of the buffer.
400 Use C{None} for the last legal address in the address space.
401
402 @rtype: tuple( int, int )
403 @return: Aligned memory addresses.
404 """
405 if begin is None:
406 begin = 0
407 if end is None:
408 end = win32.LPVOID(-1).value
409 if end < begin:
410 begin, end = end, begin
411 begin = cls.align_address_to_page_start(begin)
412 if end != cls.align_address_to_page_start(end):
413 end = cls.align_address_to_page_end(end)
414 return (begin, end)
415
416 @classmethod
417 - def get_buffer_size_in_pages(cls, address, size):
418 """
419 Get the number of pages in use by the given buffer.
420
421 @type address: int
422 @param address: Aligned memory address.
423
424 @type size: int
425 @param size: Buffer size.
426
427 @rtype: int
428 @return: Buffer size in number of pages.
429 """
430 if size < 0:
431 size = -size
432 address = address - size
433 begin, end = cls.align_address_range(address, address + size)
434
435
436 return int(float(end - begin) / float(cls.pageSize))
437
438 @staticmethod
440 """
441 Determine if the two given memory address ranges intersect.
442
443 @type begin: int
444 @param begin: Start address of the first range.
445
446 @type end: int
447 @param end: End address of the first range.
448
449 @type old_begin: int
450 @param old_begin: Start address of the second range.
451
452 @type old_end: int
453 @param old_end: End address of the second range.
454
455 @rtype: bool
456 @return: C{True} if the two ranges intersect, C{False} otherwise.
457 """
458 return (old_begin <= begin < old_end) or \
459 (old_begin < end <= old_end) or \
460 (begin <= old_begin < end) or \
461 (begin < old_end <= end)
462
466 """
467 Generator function that iterates through a memory map, filtering memory
468 region blocks by any given condition.
469
470 @type memory_map: list( L{win32.MemoryBasicInformation} )
471 @param memory_map: List of memory region information objects.
472 Returned by L{Process.get_memory_map}.
473
474 @type condition: function
475 @param condition: Callback function that returns C{True} if the memory
476 block should be returned, or C{False} if it should be filtered.
477
478 @rtype: generator of L{win32.MemoryBasicInformation}
479 @return: Generator object to iterate memory blocks.
480 """
481 for mbi in memory_map:
482 if condition(mbi):
483 address = mbi.BaseAddress
484 max_addr = address + mbi.RegionSize
485 while address < max_addr:
486 yield address
487 address = address + 1
488
490 """
491 Generator function that iterates through a memory map, returning only those
492 memory blocks that contain data.
493
494 @type memory_map: list( L{win32.MemoryBasicInformation} )
495 @param memory_map: List of memory region information objects.
496 Returned by L{Process.get_memory_map}.
497
498 @rtype: generator of L{win32.MemoryBasicInformation}
499 @return: Generator object to iterate memory blocks.
500 """
501 return CustomAddressIterator(memory_map,
502 win32.MemoryBasicInformation.has_content)
503
505 """
506 Generator function that iterates through a memory map, returning only those
507 memory blocks that belong to executable images.
508
509 @type memory_map: list( L{win32.MemoryBasicInformation} )
510 @param memory_map: List of memory region information objects.
511 Returned by L{Process.get_memory_map}.
512
513 @rtype: generator of L{win32.MemoryBasicInformation}
514 @return: Generator object to iterate memory blocks.
515 """
516 return CustomAddressIterator(memory_map,
517 win32.MemoryBasicInformation.is_image)
518
520 """
521 Generator function that iterates through a memory map, returning only those
522 memory blocks that belong to memory mapped files.
523
524 @type memory_map: list( L{win32.MemoryBasicInformation} )
525 @param memory_map: List of memory region information objects.
526 Returned by L{Process.get_memory_map}.
527
528 @rtype: generator of L{win32.MemoryBasicInformation}
529 @return: Generator object to iterate memory blocks.
530 """
531 return CustomAddressIterator(memory_map,
532 win32.MemoryBasicInformation.is_mapped)
533
535 """
536 Generator function that iterates through a memory map, returning only those
537 memory blocks that are readable.
538
539 @type memory_map: list( L{win32.MemoryBasicInformation} )
540 @param memory_map: List of memory region information objects.
541 Returned by L{Process.get_memory_map}.
542
543 @rtype: generator of L{win32.MemoryBasicInformation}
544 @return: Generator object to iterate memory blocks.
545 """
546 return CustomAddressIterator(memory_map,
547 win32.MemoryBasicInformation.is_readable)
548
550 """
551 Generator function that iterates through a memory map, returning only those
552 memory blocks that are writeable.
553
554 @note: Writeable memory is always readable too.
555
556 @type memory_map: list( L{win32.MemoryBasicInformation} )
557 @param memory_map: List of memory region information objects.
558 Returned by L{Process.get_memory_map}.
559
560 @rtype: generator of L{win32.MemoryBasicInformation}
561 @return: Generator object to iterate memory blocks.
562 """
563 return CustomAddressIterator(memory_map,
564 win32.MemoryBasicInformation.is_writeable)
565
567 """
568 Generator function that iterates through a memory map, returning only those
569 memory blocks that are executable.
570
571 @note: Executable memory is always readable too.
572
573 @type memory_map: list( L{win32.MemoryBasicInformation} )
574 @param memory_map: List of memory region information objects.
575 Returned by L{Process.get_memory_map}.
576
577 @rtype: generator of L{win32.MemoryBasicInformation}
578 @return: Generator object to iterate memory blocks.
579 """
580 return CustomAddressIterator(memory_map,
581 win32.MemoryBasicInformation.is_executable)
582
584 """
585 Generator function that iterates through a memory map, returning only those
586 memory blocks that are executable and writeable.
587
588 @note: The presence of such pages make memory corruption vulnerabilities
589 much easier to exploit.
590
591 @type memory_map: list( L{win32.MemoryBasicInformation} )
592 @param memory_map: List of memory region information objects.
593 Returned by L{Process.get_memory_map}.
594
595 @rtype: generator of L{win32.MemoryBasicInformation}
596 @return: Generator object to iterate memory blocks.
597 """
598 return CustomAddressIterator(memory_map,
599 win32.MemoryBasicInformation.is_executable_and_writeable)
600
604 """
605 Class to manipulate debug registers.
606 Used by L{HardwareBreakpoint}.
607
608 @group Trigger flags used by HardwareBreakpoint:
609 BREAK_ON_EXECUTION, BREAK_ON_WRITE, BREAK_ON_ACCESS, BREAK_ON_IO_ACCESS
610 @group Size flags used by HardwareBreakpoint:
611 WATCH_BYTE, WATCH_WORD, WATCH_DWORD, WATCH_QWORD
612 @group Bitwise masks for Dr7:
613 enableMask, disableMask, triggerMask, watchMask, clearMask,
614 generalDetectMask
615 @group Bitwise masks for Dr6:
616 hitMask, hitMaskAll, debugAccessMask, singleStepMask, taskSwitchMask,
617 clearDr6Mask, clearHitMask
618 @group Debug control MSR definitions:
619 DebugCtlMSR, LastBranchRecord, BranchTrapFlag, PinControl,
620 LastBranchToIP, LastBranchFromIP,
621 LastExceptionToIP, LastExceptionFromIP
622
623 @type BREAK_ON_EXECUTION: int
624 @cvar BREAK_ON_EXECUTION: Break on execution.
625
626 @type BREAK_ON_WRITE: int
627 @cvar BREAK_ON_WRITE: Break on write.
628
629 @type BREAK_ON_ACCESS: int
630 @cvar BREAK_ON_ACCESS: Break on read or write.
631
632 @type BREAK_ON_IO_ACCESS: int
633 @cvar BREAK_ON_IO_ACCESS: Break on I/O port access.
634 Not supported by any hardware.
635
636 @type WATCH_BYTE: int
637 @cvar WATCH_BYTE: Watch a byte.
638
639 @type WATCH_WORD: int
640 @cvar WATCH_WORD: Watch a word.
641
642 @type WATCH_DWORD: int
643 @cvar WATCH_DWORD: Watch a double word.
644
645 @type WATCH_QWORD: int
646 @cvar WATCH_QWORD: Watch one quad word.
647
648 @type enableMask: 4-tuple of integers
649 @cvar enableMask:
650 Enable bit on C{Dr7} for each slot.
651 Works as a bitwise-OR mask.
652
653 @type disableMask: 4-tuple of integers
654 @cvar disableMask:
655 Mask of the enable bit on C{Dr7} for each slot.
656 Works as a bitwise-AND mask.
657
658 @type triggerMask: 4-tuple of 2-tuples of integers
659 @cvar triggerMask:
660 Trigger bits on C{Dr7} for each trigger flag value.
661 Each 2-tuple has the bitwise-OR mask and the bitwise-AND mask.
662
663 @type watchMask: 4-tuple of 2-tuples of integers
664 @cvar watchMask:
665 Watch bits on C{Dr7} for each watch flag value.
666 Each 2-tuple has the bitwise-OR mask and the bitwise-AND mask.
667
668 @type clearMask: 4-tuple of integers
669 @cvar clearMask:
670 Mask of all important bits on C{Dr7} for each slot.
671 Works as a bitwise-AND mask.
672
673 @type generalDetectMask: integer
674 @cvar generalDetectMask:
675 General detect mode bit. It enables the processor to notify the
676 debugger when the debugee is trying to access one of the debug
677 registers.
678
679 @type hitMask: 4-tuple of integers
680 @cvar hitMask:
681 Hit bit on C{Dr6} for each slot.
682 Works as a bitwise-AND mask.
683
684 @type hitMaskAll: integer
685 @cvar hitMaskAll:
686 Bitmask for all hit bits in C{Dr6}. Useful to know if at least one
687 hardware breakpoint was hit, or to clear the hit bits only.
688
689 @type clearHitMask: integer
690 @cvar clearHitMask:
691 Bitmask to clear all the hit bits in C{Dr6}.
692
693 @type debugAccessMask: integer
694 @cvar debugAccessMask:
695 The debugee tried to access a debug register. Needs bit
696 L{generalDetectMask} enabled in C{Dr7}.
697
698 @type singleStepMask: integer
699 @cvar singleStepMask:
700 A single step exception was raised. Needs the trap flag enabled.
701
702 @type taskSwitchMask: integer
703 @cvar taskSwitchMask:
704 A task switch has occurred. Needs the TSS T-bit set to 1.
705
706 @type clearDr6Mask: integer
707 @cvar clearDr6Mask:
708 Bitmask to clear all meaningful bits in C{Dr6}.
709 """
710
711 BREAK_ON_EXECUTION = 0
712 BREAK_ON_WRITE = 1
713 BREAK_ON_ACCESS = 3
714 BREAK_ON_IO_ACCESS = 2
715
716 WATCH_BYTE = 0
717 WATCH_WORD = 1
718 WATCH_DWORD = 3
719 WATCH_QWORD = 2
720
721 try:
722 registerMask = win32.SIZE_T(-1).value
723 except TypeError:
724 if win32.SIZEOF(win32.SIZE_T) == 4:
725 registerMask = 0xFFFFFFFF
726 elif win32.SIZEOF(win32.SIZE_T) == 8:
727 registerMask = 0xFFFFFFFFFFFFFFFF
728 else:
729 raise
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757 enableMask = (
758 1 << 0,
759 1 << 2,
760 1 << 4,
761 1 << 6,
762 )
763
764
765 disableMask = tuple( [registerMask ^ x for x in enableMask] )
766 del x
767
768
769
770
771 triggerMask = (
772
773 (
774 ((0 << 16), (3 << 16) ^ registerMask),
775 ((1 << 16), (3 << 16) ^ registerMask),
776 ((2 << 16), (3 << 16) ^ registerMask),
777 ((3 << 16), (3 << 16) ^ registerMask),
778 ),
779
780 (
781 ((0 << 20), (3 << 20) ^ registerMask),
782 ((1 << 20), (3 << 20) ^ registerMask),
783 ((2 << 20), (3 << 20) ^ registerMask),
784 ((3 << 20), (3 << 20) ^ registerMask),
785 ),
786
787 (
788 ((0 << 24), (3 << 24) ^ registerMask),
789 ((1 << 24), (3 << 24) ^ registerMask),
790 ((2 << 24), (3 << 24) ^ registerMask),
791 ((3 << 24), (3 << 24) ^ registerMask),
792 ),
793
794 (
795 ((0 << 28), (3 << 28) ^ registerMask),
796 ((1 << 28), (3 << 28) ^ registerMask),
797 ((2 << 28), (3 << 28) ^ registerMask),
798 ((3 << 28), (3 << 28) ^ registerMask),
799 ),
800 )
801
802
803
804
805 watchMask = (
806
807 (
808 ((0 << 18), (3 << 18) ^ registerMask),
809 ((1 << 18), (3 << 18) ^ registerMask),
810 ((2 << 18), (3 << 18) ^ registerMask),
811 ((3 << 18), (3 << 18) ^ registerMask),
812 ),
813
814 (
815 ((0 << 23), (3 << 23) ^ registerMask),
816 ((1 << 23), (3 << 23) ^ registerMask),
817 ((2 << 23), (3 << 23) ^ registerMask),
818 ((3 << 23), (3 << 23) ^ registerMask),
819 ),
820
821 (
822 ((0 << 26), (3 << 26) ^ registerMask),
823 ((1 << 26), (3 << 26) ^ registerMask),
824 ((2 << 26), (3 << 26) ^ registerMask),
825 ((3 << 26), (3 << 26) ^ registerMask),
826 ),
827
828 (
829 ((0 << 30), (3 << 31) ^ registerMask),
830 ((1 << 30), (3 << 31) ^ registerMask),
831 ((2 << 30), (3 << 31) ^ registerMask),
832 ((3 << 30), (3 << 31) ^ registerMask),
833 ),
834 )
835
836
837 clearMask = (
838 registerMask ^ ( (1 << 0) + (3 << 16) + (3 << 18) ),
839 registerMask ^ ( (1 << 2) + (3 << 20) + (3 << 22) ),
840 registerMask ^ ( (1 << 4) + (3 << 24) + (3 << 26) ),
841 registerMask ^ ( (1 << 6) + (3 << 28) + (3 << 30) ),
842 )
843
844
845 generalDetectMask = (1 << 13)
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863 hitMask = (
864 (1 << 0),
865 (1 << 1),
866 (1 << 2),
867 (1 << 3),
868 )
869
870
871 hitMaskAll = hitMask[0] | hitMask[1] | hitMask[2] | hitMask[3]
872
873
874 clearHitMask = registerMask ^ hitMaskAll
875
876
877 debugAccessMask = (1 << 13)
878
879
880 singleStepMask = (1 << 14)
881
882
883 taskSwitchMask = (1 << 15)
884
885
886 clearDr6Mask = registerMask ^ (hitMaskAll | \
887 debugAccessMask | singleStepMask | taskSwitchMask)
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929 DebugCtlMSR = 0x1D9
930 LastBranchRecord = (1 << 0)
931 BranchTrapFlag = (1 << 1)
932 PinControl = (
933 (1 << 2),
934 (1 << 3),
935 (1 << 4),
936 (1 << 5),
937 )
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956 LastBranchToIP = 0x1DC
957 LastBranchFromIP = 0x1DB
958 LastExceptionToIP = 0x1DE
959 LastExceptionFromIP = 0x1DD
960
961
962
963 @classmethod
965 """
966 Clears a hardware breakpoint.
967
968 @see: find_slot, set_bp
969
970 @type ctx: dict( str S{->} int )
971 @param ctx: Thread context dictionary.
972
973 @type register: int
974 @param register: Slot (debug register) for hardware breakpoint.
975 """
976 ctx['Dr7'] &= cls.clearMask[register]
977 ctx['Dr%d' % register] = 0
978
979 @classmethod
980 - def set_bp(cls, ctx, register, address, trigger, watch):
981 """
982 Sets a hardware breakpoint.
983
984 @see: clear_bp, find_slot
985
986 @type ctx: dict( str S{->} int )
987 @param ctx: Thread context dictionary.
988
989 @type register: int
990 @param register: Slot (debug register).
991
992 @type address: int
993 @param address: Memory address.
994
995 @type trigger: int
996 @param trigger: Trigger flag. See L{HardwareBreakpoint.validTriggers}.
997
998 @type watch: int
999 @param watch: Watch flag. See L{HardwareBreakpoint.validWatchSizes}.
1000 """
1001 Dr7 = ctx['Dr7']
1002 Dr7 |= cls.enableMask[register]
1003 orMask, andMask = cls.triggerMask[register][trigger]
1004 Dr7 &= andMask
1005 Dr7 |= orMask
1006 orMask, andMask = cls.watchMask[register][watch]
1007 Dr7 &= andMask
1008 Dr7 |= orMask
1009 ctx['Dr7'] = Dr7
1010 ctx['Dr%d' % register] = address
1011
1012 @classmethod
1014 """
1015 Finds an empty slot to set a hardware breakpoint.
1016
1017 @see: clear_bp, set_bp
1018
1019 @type ctx: dict( str S{->} int )
1020 @param ctx: Thread context dictionary.
1021
1022 @rtype: int
1023 @return: Slot (debug register) for hardware breakpoint.
1024 """
1025 Dr7 = ctx['Dr7']
1026 slot = 0
1027 for m in cls.enableMask:
1028 if (Dr7 & m) == 0:
1029 return slot
1030 slot += 1
1031 return None
1032