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